import React from 'react' import { DatePicker } from '../../' const DatePickerDefault = (props) => ( <div> <DatePicker pickerId="date-picker-default" {...props} /> </div> ) export default DatePickerDefault
import React from 'react' import { DatePicker } from '../../' const DatePickerHideIcon = (props) => ( <div> <DatePicker hideIcon pickerId="date-picker-hide-icon" {...props} /> </div> ) export default DatePickerHideIcon
The defaultDate
/default_date
prop has a null or empty string value by default. You can pass an ISO date string (preferred rails method) or date object (preferred JS method) if you want a default value on page load. Use Ruby UTC DateTime objects and convert them to ISO date strings with DateTime.now.utc.iso8601
.
If you use a Date object without UTC time standardization the Date Picker kit may misinterpret that date as yesterdays date (consequence of timezone differentials and the Javascript Date Object constructor). See this GitHub issue for more information and the anti-pattern examples below.
import React from 'react' import { DatePicker } from '../../' const DatePickerDefaultDate = (props) => ( <div> <DatePicker defaultDate="07/31/2020" label="Default Date String" pickerId="date-picker-default-date1" {...props} /> <DatePicker defaultDate={new Date().fp_incr(1)} label="Default Date Dynamic" pickerId="date-picker-default-date2" {...props} /> <DatePicker defaultDate={[new Date(), new Date().fp_incr(7)]} label="Default Date Range" mode="range" pickerId="date-picker-default-date3" {...props} /> <DatePicker label="Default Behavior" pickerId="date-picker-default-date4" {...props} /> </div> ) export default DatePickerDefaultDate
The date picker is built with the text input kit. Text input props you pass to the date picker kit will be forwarded to the input, with a few exceptions. The value
attribute is automatically handled and bound to whatever date string is contained by the input field. You cannot pass a custom value prop. id
props passed to the date picker kit will be assigned to it's parent/wrapper div. The pickerId
prop is passed directly to the input and is required to instatiate the date picker.
You must use inputAria
or input_aria
and inputData
or input_data
props if you wish to pass data or aria attributes to the text input kit. If you use data
or aria
props they will be passed to the date picker kit itself instead. Also be aware the default behavior of text input aria and data props is to pass those props to attributes on the wrapping div not on the input itself.
The placeholder prop has a default string value: "Select Date". You can replace this with your own string or an empty string if you'd prefer it blank.
import React from 'react' import { DatePicker } from '../../' const DatePickerInput = (props) => ( <div> <DatePicker inputAria={{ label: 'input-field' }} inputData={{ key: 'value', key2: 'value2' }} label="Aria, Name, and Data Attributes" name="date-field" pickerId="date-picker-input1" {...props} /> <DatePicker label="Custom Placeholder" pickerId="date-picker-input2" placeholder="custom-placeholder" {...props} /> <DatePicker label="Blank Placeholder" pickerId="date-picker-input3" placeholder="" {...props} /> <DatePicker disableInput label="Disable Input" pickerId="date-picker-input4" placeholder="Disabled Input" {...props} /> </div> ) export default DatePickerInput
Default label prop is "Date Picker"
. To remove the label set the hideLabel
prop in React or the hide_label
prop in Rails to true
.
import React from 'react' import { DatePicker } from '../../' const DatePickerLabel = (props) => ( <div> <DatePicker label="Your Label Here" pickerId="date-picker-label" {...props} /> <DatePicker hideLabel pickerId="date-picker-hide-label" {...props} /> </div> ) export default DatePickerLabel
Your change handler function has access to two arguments: dateStr
and selectedDates
.
The first, dateStr
, is a string of the chosen date. The second, selectedDates
, is an array of selected date objects. In many use cases selectedDates
will have only one value but you'll still need to access it from index 0.
import React, { useState } from 'react' import { DatePicker, LabelValue } from '../..' const DatePickerOnChange = (props) => { const today = new Date() const [dateString, setDateString] = useState(today.toLocaleDateString()) const [dateObj, setDateObj] = useState([today]) const changeHandler = (dateStr, selectedDates) => { setDateString(dateStr) setDateObj(selectedDates) } return ( <div> <DatePicker defaultDate={dateString} marginBottom="lg" onChange={changeHandler} pickerId="date-picker-onchange" {...props} /> <LabelValue label="Date Object" marginBottom="lg" value={dateObj[0] ? dateObj[0].toString() : ''} {...props} /> <LabelValue label="Date String" value={dateString} {...props} /> </div> ) } export default DatePickerOnChange
import React from 'react' import { DatePicker } from '../../' const DatePickerRange = (props) => ( <div> <DatePicker defaultDate={[new Date(), new Date().fp_incr(7)]} mode="range" pickerId="date-picker-range" {...props} /> </div> ) export default DatePickerRange
A full list of formatting tokens, i.e. "m/d/Y"
can be found here.
import React from 'react' import { DatePicker } from '../../' const DatePickerFormat = (props) => ( <div> <DatePicker defaultDate={new Date()} format="m-d-Y" pickerId="date-picker-format1" {...props} /> <DatePicker defaultDate={new Date()} format="m/d/y" pickerId="date-picker-format2" {...props} /> <DatePicker defaultDate={new Date()} format="n-j-y" pickerId="date-picker-format3" {...props} /> <DatePicker defaultDate={new Date()} format="Y-d-m" pickerId="date-picker-format4" {...props} /> </div> ) export default DatePickerFormat
import React from 'react' import { DatePicker } from '../../' const DatePickerDisabled = (props) => ( <div> <DatePicker disableDate={[new Date().fp_incr(1)]} label="Disable Single Date" pickerId="single-disabled-date" {...props} /> <DatePicker disableDate={[new Date().fp_incr(1), new Date().fp_incr(3)]} label="Disable Multiple Dates" pickerId="multiple-disabled-dates" {...props} /> <DatePicker disableRange={[ { from: new Date().fp_incr(1), to: new Date().fp_incr(7), }, ]} label="Disable Single Range" pickerId="single-date-range" {...props} /> <DatePicker disableRange={[ { from: new Date().fp_incr(1), to: new Date().fp_incr(3), }, { from: new Date().fp_incr(7), to: new Date().fp_incr(14), }, ]} label="Disable Multiple Ranges" pickerId="multiple-date-ranges" {...props} /> <DatePicker disableWeekdays={['Sunday', 'Saturday']} label="Disable Specific Weekdays" pickerId="disabled-weekdays" {...props} /> </div> ) export default DatePickerDisabled
import React from 'react' import { DatePicker } from '../../' const DatePickerMinMax = (props) => ( <div> <DatePicker label="Dynamic dates using flatpickr increment function" maxDate={new Date().fp_incr(3)} minDate={new Date().fp_incr(-3)} pickerId="date-picker-min-max1" {...props} /> <DatePicker format="m/d/Y" label="Absolute formatted dates" maxDate="10/20/2020" minDate="10/10/2020" pickerId="date-picker-min-max2" {...props} /> </div> ) export default DatePickerMinMax
import React from 'react' import { DatePicker } from '../../' const DatePickerError = (props) => ( <div> <DatePicker error="Invalid date. Please pick a valid date." pickerId="date-picker-error" {...props} /> </div> ) export default DatePickerError
import React, { useEffect } from 'react' import { Button, DatePicker } from '../../' const DatePickerFlatpickrMethods = () => { let fpInstance useEffect(() => { fpInstance = document.querySelector('#fp-methods')._flatpickr }, []) const clickHandlerClear = () => { fpInstance.clear() } const clickHandlerClose = () => { fpInstance.close() } const clickHandlerToday = () => { fpInstance.setDate(new Date(), true) } return ( <div> <Button marginRight="sm" onClick={clickHandlerClose} text="Close" /> <Button marginRight="sm" onClick={clickHandlerClear} text="Clear" /> <Button onClick={clickHandlerToday} text="Today" /> <DatePicker hideLabel marginTop="sm" pickerId="fp-methods" /> </div> ) } export default DatePickerFlatpickrMethods
You can find a full list of flatpickr events and hooks in their documentation.
import React from 'react' import { DatePicker } from '../../' const DatePickerHooks = (props) => { // Define hooks const changeHook = () => { alert('date changed') } const openHook = () => { alert('calendar opened') } // Access flatpickr instances with picker ids and assign them variables window.addEventListener('DOMContentLoaded', () => { const fpChange = document.querySelector('#date-picker-hooks-onchange')._flatpickr const fpOpen = document.querySelector('#date-picker-hooks-onopen')._flatpickr // Push one or more hooks to flatpickr instance's Event config arrays fpChange.config.onChange.push(changeHook) fpOpen.config.onOpen.push(openHook) }) return ( <div> <DatePicker label="onChange" pickerId="date-picker-hooks-onchange" {...props} /> <DatePicker label="onOpen" pickerId="date-picker-hooks-onopen" {...props} /> </div> ) } export default DatePickerHooks
Defaults to [1900, 2100]
. Combine with min-max prop for best results.
import React from 'react' import { DatePicker } from '../../' const DatePickerYearRange = (props) => ( <div> <DatePicker defaultDate="05/05/2015" maxDate="12/31/2018" minDate="01/01/2015" pickerId="date-picker-year-range" yearRange={[2015, 2018]} {...props} /> </div> ) export default DatePickerYearRange
/* @flow */ import React, { useState } from 'react' import { FileUpload, List, ListItem, } from '../..' const AcceptedFilesList = ({ files }: FileList) => ( <List> {files.map((file) => ( <ListItem key={file.name}>{file.name}</ListItem> ))} </List> ) const FileUploadDefault = (props) => { const [filesToUpload, setFilesToUpload] = useState([]) const handleOnFilesAccepted = (files) => { setFilesToUpload([...filesToUpload, ...files]) } return ( <div> <AcceptedFilesList files={filesToUpload} {...props} /> <FileUpload onFilesAccepted={handleOnFilesAccepted} {...props} /> </div> ) } export default FileUploadDefault
/* @flow */ import React, { useState } from 'react' import { FileUpload, List, ListItem, } from '../..' const AcceptedFilesList = ({ files }: FileList) => ( <List> {files.map((file) => ( <ListItem key={file.name}>{file.name}</ListItem> ))} </List> ) const FileUploadAccept = (props) => { const [filesToUpload, setFilesToUpload] = useState([]) const handleOnFilesAccepted = (files) => { setFilesToUpload([...filesToUpload, ...files]) } return ( <div> <AcceptedFilesList files={filesToUpload} {...props} /> <FileUpload accept={['image/svg+xml']} onFilesAccepted={handleOnFilesAccepted} {...props} /> </div> ) } export default FileUploadAccept
import React from 'react' import { FormGroup, TextInput } from '../../' const FormGroupDefault = (props) => ( <div> <FormGroup> <TextInput label="First Name" placeholder="Enter First Name" {...props} /> <TextInput label="Middle Intial" placeholder="Enter Middle Initial" {...props} /> <TextInput label="Last Name" placeholder="Enter Last Name" {...props} /> </FormGroup> </div> ) export default FormGroupDefault
import React from 'react' import { Button, FormGroup, TextInput } from '../../' const FormGroupButton = (props) => ( <div> <div> <FormGroup> <TextInput label="With Label" placeholder="Search" {...props} /> <Button onClick={() => alert('Button Clicked!')} text="Submit" variant="secondary" {...props} /> </FormGroup> </div> <br /> <div> <FormGroup> <TextInput placeholder="Search" {...props} /> <Button onClick={() => alert('Button Clicked!')} text="Submit" variant="secondary" {...props} /> </FormGroup> </div> </div> ) export default FormGroupButton
import React from 'react' import { DatePicker, FormGroup, TextInput } from '../../' const FormGroupDatePicker = (props) => ( <div> <FormGroup> <TextInput label="Event" placeholder="Event Name" {...props} /> <DatePicker label="event date" pickerId="date-picker-default" {...props} /> </FormGroup> </div> ) export default FormGroupDatePicker
import React from 'react' import { FormGroup, Select, TextInput } from '../../' const FormGroupSelect = (props) => { const options = [ { value: 'Country' }, { value: 'Pop' }, { value: 'Rock' }, { value: 'Hip-Hop/Rap' }, { value: 'Classical' }, { value: 'Gospel' }, { value: 'Alternative' }, { value: 'Indie' }, { value: 'Other' }, ] return ( <div> <FormGroup> <TextInput label="Artist" placeholder="Enter Artist Name" {...props} /> <Select blankSelection="Genre" options={options} {...props} /> </FormGroup> </div> ) } export default FormGroupSelect
import React, { useState } from 'react' import { FormGroup, SelectableCard } from '../../' const FormGroupSelectableCard = (props) => { const [value, setValue] = useState('') const handleSelect = (event) => { setValue(event.target.value) } return ( <div> <FormGroup> <SelectableCard checked={value === 'cat'} inputId="cat1" multi={false} name="animal" onChange={handleSelect} value="cat" {...props} > {'Cat'} </SelectableCard> <SelectableCard checked={value === 'dog'} inputId="dog1" multi={false} name="animal" onChange={handleSelect} value="dog" {...props} > {'Dog'} </SelectableCard> </FormGroup> </div> ) } export default FormGroupSelectableCard
import React, { useState } from 'react' import { FormGroup, SelectableCardIcon } from '../../' const FormGroupSelectableCardIcon = (props) => { const [selectedFormat, toggleFormat] = useState(null) return ( <div> <FormGroup> <SelectableCardIcon checked={selectedFormat === 'basketball'} icon="basketball-ball" inputId={7} name="select" onChange={() => toggleFormat('basketball')} titleText="Basketball" value="basketball" {...props} /> <SelectableCardIcon checked={selectedFormat === 'football'} icon="football-ball" inputId={8} name="select" onChange={() => toggleFormat('football')} titleText="Football" value="football" {...props} /> </FormGroup> </div> ) } export default FormGroupSelectableCardIcon
import React from 'react' import FormPill from '../_form_pill.jsx' const FormPillDefault = (props) => { return ( <div> <FormPill avatarUrl="https://randomuser.me/api/portraits/women/44.jpg" name="Anna Black" onClick={() => { alert('Click!') }} {...props} /> <br /> <br /> <FormPill name="Anna Black" onClick={() => { alert('Click!') }} {...props} /> </div> ) } export default FormPillDefault
import React from 'react' import FormPill from '../_form_pill.jsx' const FormPillDefault = (props) => { return ( <div> <FormPill onClick={() => { alert('Click!') }} text="this is a tag" {...props} /> </div> ) } export default FormPillDefault
import React from 'react' import { Radio } from '../../' const RadioDefault = () => { const ref = React.createRef() return ( <div> <Radio label="Power" name="Group2" ref={ref} tabIndex={0} value="Power" /> <br /> <Radio defaultChecked={false} label="Nitro" name="Group2" value="Nitro" /> <br /> <Radio defaultChecked={false} label="Google" name="Group2" value="Google" /> </div> ) } export default RadioDefault
import React, { useState } from 'react' import { Radio } from '../../' const RadioCustom = (props) => { const [choice, setChoice] = useState('power') const handleOnChange = ({ target }) => { setChoice(target.value) } return ( <div> <p> {'Your choice is: '} <code>{choice}</code> </p> <br /> <Radio className="my_custom_class" label="Custom Power" {...props} > <input checked={choice === 'power'} name="custom" onChange={handleOnChange} type="radio" value="power" {...props} /> </Radio> <br /> <Radio className="my_custom_class" label="Custom Nitro" {...props} > <input checked={choice === 'nitro'} name="custom" onChange={handleOnChange} type="radio" value="nitro" {...props} /> </Radio> <br /> <Radio className="my_custom_class" label="Custom Google" {...props} > <input checked={choice === 'google'} name="custom" onChange={handleOnChange} type="radio" value="google" {...props} /> </Radio> </div> ) } export default RadioCustom
Error shows that the radio option must be selected or is invalid (ie when used in a form it signals a user to fix an error).
import React from 'react' import { Radio } from '../..' const RadioError = () => { return ( <div> <Radio error label="Power" name="Group2" value="Power" /> </div> ) } export default RadioError
import React from 'react' import { Select } from '../../' const SelectDefault = (props) => { const options = [ { value: '1', text: 'Burgers', }, { value: '2', text: 'Pizza', }, { value: '3', text: 'Tacos', }, ] return ( <div> <Select label="Favorite Food" name="food" options={options} {...props} /> </div> ) } export default SelectDefault
import React from 'react' import { Select } from '../../' const SelectBlank = (props) => { const options = [ { value: 'USA' }, { value: 'Canada' }, { value: 'Brazil' }, { value: 'Philippines' }, ] return ( <div> <Select blankSelection="Select One..." label="Where do you live" name="location" options={options} {...props} /> </div> ) } export default SelectBlank
import React from 'react' import { Select } from '../../' const SelectDisabledOptions = (props) => { const options = [ { value: '1', disabled: true, text: 'Espresso', }, { value: '2', text: 'Americano', }, { value: '3', disabled: true, text: 'Cappuccino', }, { value: '4', text: 'Mocha', }, { value: '5', text: 'Flat White', }, { value: '6', text: 'Latte', }, ] return ( <div> <Select label="Favorite Coffee" name="coffee" options={options} value="2" {...props} /> </div> ) } export default SelectDisabledOptions
import React from 'react' import { Select } from '../../' const SelectDisabled = (props) => { const options = [ { value: 'Apple Pie' }, { value: 'Cookies' }, { value: 'Ice Cream' }, { value: 'Brownies' }, ] return ( <div> <Select disabled label="Favorite Dessert" name="dessert" options={options} {...props} /> </div> ) } export default SelectDisabled
import React from 'react' import { Select } from '../../' const SelectRequired = (props) => { const options = [ { value: 'Left' }, { value: 'Right' }, { value: 'I go without laces' }, ] return ( <div> <Select blankSelection="Select One..." label="Which shoe do you tie first?" name="shoe" options={options} required {...props} /> </div> ) } export default SelectRequired
import React from 'react' import { Select } from '../../' const SelectValueTextSame = (props) => { const options = [ { value: 'Football' }, { value: 'Baseball' }, { value: 'Basketball' }, { value: 'Hockey' }, ] return ( <div> <Select label="Favorite Sport" name="sports" options={options} {...props} /> </div> ) } export default SelectValueTextSame
import React from 'react' import { Select } from '../../' const SelectCustomSelect = (props) => { return ( <div> <Select label="Favorite Holiday"> <select id="holiday" name="holiday" {...props} > <option value="1">{'Christmas'}</option> <option value="2">{'Thanksgiving'}</option> <option value="3">{'Halloween'}</option> <option value="4">{'Fourth of July'}</option> </select> </Select> </div> ) } export default SelectCustomSelect
Select w/ Error shows that the radio option must be selected or is invalid (ie when used in a form it signals a user to fix an error).
import React from 'react' import { Body, Select } from '../..' const SelectError = (props) => { const options = [ { value: '1', text: 'Burgers', }, { value: '2', text: 'Pizza', }, { value: '3', text: 'Tacos', }, ] return ( <div> <Select error="Please make a valid selection" label="Favorite Food" name="food" options={options} value="2" {...props} /> <Body error="Please make a valid selection" status="negative" {...props} /> </div> ) } export default SelectError
Default Selectable Cards are multi select by default.
import React, { useState } from 'react' import SelectableCard from '../_selectable_card.jsx' const SelectableCardDefault = (props) => { const [selectedWithIcon, setSelectedWithIcon] = useState(true) const [selectedNoIcon, setSelectedNoIcon] = useState(true) const [unselected, setUnselected] = useState(false) const [disabled, setDisabled] = useState(false) return ( <div className="pb--doc-demo-row"> <SelectableCard checked={selectedWithIcon} icon inputId="selectedWithIcon" name="selectedWithIcon" onChange={() => setSelectedWithIcon(!selectedWithIcon)} value="selectedWithIcon" {...props} > {'Selected, with icon'} </SelectableCard> <SelectableCard checked={selectedNoIcon} icon={false} inputId="selectedWithoutIcon" name="selectedWithoutIcon" onChange={() => setSelectedNoIcon(!selectedNoIcon)} value="selectedWithoutIcon" {...props} > {'Selected, without icon'} </SelectableCard> <SelectableCard checked={unselected} inputId="unselected" name="unselected" onChange={() => setUnselected(!unselected)} value="unselected" {...props} > {'Unselected'} </SelectableCard> <SelectableCard checked={disabled} disabled inputId="disabled" name="disabled" onChange={() => setDisabled(!disabled)} value="disabled" {...props} > {'Disabled'} </SelectableCard> </div> ) } export default SelectableCardDefault
Single Select allows only one selectable card in the set to be selected.
import React, { useState } from 'react' import SelectableCard from '../_selectable_card.jsx' const SelectableCardSingleSelect = (props) => { const [selected, setSelected] = useState(null) const handleSelect = (event) => { setSelected(event.target.value) } return ( <div className="pb--doc-demo-row"> <SelectableCard checked={selected === 'male'} inputId="male1" multi={false} name="gender" onChange={handleSelect} value="male" {...props} > {'Male'} </SelectableCard> <SelectableCard checked={selected === 'female'} inputId="female1" multi={false} name="gender" onChange={handleSelect} value="female" {...props} > {'Female'} </SelectableCard> <SelectableCard checked={selected === 'other'} inputId="other1" multi={false} name="gender" onChange={handleSelect} value="other" {...props} > {'Other'} </SelectableCard> </div> ) } export default SelectableCardSingleSelect
Selectable Cards can pass text or block content.
import React, { useState } from 'react' import { Body, SelectableCard, Title } from '../../' const SelectableCardBlock = (props) => { const [block, setBlock] = useState(true) const [tag, setTag] = useState(false) const handleSelect = (event) => { setBlock(event.target.checked) } const handleTag = (event) => { setTag(event.target.checked) } return ( <div className="pb--doc-demo-row"> <SelectableCard checked={block} inputId="block" name="block" onChange={handleSelect} value="block" {...props} > <Title size={4} text="Block" {...props} /> <Body tag="span" {...props} > {'This uses block'} </Body> </SelectableCard> <SelectableCard checked={tag} inputId="tag" name="tag" onChange={handleTag} text="This passes text through the tag" value="tag" {...props} /> </div> ) } export default SelectableCardBlock
Selectable Cards can pass images with optional text.
import React, { useState } from 'react' import { Body, Image, SelectableCard, } from '../../' const SelectableCardImage = (props) => { const [selectedImage, setSelectedImage] = useState(true) const [unselectedImage, setUnselectedImage] = useState(false) return ( <div className="pb--doc-demo-row"> <SelectableCard checked={selectedImage} icon inputId="selectableImage" name="selectableImage" onChange={() => setSelectedImage(!selectedImage)} value="selectableImage" {...props} > <Image rounded size="xl" url="https://unsplash.it/500/400/?image=634" {...props} /> <Body>{'Add text here'}</Body> </SelectableCard> <SelectableCard checked={unselectedImage} icon inputId="unselectedImage" name="unselectedImage" onChange={() => setUnselectedImage(!unselectedImage)} value="unselectedImage" {...props} > <Image rounded size="xl" url="https://unsplash.it/500/400/?image=634" {...props} /> </SelectableCard> </div> ) } export default SelectableCardImage
Selectable Cards can show an input indicating state.
import React from 'react' import { Body, SelectableCard, Title, } from '../../' class SelectableCardInput extends React.Component { state = { firstCheckbox: true, secondCheckbox: true, thirdCheckbox: false, forthCheckbox: false, radioSelected: 'first', } handleSelect = (event) => { this.setState({ [event.target.name]: event.target.checked, }) } handleRadioSelect = (event) => { this.setState({ radioSelected: event.target.value, }) } render() { return ( <> <Title size={3} text="What programming languages do you know?" /> <br /> <SelectableCard checked={this.state.firstCheckbox} inputId="firstCheckbox" name="firstCheckbox" onChange={this.handleSelect} value="firstCheckbox" variant="displayInput" > <Body>{'Ruby'}</Body> </SelectableCard> <SelectableCard checked={this.state.secondCheckbox} inputId="secondCheckbox" name="secondCheckbox" onChange={this.handleSelect} value="secondCheckbox" variant="displayInput" > <Body>{'JavaScript'}</Body> </SelectableCard> <SelectableCard checked={this.state.thirdCheckbox} inputId="thirdCheckbox" name="thirdCheckbox" onChange={this.handleSelect} value="thirdCheckbox" variant="displayInput" > <Body>{'TypeScript'}</Body> </SelectableCard> <SelectableCard checked={this.state.fourthCheckbox} inputId="fourthCheckbox" name="fourthCheckbox" onChange={this.handleSelect} value="fourthCheckbox" variant="displayInput" > <Body>{'Swift'}</Body> </SelectableCard> <br /> <Title size={3} text="How likely are you to recommend Playbook to a friend?" /> <br /> <SelectableCard checked={this.state.radioSelected === 'first'} inputId="radio-1" multi={false} name="radio" onChange={this.handleRadioSelect} value="first" variant="displayInput" > <Body>{'5'}</Body> </SelectableCard> <SelectableCard checked={this.state.radioSelected === 'second'} inputId="radio-2" multi={false} name="radio" onChange={this.handleRadioSelect} value="second" variant="displayInput" > <Body> {'4'} </Body> </SelectableCard> <SelectableCard checked={this.state.radioSelected === 'third'} inputId="radio-3" multi={false} name="radio" onChange={this.handleRadioSelect} value="third" variant="displayInput" > <Body>{'3'}</Body> </SelectableCard> <SelectableCard checked={this.state.radioSelected === 'fourth'} inputId="radio-4" multi={false} name="radio" onChange={this.handleRadioSelect} value="fourth" variant="displayInput" > <Body>{'2'}</Body> </SelectableCard> <SelectableCard checked={this.state.radioSelected === 'fifth'} inputId="radio-5" multi={false} name="radio" onChange={this.handleRadioSelect} value="fifth" variant="displayInput" > <Body>{'1'}</Body> </SelectableCard> </> ) } } export default SelectableCardInput
import React, { useState } from 'react' import { Body, SelectableCard, Title } from '../..' const SelectableCardError = (props) => { const [football, setFootball] = useState(false) const [basketball, setBasketball] = useState(false) const [baseball, setBaseball] = useState(false) return ( <div> <Title {...props} size={3} text="What sports do you like?" /> <br /> <SelectableCard {...props} checked={football} error inputId="football" name="football" onChange={() => setFootball(!football)} value="football" variant="displayInput" > <Body {...props}>{'Football'}</Body> </SelectableCard> <SelectableCard {...props} checked={basketball} error inputId="basketball" name="basketball" onChange={() => setBasketball(!basketball)} value="basketball" variant="displayInput" > <Body {...props}>{'Basketball'}</Body> </SelectableCard> <SelectableCard {...props} checked={baseball} error inputId="baseball" name="baseball" onChange={() => setBaseball(!baseball)} value="baseball" variant="displayInput" > <Body {...props}>{'Baseball'}</Body> </SelectableCard> </div> ) } export default SelectableCardError
import React, { useState } from 'react' import { SelectableCardIcon } from '../../' const SelectableCardIconDefault = (props) => { const [selected, setSelected] = useState(true) const [unselected, setUnselected] = useState(false) return ( <div className="pb--doc-demo-row"> <SelectableCardIcon bodyText="Export" checked={selected} icon="chart-line" inputId={1} onChange={() => setSelected(!selected)} titleText="Quarterly Report" {...props} /> <SelectableCardIcon bodyText="Export" checked={unselected} icon="chart-pie" inputId={2} onChange={() => setUnselected(!unselected)} titleText="Market Share" {...props} /> <SelectableCardIcon bodyText="Export" disabled icon="analytics" inputId={3} titleText="Comprehensive" {...props} /> </div> ) } export default SelectableCardIconDefault
import React, { useState } from 'react' import { SelectableCardIcon } from '../../' const SelectableCardIconCheckmark = (props) => { const [selected, setSelected] = useState(true) const [unselected, setUnselected] = useState(false) return ( <div className="pb--doc-demo-row"> <SelectableCardIcon bodyText="Howdy Partner." checked={selected} checkmark icon="hat-cowboy" inputId={4} onChange={() => setSelected(!selected)} titleText="Cowboy" {...props} /> <SelectableCardIcon bodyText="Poof, you're a sandwich." checked={unselected} checkmark icon="hat-wizard" inputId={5} onChange={() => setUnselected(!unselected)} titleText="Wizard" {...props} /> <SelectableCardIcon bodyText="Where is the lamb sauce?" checkmark disabled icon="hat-chef" inputId={6} titleText="Chef" {...props} /> </div> ) } export default SelectableCardIconCheckmark
import React, { useState } from 'react' import { SelectableCardIcon } from '../../' const SelectableCardIconSingleSelect = (props) => { const [selectedFormat, toggleFormat] = useState(null) return ( <div className="pb--doc-demo-row"> <SelectableCardIcon checked={selectedFormat === 'car'} icon="car" inputId={7} name="select" onChange={() => toggleFormat('car')} titleText="Car" value="car" {...props} /> <SelectableCardIcon checked={selectedFormat === 'bus'} icon="bus" inputId={8} name="select" onChange={() => toggleFormat('bus')} titleText="Bus" value="bus" {...props} /> <SelectableCardIcon checked={selectedFormat === 'subway'} icon="subway" inputId={9} name="select" onChange={() => toggleFormat('subway')} titleText="Subway" value="subway" {...props} /> </div> ) } export default SelectableCardIconSingleSelect
import React, { useState } from 'react' import { SelectableIcon } from '../../' const SelectableIconDefault = (props) => { const [ checkSelected, toggleSelected ] = useState(true) const [ checkUnselected, toggleUnselected ] = useState(false) const [ checkDisabled, toggleDisabled ] = useState(false) return ( <div className="pb--doc-demo-row"> <SelectableIcon checked={checkSelected} icon="dollar-sign" inputId={10} onChange={() => toggleSelected(!checkSelected)} text="US Dollar" {...props} /> <SelectableIcon checked={checkUnselected} icon="euro-sign" inputId={11} onChange={() => toggleUnselected(!checkUnselected)} text="Euro" {...props} /> <SelectableIcon checked={checkDisabled} disabled icon="yen-sign" inputId={12} onChange={() => toggleDisabled(!checkDisabled)} text="Yen" {...props} /> </div> ) } export default SelectableIconDefault
import React, { useState } from 'react' import { SelectableIcon } from '../../' const SelectableIconSingleSelect = (props) => { const [ selectedFormat, toggleFormat ] = useState(null) return ( <div className="pb--doc-demo-row"> <SelectableIcon checked={selectedFormat === 'Cassette'} icon="cassette-tape" inputId={13} multi={false} name="music-format" onChange={() => toggleFormat('Cassette')} text="Cassette" value="Cassette" {...props} /> <SelectableIcon checked={selectedFormat === 'CD'} icon="compact-disc" inputId={14} multi={false} name="music-format" onChange={() => toggleFormat('CD')} text="CD" value="CD" {...props} /> <SelectableIcon checked={selectedFormat === 'Vinyl'} icon="album-collection" inputId={15} multi={false} name="music-format" onChange={() => toggleFormat('Vinyl')} text="Vinyl" value="Vinyl" {...props} /> </div> ) } export default SelectableIconSingleSelect
import React from 'react' import { SelectableList } from '../..' const SelectableListDefault = (props) => { return ( <div> <SelectableList variant="checkbox"> <SelectableList.Item label="Mild" name="checkbox-name-1" value="1" {...props} /> <SelectableList.Item checked label="Medium" name="checkbox-name-2" value="2" {...props} /> <SelectableList.Item label="Hot" name="checkbox-name-3" value="3" {...props} /> </SelectableList> </div> ) } export default SelectableListDefault
import React from 'react' import { SelectableList } from '../..' const SelectableListDefault = (props) => { return ( <div> <SelectableList variant="radio"> <SelectableList.Item label="Small" name="radio" value="1" {...props} /> <SelectableList.Item defaultChecked label="Medium" name="radio" value="2" {...props} /> <SelectableList.Item label="Large" name="radio" value="3" {...props} /> </SelectableList> </div> ) } export default SelectableListDefault
import React, { useState } from 'react' import { Caption, TextInput, Title, } from '../../' const TextInputDefault = (props) => { const handleOnChangeFirstName = ({ target }) => { setFirstName(target.value) } const ref = React.createRef() const [firstName, setFirstName] = useState('') const [formFields, setFormFields] = useState({ firstName: 'Jane', lastName: 'Doe', phone: '8888888888', email: 'jane@doe.com', zip: 55555, }) const handleOnChangeFormField = ({ target }) => { const { name, value } = target setFormFields({ ...formFields, [name]: value }) } return ( <div> <TextInput aria={{ label: 'hello' }} data={{ say: 'hi', yell: 'go' }} id="unique-id" label="First Name" name="firstName" onChange={handleOnChangeFormField} placeholder="Enter first name" value={formFields.firstName} {...props} /> <TextInput label="Last Name" name="lastName" onChange={handleOnChangeFormField} placeholder="Enter last name" value={formFields.lastName} {...props} /> <TextInput label="Phone Number" name="phone" onChange={handleOnChangeFormField} placeholder="Enter phone number" type="phone" value={formFields.phone} {...props} /> <TextInput label="Email Address" name="email" onChange={handleOnChangeFormField} placeholder="Enter email address" type="email" value={formFields.email} {...props} /> <TextInput label="Zip Code" name="zip" onChange={handleOnChangeFormField} placeholder="Enter zip code" type="number" value={formFields.zip} {...props} /> <br /> <br /> <Title>{'Event Handler Props'}</Title> <br /> <Caption>{'onChange'}</Caption> <br /> <TextInput label="First Name" onChange={handleOnChangeFirstName} placeholder="Enter first name" ref={ref} value={firstName} {...props} /> <If condition={firstName !== ''}> {`First name is: ${firstName}`} </If> </div> ) } export default TextInputDefault
Text Input w/ Error shows that the radio option must be selected or is invalid (ie when used in a form it signals a user to fix an error).
import React, { useState } from 'react' import { TextInput, } from '../..' const TextInputError = (props) => { const [email, setEmail] = useState('') const handleUpdateEmail = ({ target }) => { setEmail(target.value) } return ( <div> <TextInput error="Please enter a valid email address" label="Email Address" onChange={handleUpdateEmail} placeholder="Enter email address" type="email" value={email} {...props} /> </div> ) } export default TextInputError
import React, { useState } from 'react' import { TextInput } from '../../' const TextInputCustom = (props) => { const [name, setName] = useState('') const handleUpdateName = ({ target }) => { setName(target.value) } return ( <div> <TextInput label="Custom Label" {...props} > <input name="custom-name" onChange={handleUpdateName} placeholder="custom-placeholder" type="text" value={name} {...props} /> </TextInput> </div> ) } export default TextInputCustom
import React from 'react' import { TextInput } from '../../' class TextInputDisabled extends React.Component { render(props) { return ( <div> <TextInput disabled label="Last Name" placeholder="Enter last name" {...props} /> </div> ) } } export default TextInputDisabled
import React from 'react' import { Textarea } from '../../' const TextareaDefault = (props) => { return ( <div> <Textarea label="Label" rows={4} {...props} /> <br /> <Textarea label="Label" placeholder="Placeholder text" {...props} /> <br /> <Textarea label="Label" name="comment" placeholder="Placeholder text" value="Default value text" {...props} /> </div> ) } export default TextareaDefault
import React from 'react' import { Textarea } from '../../' const TextareaCustom = (props) => { return ( <div> <Textarea label="Label"> <textarea className="my_custom_class" name="custom_textarea" rows={4} {...props} > {'Content goes here.'} </textarea> </Textarea> </div> ) } export default TextareaCustom
import React from 'react' import { Textarea } from '../../' const TextareaResize = (props) => { return ( <div> <Textarea label="auto" placeholder="Resize Auto" resize="auto" {...props} /> <br /> <Textarea label="vertical" placeholder="Resize Vertical" resize="vertical" {...props} /> <br /> <Textarea label="both" placeholder="Resize Both" resize="both" {...props} /> <br /> <Textarea label="horizontal" placeholder="Resize Horizontal" resize="horizontal" {...props} /> </div> ) } export default TextareaResize
Textarea w/ Error shows that the radio option must be selected or is invalid (ie when used in a form it signals a user to fix an error).
import React from 'react' import { Textarea } from '../..' const TextareaError = (props) => { return ( <div> <Textarea error="This field has an error!" label="Label" name="comment" placeholder="Placeholder text" value="Default value text" {...props} /> </div> ) } export default TextareaError
import React, { useState } from 'react' import { Textarea } from '../../' const TextareaCharacterCounter = () => { const [value1, setValue1] = useState('Counting characters!') const [value2, setValue2] = useState('This counter prevents the user from exceeding the maximum number of allowed characters. Just try it!') const [value3, setValue3] = useState('This counter alerts the user that they have exceeded the maximum number of allowed characters.') const [error, setError] = useState('Too many characters!') const [count1, setCount1] = useState(0) const [count2, setCount2] = useState(value1.length) const [count3, setCount3] = useState(value2.length) const [count4, setCount4] = useState(value3.length) const handleMaxCount = (event) => { setCount2(event.target.value.length) setValue1(event.target.value) } const handleMaxCountWithBlocker = (event, maxCharacters) => { if (event.target.value.length <= maxCharacters) { setCount3(event.target.value.length) setValue2(event.target.value) } } const handleMaxCountWithError = (event, maxCharacters) => { if (event.target.value.length > maxCharacters) { setError('Too many characters!') } else { setError('') } setCount4(event.target.value.length) setValue3(event.target.value) } return ( <> <Textarea characterCount={count1} label="Count Only" onChange={(event) => setCount1(event.target.value.length)} rows={4} /> <br /> <Textarea characterCount={count2} label="Max Characters" maxCharacters="100" onChange={() => handleMaxCount(event)} rows={4} value={value1} /> <br /> <Textarea characterCount={count3} label="Max Characters w/ Blocker" maxCharacters="100" onChange={() => handleMaxCountWithBlocker(event, 100)} rows={4} value={value2} /> <br /> <Textarea characterCount={count4} error={error} label="Max Characters w/ Error" maxCharacters="75" onChange={() => handleMaxCountWithError(event, 75)} rows={4} value={value3} /> </> ) } export default TextareaCharacterCounter
// @flow import React from 'react' import { Typeahead } from '../../' const options = [ { label: 'Orange', value: '#FFA500' }, { label: 'Red', value: '#FF0000' }, { label: 'Green', value: '#00FF00' }, { label: 'Blue', value: '#0000FF' }, ] const TypeaheadDefault = (props) => { return ( <Typeahead label="Colors" options={options} {...props} /> ) } export default TypeaheadDefault
Typeahead kit is data-driven. The minimum default fields are label
and value
.
This is an example of an option: { label: 'Windows', value: '#FFA500' }
You can also pass default_options
which will populate the initial pill selections:
default_options: [{ label: 'Windows', value: '#FFA500' }]
JavaScript events are triggered based on actions you take within the kit such as selection, removal and clearing.
This kit utilizes a default id
prop named react-select-input
. It is highly advised to send your own unique id
prop when using this kit to ensure these events do not unintentionally affect other instances of the kit in the same view. The examples below will use the unique id
prop named typeahead-pills-example1
:
pb-typeahead-kit-typeahead-pills-example1-result-option-select
event to perform custom work when an option is clicked.
pb-typeahead-kit-typeahead-pills-example1-result-option-remove
event to perform custom work when a pill is clicked.
pb-typeahead-kit-typeahead-pills-example1-result-option-clear
event to perform custom work when all pills are removed upon clicking the X.
The same rule regarding the id
prop applies to publishing JS events. The examples below will use the unique id
prop named typeahead-pills-example1
:
pb-typeahead-kit-typeahead-pills-example1:clear
event to clear all options.
/* @flow */ import React from 'react' import { Typeahead } from '../..' const options = [ { label: 'Windows', value: '#FFA500' }, { label: 'Siding', value: '#FF0000' }, { label: 'Doors', value: '#00FF00' }, { label: 'Roofs', value: '#0000FF' }, ] const TypeaheadWithPills = (props) => { return ( <> <Typeahead isMulti label="Colors" options={options} placeholder="" {...props} /> </> ) } export default TypeaheadWithPills
load_options
Promise*Additional required props: * async: true
, pills: true
The prop load_options
, when used in conjunction with async: true
and pills: true
, points to a JavaScript function located within the global window namespace. This function should return a Promise
which resolves with the list of formatted options as described in prior examples above. This function is identical to the function provided to the React version of this kit. See the code example for more details.
loadOptions
*Additional required props: * async: true
As outlined in the react-select Async docs, loadOptions
expects to return a Promise that resolves resolves with the list of formatted options as described in prior examples above. See the code example for more details.
getOptionLabel
+ getOptionValue
If your server returns data that requires differing field names other than label
and value
See react-select
docs for more information: https://react-select.com/advanced#replacing-builtins
/* @flow */ import React, { useState } from 'react' import { Caption, Typeahead, User, } from '../..' /** * * @const filterResults * @ignore * @returns {[Object]} - a custom mapping of objects, minimally containing * `value` and `label` among other possible fields * @summary - for doc example purposes only */ const filterResults = (results) => results.items.map((result) => { return { name: result.login, id: result.id, } }) /** * * @const promiseOptions * @ignore * @returns {Promise} - fetch API data results from Typeahead input text * @see - https://react-select.com/home#async * @summary - for doc example purposes only */ const promiseOptions = (inputValue) => new Promise((resolve) => { if (inputValue) { fetch(`https://api.github.com/search/users?q=${inputValue}`) .then((response) => response.json()) .then((results) => resolve(filterResults(results))) } else { resolve([]) } }) const TypeaheadWithPillsAsync = (props) => { const [users, setUsers] = useState([]) const handleOnChange = (value) => setUsers(formatUsers(value)) const formatValue = (users) => formatUsers(users) const formatUsers = (users) => { const results = () => (users.map((user) => { if (Object.keys(user)[0] === 'name' || Object.keys(user)[1] === 'id'){ return ({ label: user.name, value: user.id }) } else { return user } })) return results() } return ( <> <If condition={users && users.length > 0}> <Caption marginBottom="xs" text="State (Users)" {...props} /> <For each="user" of={users} > <User align="left" key={user.value} marginBottom="md" name={user.label} orientation="horizontal" {...props} /> </For> </If> <Typeahead async getOptionLabel={(option) => option.name} getOptionValue={(option) => option.id} isMulti label="Github Users" loadOptions={promiseOptions} onChange={handleOnChange} placeholder="type the name of a Github user" value={formatValue(users)} {...props} /> </> ) } export default TypeaheadWithPillsAsync
If the data field imageUrl
is present, FormPill will receive that field as a prop and display the image.
/* @flow */ import React, { useState } from 'react' import { Caption, Typeahead, User, } from '../..' /** * * @const filterResults * @ignore * @returns {[Object]} - a custom mapping of objects, minimally containing * `value` and `label` among other possible fields * @summary - for doc example purposes only */ const filterResults = (results) => results.items.map((result) => { return { imageUrl: result.avatar_url, //add the custom field label: result.login, value: result.id, } }) /** * * @const promiseOptions * @ignore * @returns {Promise} - fetch API data results from Typeahead input text * @see - https://react-select.com/home#async * @summary - for doc example purposes only */ const promiseOptions = (inputValue) => new Promise((resolve) => { if (inputValue) { fetch(`https://api.github.com/search/users?q=${inputValue}`) .then((response) => response.json()) .then((results) => resolve(filterResults(results))) } else { resolve([]) } }) const TypeaheadWithPillsAsyncUsers = (props) => { const [users, setUsers] = useState([]) const handleOnChange = (value) => setUsers(value) /** * * @const handleOnMultiValueClick {function} - a custom callback for the MultiValue click * @ignore * @returns {null} * @summary - for doc example purposes only */ const handleOnMultiValueClick = (value) => { alert(`You removed the user: "${value.label}"`) } return ( <> <If condition={users && users.length > 0}> <Caption marginBottom="xs" text="State (Users)" {...props} /> <For each="user" of={users} > <User align="left" avatar avatarUrl={user.imageUrl} key={user.value} marginBottom="md" name={user.label} orientation="horizontal" {...props} /> </For> </If> <Typeahead async isMulti label="Github Users" loadOptions={promiseOptions} onChange={handleOnChange} onMultiValueClick={handleOnMultiValueClick} placeholder="type the name of a Github user" {...props} /> </> ) } export default TypeaheadWithPillsAsyncUsers
Use valueComponent
props to pass your desire custom options. valueComponent
will be displayed if present.
/* @flow */ import React, { useState } from 'react' import { Caption, Typeahead, User, } from '../..' /** * * @const filterResults * @ignore * @returns {[Object]} - a custom mapping of objects, minimally containing * `value` and `label` among other possible fields * @summary - for doc example purposes only */ type UserProps = { imageUrl?: String, label?: String, territory?: String, type?: String, } const filterResults = (results) => results.items.map((result) => { return { imageUrl: result.avatar_url, //add the custom field label: result.login, value: result.id, territory: 'PHL', type: result.type, } }) const promiseOptions = (inputValue) => new Promise((resolve) => { if (inputValue) { fetch(`https://api.github.com/search/users?q=${inputValue}`) .then((response) => response.json()) .then((results) => resolve(filterResults(results))) } else { resolve([]) } }) const TypeaheadWithPillsAsyncCustomOptions = (props) => { const [users, setUsers] = useState([]) const handleOnChange = (value) => setUsers(value) /** * * @const handleOnMultiValueClick {function} - a custom callback for the MultiValue click * @ignore * @returns {null} * @summary - for doc example purposes only */ const handleOnMultiValueClick = (value) => { alert(`You removed the user: "${value.label}"`) } return ( <> <If condition={users && users.length > 0}> <Caption marginBottom="xs" text="State (Users)" {...props} /> <For each="user" of={users} > <User align="left" avatar avatarUrl={user.imageUrl} key={user.value} marginBottom="md" name={user.label} orientation="horizontal" {...props} /> </For> </If> <Typeahead async isMulti label="Github Users" loadOptions={promiseOptions} onChange={handleOnChange} onMultiValueClick={handleOnMultiValueClick} placeholder="type the name of a Github user" valueComponent={(props: UserProps) => ( <User avatar avatarUrl={props.imageUrl} name={props.label} territory={props.territory} title={props.type} /> )} {...props} /> </> ) } export default TypeaheadWithPillsAsyncCustomOptions
// @flow import React from 'react' import { Toggle } from '../..' const ToggleDefault = () => { return ( <> <Toggle checked /> <br /> <Toggle /> </> ) } export default ToggleDefault
// @flow import React, { useState } from 'react' import { Caption, Title, Toggle } from '../..' const ToggleName = () => { const [choice, setChoice] = useState(false) const handleOnChange = ({ target }) => { setChoice(target.value = !choice) } return ( <> <Title size={4} text="Which of the following vehicles do you own?" /> <br /> <Caption text="Car" /> <Toggle checked={choice} size="sm" > <input name="vehicle" onChange={handleOnChange} type="checkbox" value="car" /> </Toggle> <br /> <Caption text="Bike" /> <Toggle checked={choice} size="sm" > <input name="vehicle" onChange={handleOnChange} type="checkbox" value="bike" /> </Toggle> </> ) } export default ToggleName
// @flow import React, { useState } from 'react' import { Toggle } from '../..' const ToggleCustom = () => { const [choice, setChoice] = useState(false) const handleOnChange = ({ target }) => { setChoice(target.value = !choice) } return ( <> <Toggle checked={choice} size="sm" > <input className="my custom checkbox" name="custom checkbox" onChange={handleOnChange} type="checkbox" value="ABC" /> </Toggle> </> ) } export default ToggleCustom
// @flow import React, { useState } from 'react' import { Caption, Title, Toggle } from '../..' const ToggleCustomRadio = () => { const [choice, setChoice] = useState('walk') const handleOnChange = ({ target }) => { setChoice(target.value) } return ( <> <Title size={4} text="Select one option:" /> <br /> <Caption text="Walk" /> <Toggle checked={choice} size="sm" > <input name="modes of transportation" onChange={handleOnChange} type="radio" value="walk" /> </Toggle> <br /> <Caption text="Bike" /> <Toggle size="sm" > <input name="modes of transportation" onChange={handleOnChange} type="radio" value="bike" /> </Toggle> <br /> <Caption text="Ride" /> <Toggle size="sm" > <input name="modes of transportation" onChange={handleOnChange} type="radio" value="ride" /> </Toggle> </> ) } export default ToggleCustomRadio