import React from 'react' import Checkbox from '../_checkbox' const CheckboxDefault = (props) => { return ( <div> <Checkbox name="default name" tabIndex={0} text="Checkbox label" value="default value" {...props} /> </div> ) } export default CheckboxDefault
import React from 'react' import Checkbox from '../_checkbox' const CheckboxChecked = (props) => { return ( <div> <Checkbox checked name="checkbox-name" text="Checked Checkbox" value="check-box value" {...props} /> </div> ) } export default CheckboxChecked
import React, { useState } from 'react' import Checkbox from '../_checkbox' const CheckboxCustom = (props) => { const [checked, setChecked] = useState(false) const handleOnChange = () => { setChecked(!checked) } return ( <div> {`The checkbox is ${checked ? 'checked' : 'unchecked'}.`} <br /> <br /> <div> <Checkbox text="Toggle Me" {...props} > <input checked={checked} name="custom-name" onChange={handleOnChange} type="checkbox" value="custom-value" /> </Checkbox> </div> </div> ) } export default CheckboxCustom
import React from 'react' import { Checkbox } from '../..' const CheckboxError = (props) => { return ( <div> <Checkbox error name="default name" text="Checkbox label" value="default value" {...props} /> </div> ) } export default CheckboxError
import React, { useState } from 'react' import { Checkbox, Table } from '../..' const CheckboxIndeterminate = (props) => { const [checkboxes, setCheckboxes] = useState([ { name: 'Coffee', checked: false }, { name: 'Ice Cream', checked: false }, { name: 'Chocolate', checked: true }, ]) const isAllChecked = !checkboxes.find((checkbox) => !checkbox.checked) const isNoneChecked = !checkboxes.find((checkbox) => checkbox.checked) const processCheckboxes = (checked) => checkboxes.slice(0).map((checkbox) => { checkbox.checked = checked return checkbox }) const onToggleAll = () => { setCheckboxes( isNoneChecked ? processCheckboxes(true) : processCheckboxes(false) ) } const updateCheckboxes = (checkbox, index) => { const newCheckboxes = checkboxes.slice(0) newCheckboxes[index].checked = !checkbox.checked setCheckboxes(newCheckboxes) } return ( <Table container={false} size="md" > <thead> <tr> <th> <Checkbox checked={isAllChecked} indeterminate={!isAllChecked && !isNoneChecked} name="checkbox-name" onChange={onToggleAll} text={isNoneChecked ? 'Check All' : 'Uncheck All'} value="check-box value" {...props} /> </th> </tr> </thead> <tbody> {checkboxes.map((checkbox, index) => ( <tr key={index}> <td> <Checkbox checked={checkbox.checked} name={checkbox.name} onChange={() => { updateCheckboxes(checkbox, index) }} text={checkbox.name} value="check-box value" {...props} /> </td> </tr> ))} </tbody> </Table> ) } export default CheckboxIndeterminate
import React from 'react' import DatePicker from '../_date_picker' const DatePickerDefault = (props) => ( <div> <DatePicker pickerId="date-picker-default" {...props} /> </div> ) export default DatePickerDefault
import React from 'react' import DatePicker from '../_date_picker' 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 '../_date_picker' 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 '../_date_picker' 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 '../_date_picker' 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 '../_date_picker' 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 '../_date_picker' 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 '../_date_picker' 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 '../_date_picker' 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 '../_date_picker' 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 DatePicker from '../_date_picker' import Button from '../../pb_button/_button' 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 '../_date_picker' 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 '../_date_picker' 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
import React from 'react' import DatePicker from '../_date_picker' const DatePickerInline = (props) => { const showAngleDownHandler = (dateSelected) => { if (dateSelected) { document.querySelector('.inline-date-picker').classList.add('show-angle-down-icon') } } return ( <div> <DatePicker className="inline-date-picker" hideIcon inLine onChange={showAngleDownHandler} pickerId="date-picker-inline" {...props} /> </div> ) } export default DatePickerInline
By default selectType prop is disabled. To activate it set selectionType
prop in JSX/TSX to month
. To activate it set selection_type
prop in a rails file to month
.
import React from 'react' import DatePicker from '../_date_picker' const DatePickerMonthAndYear = (props) => { return ( <div> <DatePicker label="Date Picker" pickerId="disabled-date" selectionType="month" {...props} /> </div> ) } export default DatePickerMonthAndYear
By default selectType prop is disabled. To activate it set selectionType
prop in JSX/TSX to week
. To activate it set selection_type
prop in a rails file to week
.
import React from 'react' import DatePicker from '../_date_picker' const DatePickerWeek = (props) => { return ( <div> <DatePicker label="Date Picker" pickerId="week-date-picker" selectionType="week" {...props} /> </div> ) } export default DatePickerWeek
To select time as well, you should pass the enableTime
boolean prop. You can also enable timezone display by passing showTimezone
.
import React from 'react' import DatePicker from '../_date_picker' const DEFAULT_DATE = new Date() DEFAULT_DATE.setHours(12) DEFAULT_DATE.setMinutes(0) const DatePickerTime = (props) => ( <div> <DatePicker defaultDate={DEFAULT_DATE} enableTime pickerId="date-picker-time" showTimezone {...props} /> </div> ) export default DatePickerTime
/* @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
Sometimes you may want to create a custom description that is easier for users to read. In this case, you can use the acceptedFilesDescription
prop.
/* eslint-disable react/no-multi-comp */ /* @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 FileUploadCustomDescription = (props) => { const [filesToUpload, setFilesToUpload] = useState([]); const handleOnFilesAccepted = (files) => { setFilesToUpload([...filesToUpload, ...files]); }; return ( <div> <AcceptedFilesList files={filesToUpload} {...props} /> <FileUpload accept={['application/pdf','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']} acceptedFilesDescription="Adobe (.pdf) and Microsoft (.xslx)" onFilesAccepted={handleOnFilesAccepted} {...props} /> </div> ); }; export default FileUploadCustomDescription;
import React from 'react' import FormGroup from '../_form_group' import TextInput from '../../pb_text_input/_text_input' 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 from '../../pb_button/_button' import FormGroup from '../../pb_form_group/_form_group' import TextInput from '../../pb_text_input/_text_input' 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
Full Width is a prop that can be added to any of the Form Group options. This prop allows the Form Group to stretch the full width of the div.
import React from 'react' import FormGroup from '../_form_group' import TextInput from '../../pb_text_input/_text_input' import Button from '../../pb_button/_button' const FormGroupFullWidth = (props) => ( <div> <div> <FormGroup fullWidth> <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> <br /> <div> <FormGroup fullWidth> <TextInput placeholder="Search" {...props} /> <Button onClick={() => alert('Button Clicked!')} text="Submit" variant="secondary" {...props} /> </FormGroup> </div> </div> ) export default FormGroupFullWidth
import React from 'react' import FormGroup from '../_form_group' import DatePicker from '../../pb_date_picker/_date_picker' import TextInput from '../../pb_text_input/_text_input' 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 from '../_form_group' import Select from '../../pb_select/_select' import TextInput from '../../pb_text_input/_text_input' 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 from '../../pb_form_group/_form_group' import SelectableCard from '../../pb_selectable_card/_selectable_card' 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 from '../_form_group' import SelectableCardIcon from '../../pb_selectable_card_icon/_selectable_card_icon' 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' 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' const FormPillSize = (props) => { return ( <div> <FormPill avatarUrl="https://randomuser.me/api/portraits/women/44.jpg" name="Anna Black" size="small" {...props} /> <br /> <br /> <FormPill name="Anna Black" size="small" {...props} /> </div> ) } export default FormPillSize
import React from 'react' import FormPill from '../_form_pill' const FormPillDefault = (props) => { return ( <div> <FormPill onClick={() => { alert('Click!') }} text="this is a tag" {...props} /> </div> ) } export default FormPillDefault
By default textTransform = "none"
. If there is a need to enforce lowercase
, please pass the textTransform = "lowercase
prop.
import React from 'react' import FormPill from '../_form_pill' const FormPillExample = (props) => { return ( <div> <FormPill onClick={() => alert('Click!')} text="THIS IS A TAG" textTransform="lowercase" {...props} /> </div> ) } export default FormPillExample
Use the confirmation
prop to only include the label and show/hide icon.
import React, { useState } from 'react' import Passphrase from '../_passphrase' const PassphraseDefault = (props) => { const [input, setInput] = useState('') const handleChange = (e) => setInput(e.target.value) const [confoInput, setConfoInput] = useState('') const handleConfoChange = (e) => setConfoInput(e.target.value) return ( <> <div> <Passphrase id="my-passphrase" onChange={handleChange} value={input} {...props} /> <Passphrase confirmation onChange={handleConfoChange} value={confoInput} {...props} /> <span>{input === confoInput ? 'They match!' : 'They don\'t match!'}</span> </div> </> ) } export default PassphraseDefault
By default, the minimum length is 12 and the strength meter will show a strength of 1 if not met. Notice the bar won't change from red until the minimum is met
Use the minLength
prop to adjust.
The meter also response to averageThreshold
and strongTreshold
props. averageThresold
defaults to 2, and strongThreshold
defaults to 3.
This means that the bar will turn yellow when the strength of the passphrase is calculated to be 2 on a 0-4 scale, and green when 3.
Adjust these props to tune the sensitivity of the bar.
Note: minimum length trumps strength and will set the bar to a red color, despite whatever strength is calculated.
import React, { useState } from 'react' import Body from '../../pb_body/_body' import Passphrase from '../../pb_passphrase/_passphrase' import TextInput from '../../pb_text_input/_text_input' const PassphraseMeterSettings = (props) => { const [input, setInput] = useState('') const handleChange = (e) => setInput(e.target.value) const [strength, setStrength] = useState(0) const handleStrengthChange = (str) => setStrength(str) return ( <> <div> <Body> {'These examples will all share the same input value. Type in any of the inputs to see how the strength meter changes in response to different settings.'} </Body> <br /> <TextInput disabled label="Calculated Strength" readOnly value={strength} /> <Passphrase label="Default settings" onChange={handleChange} onStrengthChange={handleStrengthChange} value={input} {...props} /> <Passphrase label="Min length = 5" minLength={5} onChange={handleChange} value={input} {...props} /> <Passphrase label="Min length = 30" minLength={30} onChange={handleChange} value={input} {...props} /> <Passphrase averageThreshold={1} label="Average threshold = 1" onChange={handleChange} value={input} {...props} /> <Passphrase label="Strong Threshold = 4" onChange={handleChange} strongThreshold={4} value={input} {...props} /> </div> </> ) } export default PassphraseMeterSettings
inputProps
is passed directly to an underlying Text Input kit. See the specific docs here for more details.
import React, { useState } from 'react' import Passphrase from '../../pb_passphrase/_passphrase' const PassphraseInputProps = (props) => { const [input, setInput] = useState('') const handleChange = (e) => setInput(e.target.value) return ( <> <div> <Passphrase inputProps={{ name: 'my-disabled-field', id: 'my-value-id', disabled: true, }} label="Pass props directly to input kit" onChange={handleChange} value={input} {...props} /> <Passphrase inputProps={{ children: ( <input onChange={handleChange} type="password" value={input} />), }} label="Custom input" onChange={handleChange} value={input} {...props} /> <Passphrase inputProps={{ name: 'my-value-name', id: 'my-value-id' }} label="Set name and ID for use in form libraries" onChange={handleChange} value={input} {...props} /> <Passphrase confirmation inputProps={{ name: 'my-value-confirmation-name', id: 'my-value-confirmation-id' }} onChange={handleChange} value={input} {...props} /> </div> </> ) } export default PassphraseInputProps
showTipsBelow
(react) / show_tips_below
(rails) takes 'xs', 'sm', 'md', 'lg', 'xl' and only show the tips below the given screen size. Similar to the responsive table breakpoints. Omit this prop to always show.
import React, { useState } from 'react' import Passphrase from '../_passphrase' const PassphraseTips = (props) => { const [input, setInput] = useState('') const handleChange = (e) => setInput(e.target.value) return ( <> <div> <Passphrase label="Pass an array of strings to the tips prop" onChange={handleChange} tips={['And the info icon will appear.', 'Each string will be displayed as its own tip']} value={input} {...props} /> <Passphrase label="Omit the prop to hide the icon" onChange={handleChange} value={input} {...props} /> <Passphrase label="Only show tips at small screen size" onChange={handleChange} showTipsBelow="xs" tips={['Make the password longer', 'Type more things', 'Use something else']} value={input} {...props} /> <Passphrase label="Only show tips at medium screen size" onChange={handleChange} showTipsBelow="md" tips={['Make the password longer', 'Type more things', 'Use something else']} value={input} {...props} /> <Passphrase label="Only show tips at large screen size" onChange={handleChange} showTipsBelow="lg" tips={['Make the password longer', 'Type more things', 'Use something else']} value={input} {...props} /> </div> </> ) } export default PassphraseTips
As the strength of the entered passphrase changes, the optional onStrengthChange
callback is called with the new strength value. This exposes the calculated strength.
Strength is calculated on a 0-4 scale by the Zxcvbn package
import React, { useState } from 'react' import Passphrase from '../_passphrase' import TextInput from '../../pb_text_input/_text_input' const PassphraseStrengthChange = (props) => { const [input, setInput] = useState('') const handleChange = (e) => setInput(e.target.value) const [strength, setStrength] = useState(0) const handleStrengthChange = (str) => setStrength(str) return ( <> <div> <Passphrase label="Passphrase" onChange={handleChange} onStrengthChange={handleStrengthChange} value={input} {...props} /> <TextInput disabled label="Passphrase Strength" readOnly value={strength} /> </div> </> ) } export default PassphraseStrengthChange
import React, { useState } from 'react' import Passphrase from '../_passphrase' import Body from '../../pb_body/_body' const PassphraseCommon = (props) => { const [input, setInput] = useState('') const handleChange = (e) => setInput(e.target.value) const COMMON_PASSPHRASES = ['passphrase', 'apple', 'password', 'p@55w0rd'] const commonCheck = (passphrase) => { if (COMMON_PASSPHRASES.includes(passphrase)) return true return false } return ( <> <div> <Body text={`Try typing any of the following: ${COMMON_PASSPHRASES.join(' ')}`} /> <br /> <Passphrase common={commonCheck(input)} onChange={handleChange} value={input} {...props} /> </div> </> ) } export default PassphraseCommon
Use checkPwned | checked_pwned
prop to enable checking against HaveIBeenPwned's API. As the passphrase is typed, it is checked against more than half a billion breached passwords, to help ensure its not compromised.
Should it fail, the feedback will express the passphrase is too common, prompting the user to change.
This uses their k-Anonymity model, so only the first 5 characters of a hashed copy of the passphrase are sent.
import React, { useState } from 'react' import Passphrase from '../_passphrase' const PassphraseBreached = (props) => { const [input, setInput] = useState('') const handleChange = (e) => setInput(e.target.value) return ( <> <div> <br /> <Passphrase checkPwned onChange={handleChange} value={input} {...props} /> </div> </> ) } export default PassphraseBreached
import React from 'react' import Radio from '../_radio' 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 '../_radio' 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 { Flex, Radio } from '../../' const RadioAlignment = () => { return ( <Flex> <Radio alignment="vertical" label="Power" marginRight="sm" name="Group2" tabIndex={0} value="Power" /> <br /> <Radio alignment="vertical" defaultChecked={false} label="Nitro" marginRight="sm" name="Group2" value="Nitro" /> <br /> <Radio alignment="vertical" defaultChecked={false} label="Google" name="Group2" value="Google" /> </Flex> ) } export default RadioAlignment
import React, { useState } from 'react' import { RichTextEditor } from '../../' const RichTextEditorDefault = (props) => { const [value, setValue] = useState('Add your text here. You can format your text, add links, quotes, and bullets.'), handleOnChange = (html) => setValue(html) return ( <div> <RichTextEditor onChange={handleOnChange} value={value} {...props} /> </div> ) } export default RichTextEditorDefault
import React from 'react' import { RichTextEditor } from '../../' const RichTextEditorSimple = (props) => ( <div> <RichTextEditor simple {...props} /> </div> ) export default RichTextEditorSimple
import React from 'react' import { RichTextEditor } from '../../' const RichTextEditorAttributes = (props) => ( <div> <RichTextEditor aria={{ label: 'rich textarea' }} data={{ key: 'value', key2: 'value2' }} name="name-attribute" {...props} /> </div> ) export default RichTextEditorAttributes
import React from 'react' import { RichTextEditor } from '../../' const RichTextEditorFocus = (props) => ( <> <RichTextEditor focus {...props} /> <br /> <RichTextEditor focus {...props} /> </> ) export default RichTextEditorFocus
import React from 'react' import { RichTextEditor } from '../../' const RichTextEditorSticky = (props) => ( <div> <RichTextEditor id="sticky" sticky value="In this example, when you scroll down, the rich text editor's toolbar will scroll along with the page and it will no longer be visible at the top of the page. Dummy text to enable scroll.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis." {...props} /> </div> ) export default RichTextEditorSticky
import React, { useState } from 'react' import { RichTextEditor, Select } from '../../' import { changelog, release } from './templates.js' const RichTextEditorTemplates = (props) => { const [editorContent, setEditorContent] = useState('') const handleChange = (event) => { setEditorContent(event.target.value) } const options = [ { value: release, text: 'Playbook Release', }, { value: changelog, text: 'Changelog', }, ] return ( <div> <Select blankSelection="Select a template..." label="Template" onChange={handleChange} options={options} {...props} /> <RichTextEditor id="template" template={editorContent} {...props} /> </div> ) } export default RichTextEditorTemplates
import React from 'react' import { RichTextEditor } from '../../' const RichTextEditorToolbarBottom = (props) => ( <div> <RichTextEditor id="bottom-toolbar" toolbarBottom {...props} /> </div> ) export default RichTextEditorToolbarBottom
import React from 'react' import { RichTextEditor } from '../../' const RichTextEditorInline = (props) => ( <div> <RichTextEditor id="inline" inline toolbarBottom value="Try hovering over this text. Then try modifying it or adding more of your own text." {...props} /> </div> ) export default RichTextEditorInline
import React, { useState } from 'react' import { Button, Card, RichTextEditor, } from '../../' const RichTextEditorPreview = (props) => { const [showPreview, setShowPreview] = useState(false) const [previewText, setPreviewText] = useState(<div />) const handleChange = (event) => setPreviewText(event) const handleClick = () => { setShowPreview(true) } return ( <div> <RichTextEditor id="content-preview-editor" onChange={handleChange} {...props} /> <If condition={showPreview}> <Card marginTop="md"> <div className="trix-content" // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{ __html: previewText }} id="preview-content" /> </Card> <Else /> <div /> </If> <Button id="preview-button" marginTop="md" onClick={handleClick} text="Preview Output" variant="secondary" /> </div> ) } export default RichTextEditorPreview
import React from 'react' import Select from '../_select' 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 '../_select' 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 '../_select' 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 '../_select' 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 '../_select' 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 '../_select' 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 '../_select' const SelectCustomSelect = (props) => { return ( <div> <Select label="Favorite Holiday" {...props} > <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
import React from 'react' import { Body, Select } from '../..' const SelectInline = (props) => { const options = [ { value: '1', text: 'Burgers', }, { value: '2', text: 'Pizza', }, { value: '3', text: 'Tacos', }, ] return ( <div> <Select inline label="Favorite Food" name="food" options={options} {...props} /> <Body status="negative" {...props} /> </div> ) } export default SelectInline
import React from 'react' import { Body, Select } from '../..' const SelectInlineCompact = (props) => { const options = [ { value: '1', text: 'Burgers', }, { value: '2', text: 'Pizza', }, { value: '3', text: 'Tacos', }, ] return ( <div> <Select compact inline label="Favorite Food" name="food" options={options} {...props} /> <Body status="negative" {...props} /> </div> ) } export default SelectInlineCompact
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 SelectableCard from '../_selectable_card' import Body from '../../pb_body/_body' import Title from '../../pb_title/_title' 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 from '../../pb_body/_body' import Image from '../../pb_image/_image' import SelectableCard from '../../pb_selectable_card/_selectable_card' 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, { useState } from 'react' import Body from '../../pb_body/_body' import SelectableCard from '../../pb_selectable_card/_selectable_card' import Title from '../../pb_title/_title' const SelectableCardInput = (props) => { const [state, setState] = useState({ firstCheckbox: true, secondCheckbox: true, thirdCheckbox: false, forthCheckbox: false, radioSelected: 'first', }) const handleSelect = (event) => { setState({ ...state, [event.target.name]: event.target.checked, }) } const handleRadioSelect = (event) => { setState({ ...state, radioSelected: event.target.value, }) } return ( <> <Title size={3} text="What programming languages do you know?" {...props} /> <br /> <SelectableCard checked={state.firstCheckbox} inputId="firstCheckbox" name="firstCheckbox" onChange={handleSelect} value="firstCheckbox" variant="displayInput" {...props} > <Body {...props}>{'Ruby'}</Body> </SelectableCard> <SelectableCard checked={state.secondCheckbox} inputId="secondCheckbox" name="secondCheckbox" onChange={handleSelect} value="secondCheckbox" variant="displayInput" {...props} > <Body {...props}>{'JavaScript'}</Body> </SelectableCard> <SelectableCard checked={state.thirdCheckbox} inputId="thirdCheckbox" name="thirdCheckbox" onChange={handleSelect} value="thirdCheckbox" variant="displayInput" {...props} > <Body {...props}>{'TypeScript'}</Body> </SelectableCard> <SelectableCard checked={state.fourthCheckbox} inputId="fourthCheckbox" name="fourthCheckbox" onChange={handleSelect} value="fourthCheckbox" variant="displayInput" {...props} > <Body {...props}>{'Swift'}</Body> </SelectableCard> <br /> <Title size={3} text="How likely are you to recommend Playbook to a friend?" {...props} /> <br /> <SelectableCard checked={state.radioSelected === 'first'} inputId="radio-1" multi={false} name="radio" onChange={handleRadioSelect} value="first" variant="displayInput" {...props} > <Body {...props}>{'5'}</Body> </SelectableCard> <SelectableCard checked={state.radioSelected === 'second'} inputId="radio-2" multi={false} name="radio" onChange={handleRadioSelect} value="second" variant="displayInput" {...props} > <Body {...props}> {'4'} </Body> </SelectableCard> <SelectableCard checked={state.radioSelected === 'third'} inputId="radio-3" multi={false} name="radio" onChange={handleRadioSelect} value="third" variant="displayInput" {...props} > <Body {...props}>{'3'}</Body> </SelectableCard> <SelectableCard checked={state.radioSelected === 'fourth'} inputId="radio-4" multi={false} name="radio" onChange={handleRadioSelect} value="fourth" variant="displayInput" {...props} > <Body {...props}>{'2'}</Body> </SelectableCard> <SelectableCard checked={state.radioSelected === 'fifth'} inputId="radio-5" multi={false} name="radio" onChange={handleRadioSelect} value="fifth" variant="displayInput" {...props} > <Body {...props}>{'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 '../_selectable_card_icon' 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 '../_selectable_card_icon' 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 '../_selectable_card_icon' 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 '../_selectable_icon' 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 '../_selectable_icon' 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 from '../../pb_caption/_caption' import TextInput from '../../pb_text_input/_text_input' import Title from '../../pb_title/_title' 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 '../_text_input' const TextInputError = (props) => { const [email, setEmail] = useState('') const handleUpdateEmail = ({ target }) => { setEmail(target.value) } return ( <div> <TextInput addOn={{ icon: 'user', alignment: 'left', border: true }} error="Please enter a valid email address" label="Email Address" onChange={handleUpdateEmail} placeholder="Enter email address" type="email" value={email} {...props} /> <TextInput addOn={{ icon: 'user', alignment: 'left', border: true }} label="Confirm Email Address" onChange={handleUpdateEmail} placeholder="Confirm email address" type="email" value={email} {...props} /> </div> ) } export default TextInputError
import React, { useState } from 'react' import TextInput from '../_text_input' 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 '../_text_input' 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, { useState } from 'react' import TextInput from '../_text_input' const TextInputAddOn = (props) => { const [defaultInput, setDefaultInput] = useState('') const [firstInput, setFirstInput] = useState('') const [secondInput, setSecondInput] = useState('') const [thirdInput, setThirdInput] = useState('') const [fourthInput, setFourthInput] = useState('') const handleUpdateDefaultInput = ({ target }) => { setDefaultInput(target.value) } const handleUpdateFirstInput = ({ target }) => { setFirstInput(target.value) } const handleUpdateSecondInput = ({ target }) => { setSecondInput(target.value) } const handleUpdateThirdInput = ({ target }) => { setThirdInput(target.value) } const handleUpdateFourthInput = ({ target }) => { setFourthInput(target.value) } return ( <> <div> <TextInput addOn={{ icon: 'bat' }} label="Add On With Defaults" onChange={handleUpdateDefaultInput} value={defaultInput} {...props} /> </div> <div> <TextInput addOn={{ icon: 'user', alignment: 'right', border: true }} label="Right-Aligned Add On With Border" onChange={handleUpdateFirstInput} value={firstInput} {...props} /> </div> <div> <TextInput addOn={{ icon: 'percent', alignment: 'left', border: false }} label="Left-Aligned Add On With No Border" onChange={handleUpdateSecondInput} value={secondInput} {...props} /> </div> <div> <TextInput addOn={{ icon: 'percent', alignment: 'right', border: false }} label="Right-Aligned Add On With No Border" onChange={handleUpdateThirdInput} value={thirdInput} {...props} /> </div> <div> <TextInput addOn={{ icon: 'percent', alignment: 'left', border: true }} label="Left-Aligned Add On With Border" onChange={handleUpdateFourthInput} value={fourthInput} {...props} /> </div> </> ) } export default TextInputAddOn
import React, { useState } from 'react' import TextInput from '../_text_input' const TextInputInline = (props) => { const [value, setValue] = useState('Inline Input') const handleValueChange = ({ target }) => { setValue(target.value) } return ( <div> <TextInput inline label="Hover Over Text Below" onChange={handleValueChange} value={value} {...props} /> </div> ) } export default TextInputInline
import React from 'react' import Textarea from '../_textarea' 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 '../_textarea' const TextareaCustom = (props) => { return ( <div> <Textarea label="Label" {...props} > <textarea className="my_custom_class" name="custom_textarea" rows={4} > {'Content goes here.'} </textarea> </Textarea> </div> ) } export default TextareaCustom
import React from 'react' import Textarea from '../_textarea' 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 '../_textarea' const TextareaCharacterCounter = (props) => { 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} {...props} /> <br /> <Textarea characterCount={count2} label="Max Characters" maxCharacters="100" onChange={() => handleMaxCount(event)} rows={4} value={value1} {...props} /> <br /> <Textarea characterCount={count3} label="Max Characters w/ Blocker" maxCharacters="100" onChange={() => handleMaxCountWithBlocker(event, 100)} rows={4} value={value2} {...props} /> <br /> <Textarea characterCount={count4} error={error} label="Max Characters w/ Error" maxCharacters="75" onChange={() => handleMaxCountWithError(event, 75)} rows={4} value={value3} {...props} /> </> ) } export default TextareaCharacterCounter
import React, { useState } from 'react' import Textarea from '../_textarea' const TextareaInline = (props) => { const [value, setValue] = useState('Try clicking into this text.') const handleChange = (event) => { setValue(event.target.value) } return ( <div> <Textarea inline onChange={(e) => handleChange(e)} resize="auto" rows={1} value={value} {...props} /> </div> ) } export default TextareaInline
// @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
// @flow import React from 'react' import Typeahead from '../_typeahead' 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} noOptionsMessage={() => 'Type to Search'} 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 Typeahead from '../_typeahead' const synths = [ { label: 'Oberheim', value: 'OBXa' }, { label: 'Moog', value: 'Minimoog' }, { label: 'Roland', value: 'Juno' }, { label: 'Korg', value: 'MS-20' }, ] const cities = [ { label: 'Budapest', value: 'Hungary' }, { label: 'Singapore', value: 'Singapore' }, { label: 'Oslo', value: 'Norway' }, { label: 'Lagos', value: 'Nigeria' }, ] const TypeaheadInline = (props) => { return ( <> <Typeahead inline isMulti label="Synths" options={synths} {...props} /> <Typeahead inline isMulti label="Placeholder Plus Icon" options={cities} placeholder="Add cities" plusIcon {...props} /> </> ) } export default TypeaheadInline
// @flow import React from 'react' import Typeahead from '../_typeahead' const labels = [ { label: 'Verve', value: '1956' }, { label: 'Stax', value: '1957' }, { label: 'Motown', value: '1959' }, { label: 'Kudu', value: '1971' }, { label: 'Stones Throw', value: '1996' }, ] const expressionists = [ { label: 'Kandinsky', value: 'Russia' }, { label: 'Klee', value: 'Switzerland' }, { label: 'Kokoschka', value: 'Austria' }, { label: 'Kirchner', value: 'Germany' }, ] const TypeaheadMultiKit = (props) => { return ( <> <Typeahead defaultValue={[labels[0]]} isMulti label="Badges" multiKit="badge" options={labels} {...props} /> <Typeahead defaultValue={[expressionists[0]]} isMulti label="Small Pills" multiKit="smallPill" options={expressionists} {...props} /> </> ) } export default TypeaheadMultiKit
// @flow import React from 'react' import { Typeahead } from '../..' const options = [ { label: 'Jardim', value: 'Portuguese' }, { label: 'Garten', value: 'German' }, { label: 'Giardino', value: 'Italian' }, { label: 'JardÃn', value: 'Spanish' }, ] const TypeaheadCreateable = (props) => { return ( <Typeahead createable isMulti label="User Created Options" options={options} {...props} /> ) } export default TypeaheadCreateable
// @flow import React from 'react' import { Typeahead } 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 { 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(results.items ? filterResults(results) : []) }) } else { resolve([]) } }) const TypeaheadAsyncCreateable = (props) => { return ( <Typeahead async createable isMulti label="Existing or User Created Options" loadOptions={promiseOptions} {...props} /> ) } export default TypeaheadAsyncCreateable