// @flow import * as React from "react"; import MqttContext from "mqtt/context"; import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction"; import ListItemText from "@material-ui/core/ListItemText"; import ListItemIcon from "@material-ui/core/ListItemIcon"; import throttle from "lodash/throttle"; import type { Icon } from "config/icon"; export type Helpers = { Icon: (props: { item: { +icon?: Icon }, state: State }) => React.Node, Label: (props: {}) => React.Node, Action: (props: {}) => React.Node }; export type BaseComponent = ( helpers: Helpers, item: T, state: State, nextValue: (item: T, next: string) => void ) => React.Node; export type Component = { id: string, name: string, desc: string, /* * TODO: Map<$Keys, string> doesn't really work :( * See https://github.com/facebook/flow/issues/5276 * If there is progress on the issue try to make it $Exact as well */ parameters: Map<$Keys, string>, baseComponent: BaseComponent }; type SuperT = $ReadOnly<{ text: string }>; const IconHelper = ({item, state}: { item: { +icon?: Icon }, state: State }) => ( {item.icon == null || item.icon.size(1).render(state)} ); const createHelpers = (item: T) => ({ Icon: IconHelper, Label: () => ( ), Action: (props) => ( ) }); const debouncedChangeState = (chState: (tpc: string, nxt: string) => void) => ( throttle( (item: T, next: string) => chState(item.topic, next), 50, { leading: true, trailing: true }) ); const createComponent = (component: Component) => ({ component: (item: T) => ( {({state, changeState}) => component.baseComponent( createHelpers(item), item, state, debouncedChangeState(changeState) )} ) }); export default createComponent;