Open lukaszrys opened 4 years ago
It looks pretty cool and I think it is very easy to implement it. The look and feel might be a little different since we are using the material-ui instead of bootstrap. There might be other material-ui components available thought. Would you like to try it out and submit a PR?
@lukaszrys I think you can add any component to your list of available components, the SchemaForm
component that you can import it using import { SchemaForm } from 'react-schema-form'
accepts a property named mapper
, the mapper is an object which can be like this
const mapper = {
'my-own-color-picker': YourColorPicker,
.... other components that you want to use in your forms
}
In your component you can debug the probs, they are straight forward, also it may help to use our color picker: if you are implementing your color picker, consider the ComposedComponent
which may be required, also utils
can be totally helpful during the implementation.
// @flow
import React from 'react';
import { CirclePicker, ChromePicker } from 'react-color';
import Icon from '@material-ui/core/Icon';
import Dialog from 'packages/common/web/dialog';
import Typography from '@material-ui/core/Typography';
import { withStyles } from '@material-ui/core/styles';
import Collapse from '@material-ui/core/Collapse';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import IconButton from '@material-ui/core/IconButton';
import ColorizeIcon from '@material-ui/icons/Colorize';
import ExpandLess from '@material-ui/icons/ExpandLess';
import ExpandMore from '@material-ui/icons/ExpandMore';
import type { SchemaFormLocalization } from 'packages/common/shared/types';
import { ComposedComponent, utils } from 'react-schema-form';
import { colorDialogStyles as styles } from './styles';
type Props = {
form: {
className: string,
key: string,
readonly: boolean,
title: string,
required: boolean,
style: any,
},
onChange: (key: string, value: string) => void,
model: any,
classes: any,
localization: SchemaFormLocalization,
};
type State = {
open: boolean,
color: string,
selectedColor: string,
disabled: boolean,
colorPickerOpen: boolean,
};
class ColorSelect extends React.Component<Props, State> {
state = {
open: false,
color: '',
disabled: true,
selectedColor: '',
colorPickerOpen: false,
};
static getDerivedStateFromProps(nextProps: Props, prevState: State) {
if (prevState.color == null || prevState.color === '') {
return {
color: '',
};
}
return null;
}
componentDidMount() {
this.setColor();
}
setColor = () => {
const { form, model } = this.props;
const color = utils.selectOrSet(form.key, model);
this.setState({
color: color || '',
selectedColor: color || '',
});
};
open = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
};
onChangeColor = color => {
this.setState({ selectedColor: color.hex, disabled: false });
};
submit = () => {
const { selectedColor } = this.state;
const {
form: { key },
onChange,
} = this.props;
onChange(key, selectedColor);
this.setState({ color: selectedColor, open: false, disabled: true });
};
colorPickerOpenHandle = () => {
this.setState(state => ({ colorPickerOpen: !state.colorPickerOpen }));
};
render() {
const {
classes,
form: { title, required, style },
localization: { getLocalizedString },
} = this.props;
const label = getLocalizedString(title) + (required ? ' *' : '');
const {
disabled,
selectedColor,
colorPickerOpen,
color,
open,
} = this.state;
const colors = [
'#D50000',
'#F44336',
'#e81d62',
'#9C27B0',
'#7341f2',
'#3F51B5',
'#2196F3',
'#03A9F4',
'#00BCD4',
'#009688',
'#4CAF50',
'#8ac249',
'#CDDC39',
'#FFEB3B',
'#FFC107',
'#fe9700',
'#fe5621',
'#795548',
'#9E9E9E',
'#607D8B',
];
return (
<div style={style}>
<div className={classes.div}>
<IconButton onClick={this.open}>
<Icon style={{ color }}>
{selectedColor ? 'lens' : 'panorama_fish_eye'}
</Icon>
</IconButton>
<Typography component="span" className={classes.title}>
{label}
</Typography>
</div>
<Dialog
title={getLocalizedString('form.select.color')}
open={open}
onClose={this.handleClose}
classes={{
paper: classes.colorDialog,
content: classes.colorDialogContent,
}}
actions={[
{
label: getLocalizedString('clear'),
onClick: () => {
this.setState(
{
selectedColor: '',
},
this.submit
);
this.handleClose();
},
},
{
label: getLocalizedString('submit'),
type: 'primary',
onClick: this.submit,
disabled,
},
]}
>
<List>
<ListItem>
<CirclePicker
width="185px"
circleSize={23}
color={selectedColor}
colors={colors}
onChange={this.onChangeColor}
/>
</ListItem>
<ListItem button onClick={this.colorPickerOpenHandle}>
<ListItemIcon className={classes.colorizeIcon}>
<ColorizeIcon />
</ListItemIcon>
<ListItemText primary="Color Picker" />
{colorPickerOpen ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={colorPickerOpen} timeout="auto" unmountOnExit>
<ChromePicker
color={selectedColor}
onChange={this.onChangeColor}
/>
</Collapse>
</List>
</Dialog>
</div>
);
}
}
export default withStyles(styles)(ComposedComponent(ColorSelect));
At the end you can use this with your form object which you should pass to SchemaForm
like this:
{ key: 'color', type: 'my-own-color-picker'}
The original plugin (http://schemaform.io/examples/bootstrap-example.html) has the Color pallette in "Kitchen Sink - More stuff").
Unfortunately, I do not see this one here. Is it possible to create it?