Skip to content

Instantly share code, notes, and snippets.

@cevr
Last active June 6, 2019 23:56
Show Gist options
  • Save cevr/2037e766b041216f59d19763cb6dcb6f to your computer and use it in GitHub Desktop.
Save cevr/2037e766b041216f59d19763cb6dcb6f to your computer and use it in GitHub Desktop.
With Arranger
import React from 'react';
import { findDOMNode } from 'react-dom';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import Radio from '@material-ui/core/Radio';
import clsx from 'clsx';
import { pipe, makeHandlers, makeEffect, makeState, makeRef } from 'arranger';
import { EditableText } from 'shared';
import { CONFIG_ACTIONS } from 'models/configuration';
import { makeStore, makeActions } from 'utils';
const useEnhancer = pipe(
makeStore(state => ({
configs: state.configuration.configs,
lastAction: state.configuration.lastAction,
})),
makeActions(actions => ({
updateConfiguration: actions.configuration.updateConfiguration,
})),
makeState('shouldOutline', 'setShouldOutline', false),
makeRef('lastItem'),
makeHandlers({
handleSelect: props => id => {
const items = props.configs.map(config =>
config.id === id ? { ...config, isSelected: true } : { ...config, isSelected: false },
);
props.updateConfiguration({ type: CONFIG_ACTIONS.EDIT, items });
},
handleEdit: props => ({ name, id }) => {
const items = props.configs.map(config => (config.id === id ? { ...config, name } : config));
props.updateConfiguration({ type: CONFIG_ACTIONS.EDIT, items });
},
}),
makeEffect(
props => {
if (props.lastAction === CONFIG_ACTIONS.ADD) {
const node = findDOMNode(props.lastItem.current);
node.scrollIntoView(true);
props.setShouldOutline(true);
setTimeout(() => {
props.setShouldOutline(false);
}, 3000);
}
},
['configs', 'lastAction'],
),
);
function ConfigLists(props) {
const { configs, handleSelect, handleEdit, lastItem, shouldOutline } = useEnhancer(props);
return (
<List>
{configs.map((config, index, arr) => {
const selected = config.isSelected;
const isLastItem = index === arr.length - 1;
return (
<ListItem
key={config.id}
onClick={() => handleSelect(config.id)}
className={clsx('listItem', {
active: selected,
outline: isLastItem && shouldOutline,
})}
{...(isLastItem ? { ref: lastItem } : {})}
>
<Radio checked={selected} />
<ListItemText
primary={
<EditableText
value={config.name}
onCommit={name => handleEdit({ name, id: config.id })}
/>
}
/>
</ListItem>
);
})}
</List>
);
}
export default ConfigLists;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment