import React, { useState } from 'react' import { FileUpload, List, ListItem } from 'playbook-ui' const AcceptedFilesList = ({ files }) => ( <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} /> <FileUpload onFilesAccepted={handleOnFilesAccepted} /> </div> ) } export default FileUploadDefault
import React, { useState } from 'react' import { FileUpload, List, ListItem } from 'playbook-ui' const AcceptedFilesList = ({ files }) => ( <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} /> <FileUpload accept={{ "image/svg+xml": [".svg", ".xml"], }} onFilesAccepted={handleOnFilesAccepted} /> </div> ) } export default FileUploadAccept
import React, { useState } from 'react' import { FileUpload, List, ListItem } from 'playbook-ui' const AcceptedFilesList = ({ files }) => ( <List> {files.map((file) => ( <ListItem key={file.name}>{file.name}</ListItem> ))} </List> ) const FileUploadCustomMessage = (props) => { const [filesToUpload, setFilesToUpload] = useState([]) const handleOnFilesAccepted = (files) => { setFilesToUpload([...filesToUpload, ...files]) } return ( <div> <AcceptedFilesList files={filesToUpload} /> <FileUpload customMessage="Playbook is awesome!" onFilesAccepted={handleOnFilesAccepted} /> </div> ) } export default FileUploadCustomMessage
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 */ import React, { useState } from "react"; import { FileUpload, List, ListItem } from 'playbook-ui' const AcceptedFilesList = ({ files }) => ( <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} /> <FileUpload accept={{ "application/pdf": [".pdf"], "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [".xlsx"], }} acceptedFilesDescription="Adobe (.pdf) and Microsoft (.xslx)" onFilesAccepted={handleOnFilesAccepted} /> </div> ); }; export default FileUploadCustomDescription;
/* eslint-disable react/no-multi-comp */ import React, { useState } from 'react' import { Body, FileUpload, List, ListItem } from 'playbook-ui' const AcceptedFilesList = ({ files }) => ( <List> {files.map((file) => ( <ListItem key={file.name}>{file.name}</ListItem> ))} </List> ) const RejectedFilesList = ({ files }) => ( <List> {files.map((file) => ( <ListItem key={file.file.name}><Body color="error">{`${file.file.name} (file too large)`}</Body></ListItem> ))} </List> ) const FileUploadMaxSize = (props) => { const [filesToUpload, setFilesToUpload] = useState([]) const [filesRejected, setFilesRejected] = useState([]) const [error, setError] = useState() const handleOnFilesAccepted = (files) => { if (files.length) setError() setFilesToUpload([...filesToUpload, ...files]) } const handleOnFilesRejected = (error, files) => { setError(error) setFilesRejected([...filesRejected, ...files]) } return ( <div> <AcceptedFilesList files={filesToUpload} /> <RejectedFilesList files={filesRejected} /> <FileUpload acceptedFilesDescription="Choose a file or drag it here. 1 MB size limit." maxSize={1000000} onFilesAccepted={handleOnFilesAccepted} onFilesRejected={handleOnFilesRejected} /> { error && ( <Body color="error" marginY="md" > {error} </Body> )} </div> ) } export default FileUploadMaxSize
import React, { useState } from 'react' import { FileUpload, List, ListItem, Icon } from 'playbook-ui' const AcceptedFilesList = ({ files }) => ( <List> {files.map((file) => ( <ListItem key={file.name}>{file.name}</ListItem> ))} </List> ) const FileUploadError = (props) => { const [filesToUpload, setFilesToUpload] = useState([]) const handleOnFilesAccepted = (files) => { setFilesToUpload([...filesToUpload, ...files]) } const error = (<> <Icon icon="warning" /> Please upload a valid file </>) return ( <div> <AcceptedFilesList files={filesToUpload} /> <FileUpload error={error} onFilesAccepted={handleOnFilesAccepted} /> </div> ) } export default FileUploadError
import React, { useState } from 'react' import { Caption, Title, Toggle } from 'playbook-ui' 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
import React, { useState } from 'react' import { Toggle } from 'playbook-ui' 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
import React, { useState } from 'react' import { Caption, Title, Toggle } from 'playbook-ui' 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
import React from 'react' import { FormPill } from 'playbook-ui' const FormPillDefault = (props) => { return ( <div> <FormPill avatarUrl="https://randomuser.me/api/portraits/women/44.jpg" name="Anna Black" onClick={() => alert('Click!')} tabIndex={0} /> <br /> <br /> <FormPill name="Anna Black" onClick={() => alert('Click!')} tabIndex={0} /> </div> ) } export default FormPillDefault
import React from 'react' import { FormPill } from 'playbook-ui' const FormPillSize = (props) => { return ( <div> <FormPill avatarUrl="https://randomuser.me/api/portraits/women/44.jpg" name="Anna Black" size="small" tabIndex={0} /> <br /> <br /> <FormPill name="Anna Black" size="small" tabIndex={0} /> </div> ) } export default FormPillSize
For Form Pills with longer text, the truncate global prop can be used to truncate the label within each Form Pill. Hover over the truncated Form Pill and a Tooltip containing the text or tag section of the Form Pill will appear. See here for more information on the truncate global prop.
import React from 'react' import { Card, Caption, FormPill, Typeahead } from 'playbook-ui' const names = [ { label: 'Alexander Nathaniel Montgomery', value: 'Alexander Nathaniel Montgomery' }, { label: 'Isabella Anastasia Wellington', value: 'Isabella Anastasia Wellington' }, { label: 'Christopher Maximilian Harrington', value: 'Christopher Maximilian Harrington' }, { label: 'Elizabeth Seraphina Kensington', value: 'Elizabeth Seraphina Kensington' }, { label: 'Theodore Jonathan Abernathy', value: 'Theodore Jonathan Abernathy' }, ] const FormPillTruncatedText = (props) => { return ( <> <Typeahead htmlOptions={{ style: { maxWidth: "240px" }}} isMulti label="Truncation Within Typeahead" options={names} truncate={"1"} /> <Caption text="Form Pill Truncation"/> <Card maxWidth="xs"> <FormPill avatarUrl="https://randomuser.me/api/portraits/women/44.jpg" name="Princess Amelia Mignonette Grimaldi Thermopolis Renaldo" onClick={() => alert('Click!')} tabIndex={0} truncate={"1"} /> <FormPill icon="badge-check" onClick={() => {alert('Click!')}} tabIndex={0} text="icon and a very long tag to show truncation" truncate={"1"} /> <FormPill onClick={() => {alert('Click!')}} tabIndex={0} text="form pill with a very long tag to show truncation" truncate={"1"} /> </Card> </> ) } export default FormPillTruncatedText
For Form Pills with longer text, the wrapped prop can be used to wrap the label within each Form Pill.
Note: Avoid using the wrapped and small props together, as their styles conflict and may cause functionality issues.
import React from 'react' import { Card, Caption, FormPill, Typeahead } from 'playbook-ui' const names = [ { label: 'Alexander Nathaniel Montgomery', value: 'Alexander Nathaniel Montgomery' }, { label: 'Isabella Anastasia Wellington', value: 'Isabella Anastasia Wellington' }, { label: 'Christopher Maximilian Harrington', value: 'Christopher Maximilian Harrington' }, { label: 'Elizabeth Seraphina Kensington', value: 'Elizabeth Seraphina Kensington' }, { label: 'Theodore Jonathan Abernathy', value: 'Theodore Jonathan Abernathy' }, ] const FormPillWrapped = (props) => { return ( <> <Typeahead htmlOptions={{ style: { maxWidth: "240px" } }} isMulti label="Wrapped Within Typeahead" options={names} wrapped /> <Caption text="Form Pill Wrapped Text"/> <Card maxWidth="xs"> <FormPill avatarUrl="https://randomuser.me/api/portraits/women/44.jpg" name="Princess Amelia Mignonette Grimaldi Thermopolis Renaldo" onClick={() => alert('Click!')} tabIndex={0} wrapped /> <FormPill icon="badge-check" onClick={() => {alert('Click!')}} tabIndex={0} text="icon and a very long tag to show wrapped text" wrapped /> <FormPill onClick={() => {alert('Click!')}} tabIndex={0} text="form pill with a very long tag to show wrapped text" wrapped /> </Card> </> ) } export default FormPillWrapped
By default textTransform = "none". If there is a need to enforce lowercase, please pass the textTransform = "lowercase prop.
The Status, Data, and Product colors highlighted above can be passed to the color prop. Primary is the default color. Form pills with a text tag, an avatar, or an icon with text tag can all receive the color prop.
import React from 'react' import { FormPill, Title } from 'playbook-ui' const FormPillColors = (props) => { return ( <div> <Title marginBottom="sm" size={4} text="Status Colors" /> <FormPill onClick={() => { alert('Click!') }} tabIndex={0} text="Primary" /> <FormPill color="neutral" onClick={() => { alert('Click!') }} tabIndex={0} text="Neutral" /> <FormPill color="success" onClick={() => { alert('Click!') }} tabIndex={0} text="Success" /> <FormPill color="warning" onClick={() => { alert('Click!') }} tabIndex={0} text="Warning" /> <FormPill color="error" onClick={() => { alert('Click!') }} tabIndex={0} text="Error" /> <FormPill color="info" onClick={() => { alert('Click!') }} tabIndex={0} text="Info" /> <Title marginBottom="sm" marginTop="md" size={4} text="Data Colors" /> <FormPill color="data_1" onClick={() => { alert('Click!') }} tabIndex={0} text="Data 1" /> <FormPill color="data_2" onClick={() => { alert('Click!') }} tabIndex={0} text="Data 2" /> <FormPill color="data_3" onClick={() => { alert('Click!') }} tabIndex={0} text="Data 3" /> <FormPill color="data_4" onClick={() => { alert('Click!') }} tabIndex={0} text="Data 4" /> <FormPill color="data_5" onClick={() => { alert('Click!') }} tabIndex={0} text="Data 5" /> <FormPill color="data_6" onClick={() => { alert('Click!') }} tabIndex={0} text="Data 6" /> <FormPill color="data_7" onClick={() => { alert('Click!') }} tabIndex={0} text="Data 7" /> <FormPill color="data_8" onClick={() => { alert('Click!') }} tabIndex={0} text="Data 8" /> <Title marginBottom="sm" marginTop="md" size={4} text="Product Colors" /> <FormPill color="windows" onClick={() => { alert('Click!') }} tabIndex={0} text="Windows" /> <FormPill color="siding" onClick={() => { alert('Click!') }} tabIndex={0} text="Siding" /> <FormPill color="roofing" onClick={() => { alert('Click!') }} tabIndex={0} text="Roofing" /> <FormPill color="doors" onClick={() => { alert('Click!') }} tabIndex={0} text="Doors" /> <FormPill color="gutters" onClick={() => { alert('Click!') }} tabIndex={0} text="Gutters" /> <FormPill color="solar" onClick={() => { alert('Click!') }} tabIndex={0} text="Solar" /> <FormPill color="insulation" onClick={() => { alert('Click!') }} tabIndex={0} text="Insulation" /> <FormPill color="accessories" onClick={() => { alert('Click!') }} tabIndex={0} text="Accessories" /> </div> ) } export default FormPillColors
import React from 'react' import { FormGroup, TextInput } from 'playbook-ui' const FormGroupDefault = (props) => ( <div> <FormGroup> <TextInput id="first-name" label="First Name" placeholder="Enter First Name" /> <TextInput id="middle-initial" label="Middle Initial" placeholder="Enter Middle Initial" /> <TextInput id="last-name" label="Last Name" placeholder="Enter Last Name" /> </FormGroup> </div> ) export default FormGroupDefault
import React from 'react' import { Button, FormGroup, TextInput } from 'playbook-ui' const FormGroupButton = (props) => ( <div> <div> <FormGroup> <TextInput id="search-with-label" label="With Label" placeholder="Search" /> <Button onClick={() => alert('Button Clicked!')} text="Submit" variant="secondary" /> </FormGroup> </div> <br /> <div> <FormGroup> <TextInput placeholder="Search" /> <Button onClick={() => alert('Button Clicked!')} text="Submit" variant="secondary" /> </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, TextInput, Button } from 'playbook-ui' const FormGroupFullWidth = (props) => ( <div> <div> <FormGroup fullWidth> <TextInput id="first-name-full-width" label="First Name" placeholder="Enter First Name" /> <TextInput id="middle-initial-full-width" label="Middle Initial" placeholder="Enter Middle Initial" /> <TextInput id="last-name-full-width" label="Last Name" placeholder="Enter Last Name" /> </FormGroup> </div> <br /> <div> <FormGroup fullWidth> <TextInput placeholder="Search" /> <Button onClick={() => alert('Button Clicked!')} text="Submit" variant="secondary" /> </FormGroup> </div> </div> ) export default FormGroupFullWidth
import React from 'react' import { FormGroup, DatePicker, TextInput } from 'playbook-ui' const FormGroupDatePicker = (props) => ( <div> <FormGroup> <TextInput id="event-name" label="Event" placeholder="Event Name" /> <DatePicker label="event date" pickerId="date-picker-default" /> </FormGroup> </div> ) export default FormGroupDatePicker
import React, {useState} from 'react' import { FormGroup, PhoneNumberInput, Select, TextInput, Flex, Passphrase } from 'playbook-ui' const FormGroupSelect = (props) => { const [input, setInput] = useState(""); const handleChange = (e) => setInput(e.target.value); const options = [ { value: 'Country' }, { value: 'Pop' }, { value: 'Rock' }, { value: 'Hip-Hop/Rap' }, { value: 'Classical' }, { value: 'Gospel' }, { value: 'Alternative' }, { value: 'Indie' }, { value: 'Other' }, ] const phoneOptions = [ { value: 'Cell' }, { value: 'Work' }, { value: 'Home' }, ] return ( <Flex orientation="column" rowGap="md" > <FormGroup> <TextInput placeholder="Enter Artist Name" /> <Select blankSelection="Genre" options={options} /> </FormGroup> <FormGroup> <Select blankSelection="Phone" options={phoneOptions} /> <PhoneNumberInput id='default' /> </FormGroup> <FormGroup> <PhoneNumberInput id='default-2' /> <Select blankSelection="Phone" options={phoneOptions} /> </FormGroup> <FormGroup> <Select blankSelection="Phone" options={phoneOptions} /> <Passphrase id="my-passphrase" label="" onChange={handleChange} value={input} /> </FormGroup> </Flex> ) } export default FormGroupSelect
import React, { useState } from 'react' import { FormGroup, SelectableCard } from 'playbook-ui' 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" > {'Cat'} </SelectableCard> <SelectableCard checked={value === 'dog'} inputId="dog1" multi={false} name="animal" onChange={handleSelect} value="dog" > {'Dog'} </SelectableCard> </FormGroup> </div> ) } export default FormGroupSelectableCard
import React, { useState } from 'react' import { FormGroup, SelectableCardIcon } from 'playbook-ui' 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" /> <SelectableCardIcon checked={selectedFormat === 'football'} icon="football-ball" inputId={8} name="select" onChange={() => toggleFormat('football')} titleText="Football" value="football" /> </FormGroup> </div> ) } export default FormGroupSelectableCardIcon