Last active
August 21, 2018 19:07
-
-
Save ccapndave/4bd4aa5c70d0c1ff81cd7efbf597a819 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module type GridInterface = { | |
type t('a); | |
let make: (~xNames: list(string), ~yNames: list(string)) => t('a); | |
let xNames: t('a) => list(string); | |
let yNames: t('a) => list(string); | |
let get: (t('a), ~x: int, ~y: int) => option('a); | |
/* let set: (t('a), ~x: int, ~y: int, ~value: 'a) => t('a); */ | |
}; | |
module Grid: GridInterface = { | |
type t('a) = { | |
xNames: list(string), | |
yNames: list(string), | |
data: array(array(option('a))), | |
}; | |
let make = (~xNames, ~yNames) => { | |
xNames, | |
yNames, | |
data: Array.make_matrix(List.length(xNames), List.length(yNames), None), | |
}; | |
let xNames = grid => grid.xNames; | |
let yNames = grid => grid.yNames; | |
let get = (grid, ~x, ~y) => grid.data->Array.get(x)->Array.get(y); | |
/* TODO | |
let set = (grid, ~x, ~y, ~value) => { | |
let newData = Array.copy(grid.data); | |
newData->Array.get(y)->Array.set(x, value); | |
{...grid, data: newData}; | |
};*/ | |
}; | |
module Styles = { | |
open Css; | |
let grid = | |
style([ | |
height(vh(100.)), | |
width(pct(100.0)), | |
borderCollapse(`collapse), | |
]); | |
let y = style([maxWidth(px(10))]); | |
let yText = style([transform(rotateZ(deg(-90))), textAlign(center)]); | |
let x = style([textAlign(center)]); | |
let gridCell = | |
style([ | |
padding2(~v=px(5), ~h=px(20)), | |
border(px(1), solid, grey), | |
textAlign(center), | |
]); | |
}; | |
let component = ReasonReact.statelessComponent("Grid"); | |
let renderX = xNames => | |
<tr> | |
<th /> | |
{ | |
xNames | |
|> List.mapi((idx, xName) => | |
<th key={string_of_int(idx)} className=Styles.x> | |
{ReasonReact.string(xName)} | |
</th> | |
) | |
|> Array.of_list | |
|> ReasonReact.array | |
} | |
</tr>; | |
let make = | |
( | |
~grid: Grid.t('a), | |
~renderCell: 'a => ReasonReact.reactElement, | |
_children, | |
) => { | |
...component, | |
render: _self => | |
<table className=Styles.grid> | |
<thead> {renderX(Grid.xNames(grid))} </thead> | |
<tbody> | |
{ | |
Grid.yNames(grid) | |
|> List.mapi((y, yName) => | |
<tr key={string_of_int(y)}> | |
<td className=Styles.y> | |
<div className=Styles.yText> | |
{ReasonReact.string(yName)} | |
</div> | |
</td> | |
{ | |
Grid.xNames(grid) | |
|> List.mapi((x, _) => { | |
let cellContents = Grid.get(grid, ~x, ~y); | |
let renderedContent = | |
cellContents | |
->Belt.Option.mapWithDefault( | |
ReasonReact.null, | |
renderCell, | |
); | |
<td key={string_of_int(x)} className=Styles.gridCell> | |
renderedContent | |
</td>; | |
}) | |
|> Array.of_list | |
|> ReasonReact.array | |
} | |
</tr> | |
) | |
|> Array.of_list | |
|> ReasonReact.array | |
} | |
</tbody> | |
</table>, | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let yNames = ["Breakfast", "Lunch", "Dinner"]; | |
let xNames = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; | |
let grid = Grid.Grid.make(~xNames, ~yNames); | |
let renderCell = ReasonReact.string; | |
module SelectConfig = { | |
type t = string; | |
let id = data => data; | |
let toString = data => data; | |
}; | |
module Select = Select.MakeSelect(SelectConfig); | |
ReactDOMRe.renderToElementWithId( | |
<div> <Select /> <Grid grid renderCell /> </div>, | |
"app", | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module type SelectData = { | |
type t; | |
let id: t => string; | |
let toString: t => string; | |
}; | |
module Styles = { | |
open Css; | |
let search = style([width(px(300)), fontSize(px(20))]); | |
}; | |
module MakeSelect = (Data: SelectData) => { | |
type state = { | |
searchTerm: string, | |
results: Belt.List.t(Data.t), | |
}; | |
type action = | |
| SetSearch(string); | |
let reactList = list => list->Belt.List.toArray->ReasonReact.array; | |
let component = ReasonReact.reducerComponent("Select"); | |
let make = _children => { | |
...component, | |
initialState: () => {searchTerm: "", results: []}, | |
reducer: (action: action, state: state) => | |
switch (action) { | |
| SetSearch(searchTerm) => ReasonReact.Update({...state, searchTerm}) | |
}, | |
render: self => { | |
let renderedResults = | |
self.state.results | |
->Belt.List.map(result => | |
<li key={Data.id(result)}> | |
{ReasonReact.string(result->Data.toString)} | |
</li> | |
); | |
<div> | |
<input | |
className=Styles.search | |
value={self.state.searchTerm} | |
onChange={ | |
event => | |
self.send(SetSearch(event->ReactEvent.Form.target##value)) | |
} | |
/> | |
<ol> {reactList(renderedResults)} </ol> | |
</div>; | |
}, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment