Changeset View
Changeset View
Standalone View
Standalone View
web/components/enum-settings-option.react.js
// @flow | // @flow | ||||
import classnames from 'classnames'; | import classnames from 'classnames'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import Checkbox from './checkbox.react'; | |||||
import EnumSettingsOptionInfo from './enum-settings-option-info.react.js'; | import EnumSettingsOptionInfo from './enum-settings-option-info.react.js'; | ||||
import css from './enum-settings-option.css'; | import css from './enum-settings-option.css'; | ||||
import Radio from './radio.react'; | import Radio from './radio.react'; | ||||
const iconPositionClassnames = { | |||||
top: css.optionIconTop, | |||||
center: css.optionIconCenter, | |||||
bottom: css.optionIconBottom, | |||||
}; | |||||
type InputType = 'radio' | 'checkbox'; | |||||
type IconPosition = $Keys<typeof iconPositionClassnames>; | |||||
type Props = { | type Props = { | ||||
+selected: boolean, | +selected: boolean, | ||||
+onSelect: () => void, | +onSelect: () => void, | ||||
+icon: React.Node, | +icon: React.Node, | ||||
+title: string, | +title: string, | ||||
+type?: InputType, | |||||
+iconPosition?: IconPosition, | |||||
+statements: $ReadOnlyArray<{ | +statements: $ReadOnlyArray<{ | ||||
+statement: string, | +statement: string, | ||||
+isStatementValid: boolean, | +isStatementValid: boolean, | ||||
+styleStatementBasedOnValidity: boolean, | +styleStatementBasedOnValidity: boolean, | ||||
}>, | }>, | ||||
}; | }; | ||||
function EnumSettingsOption(props: Props): React.Node { | function EnumSettingsOption(props: Props): React.Node { | ||||
const { icon, title, statements, selected, onSelect } = props; | const { | ||||
icon, | |||||
title, | |||||
statements, | |||||
selected, | |||||
onSelect, | |||||
type = 'radio', | |||||
iconPosition = 'center', | |||||
} = props; | |||||
const descriptionItems = React.useMemo( | const descriptionItems = React.useMemo( | ||||
() => | () => | ||||
statements.map( | statements.map( | ||||
({ statement, isStatementValid, styleStatementBasedOnValidity }) => ( | ({ statement, isStatementValid, styleStatementBasedOnValidity }) => ( | ||||
<EnumSettingsOptionInfo | <EnumSettingsOptionInfo | ||||
key={statement} | key={statement} | ||||
optionSelected={selected} | optionSelected={selected} | ||||
valid={isStatementValid} | valid={isStatementValid} | ||||
styleStatementBasedOnValidity={styleStatementBasedOnValidity} | styleStatementBasedOnValidity={styleStatementBasedOnValidity} | ||||
> | > | ||||
{statement} | {statement} | ||||
</EnumSettingsOptionInfo> | </EnumSettingsOptionInfo> | ||||
), | ), | ||||
), | ), | ||||
[selected, statements], | [selected, statements], | ||||
); | ); | ||||
const inputIcon = React.useMemo( | |||||
() => | |||||
type === 'checkbox' ? ( | |||||
<Checkbox checked={selected} /> | |||||
) : ( | |||||
<Radio checked={selected} /> | |||||
), | |||||
[type, selected], | |||||
); | |||||
const optionContainerClasses = React.useMemo( | const optionContainerClasses = React.useMemo( | ||||
() => | () => | ||||
classnames(css.optionContainer, { | classnames(css.optionContainer, { | ||||
[css.optionContainerSelected]: selected, | [css.optionContainerSelected]: selected, | ||||
}), | }), | ||||
[selected], | [selected], | ||||
); | ); | ||||
const optionIconClasses = React.useMemo( | |||||
() => classnames(css.optionIcon, iconPositionClassnames[iconPosition]), | |||||
[iconPosition], | |||||
); | |||||
return ( | return ( | ||||
<div className={optionContainerClasses} onClick={onSelect}> | <div className={optionContainerClasses} onClick={onSelect}> | ||||
<div className={css.optionIcon}>{icon}</div> | <div className={optionIconClasses}>{icon}</div> | ||||
<div className={css.optionContent}> | <div className={css.optionContent}> | ||||
<div className={css.optionTitle}>{title}</div> | <div className={css.optionTitle}>{title}</div> | ||||
<div className={css.optionDescription}>{descriptionItems}</div> | <div className={css.optionDescription}>{descriptionItems}</div> | ||||
</div> | </div> | ||||
<Radio checked={selected} /> | {inputIcon} | ||||
</div> | </div> | ||||
); | ); | ||||
} | } | ||||
export default EnumSettingsOption; | export default EnumSettingsOption; |