Bjorn-Strom / FSS

MIT License
101 stars 4 forks source link

Is it possible to use FSS to implement the demo I link to in the question? #21

Closed travis-leith closed 1 year ago

travis-leith commented 1 year ago

I have implemented a Fable React style wrapper for DevExtreme. I have got all the basic components covered, including DataGrid. I want to make the color of cell text be dependent on the cell value. In Aggrid, this seems to be done purely in JS. But in DevExtreme, the only example I can find uses css. Here it is.

The way it works is they supply a render function to the React Component like this

import React from 'react';

import DataGrid, {
  Column,
  Sorting,
  Paging,
} from 'devextreme-react/data-grid';
import service from './data.js';
import DiffCell from './DiffCell.js';
import ChartCell from './ChartCell.js';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.dataSource = service.getWeekData();
  }

  render() {
    return (
      <DataGrid id="gridContainer"
        dataSource={this.dataSource}
        keyExpr="date"
        showRowLines={true}
        showColumnLines={false}
        showBorders={true}>
        <Sorting mode="none" />
        <Paging defaultPageSize={10} />
        <Column dataField="date" width={110} dataType="date" />
        <Column caption="Open" cellRender={DiffCell} />
        <Column caption="Close" cellRender={DiffCell} />
        <Column caption="Dynamics" minWidth={320} cellRender={ChartCell} />
        <Column caption="High" cellRender={DiffCell} />
        <Column caption="Low" cellRender={DiffCell} />
      </DataGrid>
    );
  }
}

export default App;

and the render function is defined thusly

import React from 'react';
import 'devextreme/localization/globalize/currency';
import { formatNumber } from 'devextreme/localization';

function gridCellData(gridData) {
  return gridData.data[gridData.column.caption.toLowerCase()];
}

export default function DiffCell(cellData) {
  return (
    <div className={gridCellData(cellData).diff > 0 ? 'inc' : 'dec'}>
      <div className="current-value">{formatNumber(gridCellData(cellData).value, { type: 'currency', currency: 'USD', precision: 2 })}</div>
      <div className="diff">{Math.abs(gridCellData(cellData).diff).toFixed(2)}</div>
    </div>
  );
}

so it looks like they set the class name depending on the value of the cell, then let the css do it's thing. on the few occasions that I have had to set a class name so far, I have been using prop.classnames from Feliz, which takes a list of strings.

I am hoping that FSS will allow me to avoid creating css files and just have F#. I am struggling to see how the conditional styling docs are applicable here.

Bjorn-Strom commented 1 year ago

Hey, @travis-leith . That sounds like a cool project!

You can indeed use Fss to write all your styling in F# to avoid CSS.

I have not used DevExpress but I believe you refer to this line:

<div className={gridCellData(cellData).diff > 0 ? 'inc' : 'dec'}>

I would do the following:

let cell diff = fss [ if diff > 0 then INC STYLING HERE else DEC STYLING HERE ]
Html.div [ prop.className (cell diff) ]

Alternatively:

let inc = fss [ INC STYLING ]
let dec = fss [ DEC STYLING ]
Html.div [ prop.className (if diff > 0 then inc else dec) ]

Does that answer your question?

travis-leith commented 1 year ago

Thanks that answers perfectly. I think my confusion came from the fact I did not realize the result of fss ... is in fact a string.