UNPKG

@orfeas126/box-ui-elements

Version:
336 lines (311 loc) 10.4 kB
// @flow /* eslint-disable react-hooks/rules-of-hooks */ import * as React from 'react'; import type { Option } from 'components/pill-selector-dropdown/flowTypes'; import ContactDatalistItem from '../contact-datalist-item'; import PillSelectorDropdown from './PillSelectorDropdown'; import notes from './PillSelectorDropdown.notes.md'; import './PillSelectorDropdown.stories.scss'; const users = [ { id: 0, name: 'bob@foo.bar' }, { id: 1, name: 'sally@foo.bar', isExternalUser: true }, { id: 2, name: 'jean@foo.bar' }, { id: 3, name: 'longlonglonglonglonglonglonglonglonglonglonglongemail@foo.bar' }, { id: 4, name: 'anotherlonglonglonglonglonglonglonglonglonglonglonglongemail@foo.bar' }, { id: 5, name: 'aaa@foo.bar' }, { id: 6, name: 'bbb@foo.bar' }, { id: 7, name: 'ccc@foo.bar' }, ]; function generateProps({ setError, selectedOptions, setSelectedOptions, selectorOptions, setSelectorOptions }) { const handleInput = value => { const newSelectorOptions = []; if (value !== '') { users.forEach(user => { if (user.name.toLowerCase().indexOf(value.toLowerCase()) !== -1) { selectorOptions.push({ displayText: user.name, value: user.id, }); } }); } // As user is typing, reset error and update selectorOptions setSelectorOptions(newSelectorOptions); setError(''); }; const handleSelect = pills => { setSelectedOptions([...selectedOptions, ...pills]); }; const handleRemove = (option, index) => { const newSelectedOptions = [...selectedOptions]; newSelectedOptions.splice(index, 1); setSelectedOptions(newSelectedOptions); }; const validator = text => { // email input validation const pattern = /^[^\s<>@,]+@[^\s<>@,/\\]+\.[^\s<>@,]+$/i; return pattern.test(((text: any): string)); }; const validateForError = text => { const count = selectedOptions.length; let error = ''; if (!text && count === 0) { error = 'Field Required'; } else if (text && !validator(text)) { error = 'Invalid Email Address'; } setError(error); }; return { handleInput, handleRemove, handleSelect, validator, validateForError, }; } export const empty = () => { const [error, setError] = React.useState(''); const [selectedOptions, setSelectedOptions] = React.useState<SelectedOptions>([]); const [selectorOptions, setSelectorOptions] = React.useState<Array<Object>>([]); const { handleInput, handleRemove, handleSelect, validator, validateForError } = generateProps({ setError, selectedOptions, setSelectedOptions, selectorOptions, setSelectorOptions, }); return ( <PillSelectorDropdown allowCustomPills error={error} placeholder="Names or email addresses" onInput={handleInput} onRemove={handleRemove} onSelect={handleSelect} selectedOptions={selectedOptions} selectorOptions={selectorOptions} validateForError={validateForError} validator={validator} > {selectorOptions.map(option => ( <ContactDatalistItem key={option.value} name={option.displayText}> {option.displayText} </ContactDatalistItem> ))} </PillSelectorDropdown> ); }; export const withPills = () => { const [error, setError] = React.useState(''); const [selectedOptions, setSelectedOptions] = React.useState<SelectedOptions>([ { displayText: users[2].name, value: users[2].name, }, { displayText: users[1].name, value: users[1].name, }, { displayText: users[4].name, value: users[4].name, }, ]); const [selectorOptions, setSelectorOptions] = React.useState<Array<Object>>([]); const { handleInput, handleRemove, handleSelect, validator, validateForError } = generateProps({ setError, selectedOptions, setSelectedOptions, selectorOptions, setSelectorOptions, }); return ( <PillSelectorDropdown allowCustomPills error={error} placeholder="Names or email addresses" onInput={handleInput} onRemove={handleRemove} onSelect={handleSelect} selectedOptions={selectedOptions} selectorOptions={selectorOptions} validateForError={validateForError} validator={validator} > {selectorOptions.map(option => ( <ContactDatalistItem key={option.value} name={option.value}> {option.displayText} </ContactDatalistItem> ))} </PillSelectorDropdown> ); }; export const showRoundedPills = () => { const [error, setError] = React.useState(''); const [selectedOptions, setSelectedOptions] = React.useState([ { displayText: users[2].name, value: users[2].name, }, { displayText: users[1].name, value: users[1].name, }, { displayText: users[4].name, value: users[4].name, }, ]); const [selectorOptions, setSelectorOptions] = React.useState([]); const { handleInput, handleRemove, handleSelect, validator, validateForError } = generateProps({ setError, selectedOptions, setSelectedOptions, selectorOptions, setSelectorOptions, }); return ( <PillSelectorDropdown allowCustomPills error={error} placeholder="Names or email addresses" onInput={handleInput} onRemove={handleRemove} onSelect={handleSelect} selectedOptions={selectedOptions} selectorOptions={selectorOptions} showRoundedPills validateForError={validateForError} validator={validator} > {selectorOptions.map(option => ( <ContactDatalistItem key={option.value} name={option.value}> {option.displayText} </ContactDatalistItem> ))} </PillSelectorDropdown> ); }; export const showAvatars = () => { const [error, setError] = React.useState(''); const [selectedOptions, setSelectedOptions] = React.useState([ { text: users[2].name, value: users[2].name, id: users[2].id, }, { text: users[1].name, value: users[1].name, id: users[1].id, isExternalUser: users[1].isExternalUser, }, { text: users[3].name, value: users[3].name, id: users[3].id, }, ]); const [selectorOptions, setSelectorOptions] = React.useState([]); const { handleInput, handleRemove, handleSelect, validator, validateForError } = generateProps({ setError, selectedOptions, setSelectedOptions, selectorOptions, setSelectorOptions, }); return ( <PillSelectorDropdown allowCustomPills error={error} placeholder="Names or email addresses" onInput={handleInput} onRemove={handleRemove} onSelect={handleSelect} selectedOptions={selectedOptions} selectorOptions={selectorOptions} showAvatars showRoundedPills validateForError={validateForError} validator={validator} > {selectorOptions.map(option => ( <ContactDatalistItem key={option.value} name={option.value}> {option.displayText} </ContactDatalistItem> ))} </PillSelectorDropdown> ); }; export const customPillStyles = () => { /** * NOTE: For consistent styling, use bdl-RoundPill mixin when creating custom pill classes. * * Example: * * .bdl-RoundPill { * &.is-custom { * @include bdl-RoundPill($border-color: $bdl-watermelon-red-50, $selected-border-color: $bdl-watermelon-red-50); * } * } * * */ const getPillClassName = ({ value }) => { switch (value) { case '2': return 'is-custom'; default: return ''; } }; const [error, setError] = React.useState(''); const [selectedOptions, setSelectedOptions] = React.useState<Option[]>([ { displayText: 'default@example.com', value: '1', }, { displayText: 'custom@example.com', value: '2', }, ]); const [selectorOptions, setSelectorOptions] = React.useState<Option[]>([]); const { handleInput, handleRemove, handleSelect, validator, validateForError } = generateProps({ setError, selectedOptions, setSelectedOptions, selectorOptions, setSelectorOptions, }); return ( <PillSelectorDropdown allowCustomPills error={error} getPillClassName={getPillClassName} placeholder="Names or email addresses" onInput={handleInput} onRemove={handleRemove} onSelect={handleSelect} selectedOptions={selectedOptions} selectorOptions={selectorOptions} showRoundedPills validateForError={validateForError} validator={validator} > {selectorOptions.map(option => ( <ContactDatalistItem key={option.value} name={option.displayText}> {option.displayText} </ContactDatalistItem> ))} </PillSelectorDropdown> ); }; export default { title: 'Components/PillSelectorDropdown', component: PillSelectorDropdown, parameters: { notes, }, };