diff --git a/docs/components/Code.js b/docs/components/Code.js index 5d1ab04fad..6ed29a7588 100644 --- a/docs/components/Code.js +++ b/docs/components/Code.js @@ -5,7 +5,6 @@ import * as React from 'react' import { LivePreview, LiveProvider } from 'react-live' import theme from 'prism-react-renderer/themes/nightOwl' import NextLink from 'next/link' -import { Form as FinalForm } from 'react-final-form' import dateFR from 'date-fns/locale/fr' import * as yup from 'yup' import { Controller } from 'react-hook-form' @@ -20,7 +19,6 @@ import { Breadcrumb } from '@welcome-ui/breadcrumb' import { Button } from '@welcome-ui/button' import { Card } from '@welcome-ui/card' import { Checkbox } from '@welcome-ui/checkbox' -import { ConnectedField } from '@welcome-ui/connected-field' import { DatePicker } from '@welcome-ui/date-picker' import { DateTimePicker } from '@welcome-ui/date-time-picker' import * as DropdownMenu from '@welcome-ui/dropdown-menu' @@ -68,7 +66,6 @@ import * as Emoji from '@welcome-ui/emoji' import * as constants from '../constants' -import { Form } from './Form' import { HookForm } from './HookForm' import { IconsList } from './IconsList' import * as S from './Code.styled' @@ -137,7 +134,6 @@ export function Code({ children, className, isCopyable = true, live = true, row Checkbox, CodeContent: S.CodeContent, CodeContentRow: S.CodeContentRow, - ConnectedField, constants, Controller, dateFR, @@ -152,8 +148,6 @@ export function Code({ children, className, isCopyable = true, live = true, row FileDrop, ...Files, FileUpload, - FinalForm, - Form, Group, Hint, HookForm, @@ -199,7 +193,13 @@ export function Code({ children, className, isCopyable = true, live = true, row if (live === true && language === 'jsx') { return ( - + @@ -209,7 +209,7 @@ export function Code({ children, className, isCopyable = true, live = true, row - + {editorOpen && ( diff --git a/docs/components/Code.styled.js b/docs/components/Code.styled.js index bbafc16020..1e4c298098 100644 --- a/docs/components/Code.styled.js +++ b/docs/components/Code.styled.js @@ -1,7 +1,6 @@ import styled from '@xstyled/styled-components' import { th } from '@xstyled/system' import { LiveEditor as ReactLiveEditor, LiveError as ReactLiveError } from 'react-live' -import { Card } from '@welcome-ui/card' import { Box } from '@welcome-ui/box' export const LiveEditor = styled(Box)` @@ -38,13 +37,6 @@ export const LiveError = styled(ReactLiveError)` margin: xxs 0 lg; ` -export const LivePreview = styled(Card)` - display: flex; - flex-direction: column; - overflow: visible; - margin-bottom: md; -` - export const ShowEditor = styled.div` padding-top: sm; margin-top: xl; diff --git a/docs/components/Form.js b/docs/components/Form.js deleted file mode 100644 index 5d8ca685f3..0000000000 --- a/docs/components/Form.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable react/jsx-handler-names */ -/* eslint-disable no-console */ - -import React from 'react' -import { Form as FinalForm } from 'react-final-form' -import { Box } from '@welcome-ui/box' - -import { Code } from './Code' - -// eslint-disable-next-line react/prop-types -export const Form = ({ children, initialValues, validate }) => ( - - {({ handleSubmit, values }) => ( - <> -
{children}
- - {Object.keys(values).length > 0 && ( - - {JSON.stringify(values, 0, 2)} - - )} - - - )} -
-) - -export const getFormValues = node => - node.querySelector('pre') ? JSON.parse(node.querySelector('pre').textContent) : {} diff --git a/docs/components/Header.js b/docs/components/Header.js index 708518d0be..207b3f51c8 100644 --- a/docs/components/Header.js +++ b/docs/components/Header.js @@ -17,7 +17,7 @@ import { Navigation } from './Navigation' import { SelectTheme } from './SelectTheme' import * as S from './Header.styled' -export const Header = () => { +export function Header() { const modal = useModalState() const theme = useThemeContext() @@ -26,7 +26,7 @@ export const Header = () => { window.docsearch({ apiKey: '85801aa252bde17259c4a5a61c1e84db', indexName: 'welcome-ui', - inputSelector: '#search-algolia' + inputSelector: '#search-algolia', }) } }, []) @@ -75,14 +75,14 @@ export const Header = () => { - } - isClearable - name="search-algolia" - placeholder="Search" - size="sm" - /> + + } + isClearable + name="search-algolia" + placeholder="Search" + /> + - - - - - - +function() { + const FormChildren = ({ control, register }) => ( + + ( + + onChange(!e.target.checked)} + checked={value} + /> + + ) + } + /> + ( + + onChange(!e.target.checked)} + checked={value} + /> + + ) + } + /> + ( + + onChange(!e.target.checked)} + checked={value} + /> + + ) + } + /> + + ) + + return ( + + yup.object().shape({ + react: yup.boolean().required().oneOf([true, false]), + angular: yup.boolean().required().oneOf([true, false]), + vue: yup.boolean().required().oneOf([true, false]), + }) + } + > + + + ) +} + ``` ## Standalone diff --git a/docs/pages/components/date-picker.mdx b/docs/pages/components/date-picker.mdx index 5894210323..940c856a44 100644 --- a/docs/pages/components/date-picker.mdx +++ b/docs/pages/components/date-picker.mdx @@ -21,46 +21,81 @@ It is based on the [react-datepicker](https://github.com/Hacker0x01/react-datepi ## Simple use case ```jsx -
- - +function () { + const [value, setValue] = useState(Date.now()) + + const handleChange = newValue => { + setValue(newValue) + } + + return ( + + + + ) +} ``` ## Pass props from the original library. ```jsx -
- - +function () { + const [value, setValue] = useState(Date.now()) + + const handleChange = newValue => { + setValue(newValue) + } + + return ( + + + + ) +} ``` ## Give an Icon ```jsx -
- } - label="Date" - name="welcome3" - /> - +function () { + const [value, setValue] = useState(Date.now()) + + const handleChange = newValue => { + setValue(newValue) + } + + return ( + + } name="welcome3" value={value} onChange={handleChange} /> + + ) +} ``` ## fr locale ```jsx -
- - +function () { + const [value, setValue] = useState(Date.now()) + + const handleChange = newValue => { + setValue(newValue) + } + + return ( + + + + ) +} ``` ## Properties diff --git a/docs/pages/components/date-time-picker.mdx b/docs/pages/components/date-time-picker.mdx index b0cefd6071..bbf7c48f20 100644 --- a/docs/pages/components/date-time-picker.mdx +++ b/docs/pages/components/date-time-picker.mdx @@ -23,28 +23,48 @@ _Note_: Pass a value of `null` if you don't want the default value of `Date.now( ## Simple use case ```jsx -
- - +function () { + const [value, setValue] = useState(Date.now()) + + const handleChange = newValue => { + setValue(newValue) + } + + return ( + + + + ) +} ``` ## Pass props to DatePicker ```jsx -
- - } iconPlacement="right" /> - - -
+function () { + const [value, setValue] = useState(Date.now()) + + const handleChange = newValue => { + setValue(newValue) + } + + return ( + + + } iconPlacement="right" /> + + + + ) +} ``` ## Properties diff --git a/docs/pages/components/drawer.mdx b/docs/pages/components/drawer.mdx index 2ec216d737..99d4267827 100644 --- a/docs/pages/components/drawer.mdx +++ b/docs/pages/components/drawer.mdx @@ -107,19 +107,18 @@ function PlacementDrawer() { return ( <> - setPlacement(e.target.value)} - options={[ - { value: 'top', label: 'Top' }, - { value: 'right', label: 'Right' }, - { value: 'bottom', label: 'Bottom' }, - { value: 'left', label: 'Left' }, - ]} - flexDirection="row" - /> + + setPlacement(e.target.value)} + options={[ + { value: 'top', label: 'Top' }, + { value: 'right', label: 'Right' }, + { value: 'bottom', label: 'Bottom' }, + { value: 'left', label: 'Left' }, + ]} + /> + Open Drawer @@ -148,41 +147,39 @@ function SizeDrawer() { return ( <> - setSize(e.target.value)} - options={[ - { value: 'sm', label: 'sm' }, - { value: 'md', label: 'md' }, - { value: 'lg', label: 'lg' }, - { - value: '50%', - label: ( - <> - 50% (width or height depending on the placement - - ), - }, - ]} - flexDirection="row" - /> + + setSize(e.target.value)} + options={[ + { value: 'sm', label: 'sm' }, + { value: 'md', label: 'md' }, + { value: 'lg', label: 'lg' }, + { + value: '50%', + label: ( + <> + 50% (width or height depending on the placement + + ), + }, + ]} + /> + - setPlacement(e.target.value)} - options={[ - { value: 'top', label: 'Top' }, - { value: 'right', label: 'Right' }, - { value: 'bottom', label: 'Bottom' }, - { value: 'left', label: 'Left' }, - ]} - flexDirection="row" - /> + + setPlacement(e.target.value)} + options={[ + { value: 'top', label: 'Top' }, + { value: 'right', label: 'Right' }, + { value: 'bottom', label: 'Bottom' }, + { value: 'left', label: 'Left' }, + ]} + /> + Open Drawer diff --git a/docs/pages/components/field.mdx b/docs/pages/components/field.mdx index 4199ba87b8..eb458fdb2b 100644 --- a/docs/pages/components/field.mdx +++ b/docs/pages/components/field.mdx @@ -12,7 +12,7 @@ import { -We recommend using [Final Form](https://github.com/final-form/react-final-form), [Redux Form](https://github.com/erikras/redux-form) or [Formik](https://github.com/jaredpalmer/formik) with these components. If so, use `ConnectedField` for your fields (as in the examples below). The examples below give you an overview of common props (e.g. `size`, `disable`, `required` etc.) +We recommend using [React-hook-form](https://react-hook-form.com/) or [Formik](https://github.com/jaredpalmer/formik) with these components. If so, use `Field` for your fields (as in the examples below). The examples below give you an overview of common props (e.g. `size`, `disable`, `required` etc.) You can find props for each field component in the other `Forms` pages. @@ -20,197 +20,60 @@ You can find props for each field component in the other `Forms` pages. -## Sizes - -```jsx -
- <> - - - - - -``` - ## Variants ```jsx -
- <> - - - - - + + + + + + + + + ``` ## Disabled ```jsx -
- - + + + ``` ## Required ```jsx -
- - + + + ``` ## Refs -You can create a `ref`\* and pass it to a component to access the underlying DOM element. - -Note: `ref`s can be created with either `React.createRef()` or `React.useRef(null)` for functional components or a callback ref if using a React `class`. - ```jsx -function() { - const connectedInputRef = createRef() - const normalInputRef = useRef(null) - const nakedInputRef = useRef(null) - const fileUploadRef = useRef(null) - const buttonRef = useRef(null) - const linkRef = useRef(null) - - const handleConnectedClick = () => { - connectedInputRef.current.focus() - } - - const handleNormalClick = () => { - normalInputRef.current.focus() - } - - const handleNakedClick = () => { - nakedInputRef.current.focus() - } - - const handleFileUploadClick = () => { - fileUploadRef.current.focus() - } - - const handleButtonClick = () => { - console.debug(' - - - - - Click the button below to read the button's ref in the console - - - - Click the link below to read the link's ref in the console - - - Test link - - + return ( + <> + + + + + ) } ``` ## Properties - + ## Dependencies diff --git a/docs/pages/components/file-drop.mdx b/docs/pages/components/file-drop.mdx index afc11ba805..ddad65d563 100644 --- a/docs/pages/components/file-drop.mdx +++ b/docs/pages/components/file-drop.mdx @@ -33,20 +33,27 @@ By default, `accept`: is set to `image/*`, see more about [media type](https://w ```jsx function() { + const [value, setValue] = useState(null) + + const handleChange = (event) => { + setValue(event.target.value) + } + return ( -
- + - + ) } ``` @@ -56,45 +63,52 @@ function() { ### Image ```jsx -
- - +function () { + const [value, setValue] = useState('https://media3.giphy.com/media/uYiJD8fcWDys8/giphy.gif?cid=790b76115d08fb457747437951ff7674&rid=giphy.gif') + + const handleChange = (event) => { + setValue(event.target.value) + } + + return ( + + + + ) +} ``` ### Other files ```jsx -
- - +function () { + const [value, setValue] = useState('https://test-documents-file/file.docx?v=63731713698') + + const handleChange = (event) => { + setValue(event.target.value) + } + + return ( + + + + ) +} ``` ## File without type @@ -102,48 +116,44 @@ function() { Sometime in the url we don't have the type of the file, you can override with `forceFileType` set to `image`, `audio` or `video`. ```jsx -
- - - -``` +function () { + const [value, setValue] = useState('https://cdn-images.welcomehome.io/zn9KvR98haoYRV6m1T-LR4c5h0HPZtVtvzwKPv02wgA/rs:auto:600::/q:100/czM6Ly93aC1wcml2YXRlLXByb2R1Y3Rpb24vcHJvZHVjdGlvbi91cGxvYWRzL3doL2Jsb2Nrcy9iZTI2MTc4OC1mYjc5LTRlZTQtYjQ4OC04ZDhiYTk4YTY3NDIvY292ZXIvdHdpdHRlckB4Mi5wbmc') -## Disabled + const handleChange = (event) => { + setValue(event.target.value) + } -```jsx -
- - + return ( + <> + + + + + + + + ) +} ``` -## Bare example +## Disabled ```jsx -
- - + + + ``` ## Properties diff --git a/docs/pages/components/file-upload.mdx b/docs/pages/components/file-upload.mdx index 6f9502dbdd..d8cb524e40 100644 --- a/docs/pages/components/file-upload.mdx +++ b/docs/pages/components/file-upload.mdx @@ -25,42 +25,52 @@ See your browser console for the real `File` object ready to upload. See more about [media type](https://www.iana.org/assignments/media-types/media-types.xhtml). ```jsx -
- - {({ openFile }) => } - -
+function () { + const [value, setValue] = useState(null) + + const handleChange = file => { + setValue(file) + } + + return ( + + + {({ openFile }) => } + + + ) +} ``` ## Show preview if value exists ```jsx -
- - +function () { + const [value, setValue] = useState('https://doc-example/example.docx?v=63731713698') + + const handleChange = file => { + setValue(file) + } + + return ( + + + + ) +} ``` ## Multiple @@ -68,39 +78,45 @@ See more about [media type](https://www.iana.org/assignments/media-types/media-t Add `multiple` property. ```jsx -
- - {({ openFile, disabled }) => ( - - )} - -
+function () { + const [value, setValue] = useState(null) + + const handleChange = file => { + setValue(file) + } + + return ( + + + {({ openFile, disabled }) => ( + + )} + + + ) +} ``` ## Disabled ```jsx -
- + + {({ openFile, disabled }) => ( )} - -
+ + ``` ## Customize @@ -110,15 +126,25 @@ Add `multiple` property. You can change the upload button component. ```jsx -
- - {({ openFile, disabled }) => ( - - )} - -
+function () { + const [value, setValue] = useState(null) + + const handleChange = file => { + setValue(file) + } + + return ( + + + {({ openFile, disabled }) => ( + + )} + + + ) +} ``` ### Change Preview @@ -127,6 +153,12 @@ You can change the preview component. ```jsx function() { + const [value, setValue] = useState('https://doc-example/example.docx?v=63731713698') + + const handleChange = file => { + setValue(file) + } + const Preview = ({ file, onRemove }) => { const Icon = getFileIcon(file) const name = getFileName(file) @@ -154,20 +186,15 @@ function() { } return ( -
- + + {({ openFile, disabled }) => ( )} - -
+ + ) } ``` @@ -175,23 +202,33 @@ function() { You can also set the `preview` prop to `null` and handle your own preview in place of the upload button with `files` & `onRemoveFile` render props: ```jsx -
- - {({ openFile, files, onRemoveFile }) => - files.length === 0 ? ( - - ) : ( - - {files.map(file => ( - - ))} - - ) - } - -
+function () { + const [value, setValue] = useState(null) + + const handleChange = file => { + setValue(file) + } + + return ( + + + {({ openFile, files, onRemoveFile }) => + files.length === 0 ? ( + + ) : ( + + {files.map(file => ( + + ))} + + ) + } + + + ) +} ``` ## Properties diff --git a/docs/pages/components/hook-form.mdx b/docs/pages/components/hook-form.mdx index 55362b7bb6..82bc265868 100644 --- a/docs/pages/components/hook-form.mdx +++ b/docs/pages/components/hook-form.mdx @@ -10,38 +10,45 @@ function() { return ( <> + > + + + > + + { return ( onChange(e && e.target && e.target.checked)} required - value={value} - /> + > + onChange(e && e.target && e.target.checked)} + ref={register} + value={value} + /> + ) }} /> diff --git a/docs/pages/components/input-text.mdx b/docs/pages/components/input-text.mdx index c350e66335..dd051ddd70 100644 --- a/docs/pages/components/input-text.mdx +++ b/docs/pages/components/input-text.mdx @@ -19,15 +19,33 @@ import { ## Default ```jsx -
- - +function () { + const [value, setValue] = React.useState('') + + const handleChange = (event) => { + setValue(event.target.value) + } + + return +} +``` + +## With Field + +```jsx +function () { + const [value, setValue] = React.useState('') + + const handleChange = (event) => { + setValue(event.target.value) + } + + return ( + + + + ) +} ``` ## Clearable @@ -35,15 +53,15 @@ import { Use the `isClearable` prop to add a cross button to remove the content (value) of the `TextInput` ```jsx -
- - +function () { + const [value, setValue] = React.useState('') + + const handleChange = (event) => { + setValue(event.target.value) + } + + return +} ``` ## Icon @@ -51,74 +69,43 @@ Use the `isClearable` prop to add a cross button to remove the content (value) o Pass an `icon` through to decorate your `InputText` ```jsx -
- } - label="First name" - name="firstName3" - placeholder="Boaty" - /> - +function () { + const [value, setValue] = React.useState('') + + const handleChange = (event) => { + setValue(event.target.value) + } + + return } name="firstName3" placeholder="Boaty" value={value} onChange={handleChange} /> +} ``` ## Sizes ```jsx -
- - - - - -
+ + + + + ``` ## Inline ```jsx -
- - + + + ``` ## Disabled ```jsx -
- - + + + + + ``` ## Properties diff --git a/docs/pages/components/label.mdx b/docs/pages/components/label.mdx index f7cab9b8ac..9f18dfaabc 100644 --- a/docs/pages/components/label.mdx +++ b/docs/pages/components/label.mdx @@ -49,14 +49,22 @@ With `required` property. Checkboxes and radio buttons are normally nested inside labels. If you do this, make sure there is only one other child (in this example, a `div`). ```jsx - +function () { + const [checked, setChecked] = useState(false) + + const handleToggle = () => setChecked(!checked) + + return ( + + ) +} ``` ## Disabled diff --git a/docs/pages/components/markdown-editor.mdx b/docs/pages/components/markdown-editor.mdx index 9c4fad23ed..59c906950b 100644 --- a/docs/pages/components/markdown-editor.mdx +++ b/docs/pages/components/markdown-editor.mdx @@ -26,19 +26,19 @@ We use [react-simplemde-editor](https://github.com/RIP21/react-simplemde-editor) ## Usage ````jsx -
And a quote", - }} -> - - +function () { + const [value, setValue] = useState("# Hi!\n## Look at me!\n\nWe've got some **bold** and *italic* text, a cheeky bit of ~~strikethrough~~, some `inline code` and a [link](https://welcometothejungle.com). We can also do inline images by hand ![Milou](https://fr.tintin.com/images/tintin/persos/images/milou.png 'Milou') as well as:\n\n* Unordered lists\n* Unordered lists\n\n1. Ordered lists\n1. Ordered lists\n\nAnd of course the classics:\n\n```\nA code block\nwith multiple lines\n```\n\n> And a quote") + + const handleChange = event => { + setValue(event.target.value) + } + + return ( + + + + ) +} ```` ## Toolbar @@ -57,26 +57,36 @@ For example, in the toolbar below we're using icons from: Note: to use FontAwesome or Material Design icons (or any other 3rd-party icon font), you'll have to include the font stylesheet somewhere in your app. ```jsx -
- , title: 'Bold 🌴' }, - { name: 'italic', icon: }, - { name: 'divider' }, - { name: 'strikethrough', icon: }, - { name: 'link', icon: }, - { name: 'divider' }, - { name: 'code' }, - { name: 'quote', title: 'Quote 🌴' }, - { name: 'divider' }, - { name: 'emoji', icon: '👌' }, - ]} - /> - +function () { + const [value, setValue] = useState('') + + const handleChange = event => { + setValue(event.target.value) + } + + return ( + + , title: 'Bold 🌴' }, + { name: 'italic', icon: }, + { name: 'divider' }, + { name: 'strikethrough', icon: }, + { name: 'link', icon: }, + { name: 'divider' }, + { name: 'code' }, + { name: 'quote', title: 'Quote 🌴' }, + { name: 'divider' }, + { name: 'emoji', icon: '👌' }, + ]} + /> + + ) +} ``` The default toolbar uses [Welcome UI icons](/components/icon) with the following items: @@ -106,27 +116,37 @@ The default toolbar uses [Welcome UI icons](/components/icon) with the following You can add some actions on the bottom of the textarea with `actions` childrens. We calculate automatically the height of actions. ```jsx -
- - - - - - } - /> - +function () { + const [value, setValue] = useState('') + + const handleChange = event => { + setValue(event.target.value) + } + + return ( + + + + + + + } + name="welcome-actions" + placeholder="Placeholder" + onChange={handleChange} + value={value} + /> + + ) +} ``` ## Properties diff --git a/docs/pages/components/password-input.mdx b/docs/pages/components/password-input.mdx index 94afcbcb7f..f4315966d6 100644 --- a/docs/pages/components/password-input.mdx +++ b/docs/pages/components/password-input.mdx @@ -21,9 +21,33 @@ InputText component to create a password input with a show and hide password fun ## Default ```jsx -
- - +function () { + const [value, setValue] = useState('') + + const handleChange = (event) => { + setValue(event.target.value) + } + + return +} +``` + +## With Field + +```jsx +function () { + const [value, setValue] = useState('') + + const handleChange = (event) => { + setValue(event.target.value) + } + + return ( + + + + ) +} ``` ## Properties diff --git a/docs/pages/components/picker.mdx b/docs/pages/components/picker.mdx index d1dfe717ea..b36dab330f 100644 --- a/docs/pages/components/picker.mdx +++ b/docs/pages/components/picker.mdx @@ -19,79 +19,97 @@ import { ## With icons ```jsx -
- ( - - - - ), - value: 'edit', - }, - { - element: ({ selected }) => ( - - - - ), - value: 'twitter', - }, - { - element: ({ selected }) => ( - - - - ), - value: 'pencil', - }, - ]} - name="icon" - label="Icons" - required - /> - +function () { + const [value, setValue] = useState(null) + + const handleChange = event => { + setValue(event.target.value) + } + + return ( + + ( + + + + ), + value: 'edit', + }, + { + element: ({ selected }) => ( + + + + ), + value: 'twitter', + }, + { + element: ({ selected }) => ( + + + + ), + value: 'pencil', + }, + ]} + onChange={handleChange} + value={value} + /> + + ) +} ``` ## With colors and a default value ```jsx -
- ( - - - - ), - value: '1', - }, - { - element: ({ selected }) => ( - - - - ), - value: '2', - }, - { - element: ({ selected }) => ( - - - - ), - value: '3', - }, - ]} - name="color" - label="Colors" - required - /> - +function () { + const [value, setValue] = useState('3') + + const handleChange = event => { + setValue(event.target.value) + } + + return ( + + ( + + + + ), + value: '1', + }, + { + element: ({ selected }) => ( + + + + ), + value: '2', + }, + { + element: ({ selected }) => ( + + + + ), + value: '3', + }, + ]} + onChange={handleChange} + value={value} + /> + + ) +} ``` ## Properties diff --git a/docs/pages/components/radio-group.mdx b/docs/pages/components/radio-group.mdx index 995eb7e214..116af403cc 100644 --- a/docs/pages/components/radio-group.mdx +++ b/docs/pages/components/radio-group.mdx @@ -19,53 +19,59 @@ import { ## Usage ```jsx -
(!values.social ? { social: 'You must choose a social network' } : {})} -> - - - +function () { + const [value, setValue] = useState(null) + + const handleChange = event => { + setValue(event.target.value) + } + + return ( + + + + ) +} ``` ## With hint on radio ```jsx -
(!values.social ? { social: 'You must choose a social network' } : {})} -> - - - +function () { + const [value, setValue] = useState(null) + + const handleChange = event => { + setValue(event.target.value) + } + + return ( + + + + ) +} ``` ## Properties diff --git a/docs/pages/components/radio-tab.mdx b/docs/pages/components/radio-tab.mdx index e7a1947546..8ab423746f 100644 --- a/docs/pages/components/radio-tab.mdx +++ b/docs/pages/components/radio-tab.mdx @@ -19,28 +19,35 @@ import { ## Usage ```jsx -
- - - +function () { + const [value, setValue] = useState('twitter') + + const handleChange = event => { + setValue(event.target.value) + } + + return ( + + + + ) +} +``` + +```jsx +function () { + const [value, setValue] = useState('twitter') + + const handleChange = event => { + setValue(event.target.value) + } + + return ( + + + + ) +} ``` ## Properties diff --git a/docs/pages/components/search.mdx b/docs/pages/components/search.mdx index e094d0d6f4..83f753ff6e 100644 --- a/docs/pages/components/search.mdx +++ b/docs/pages/components/search.mdx @@ -21,30 +21,38 @@ This allows you to search data from a remote API. It is based on the [downshift] ## Default ```jsx -
- - item && ( -
- - - - {item.Title} ({item.Year}) -
- ) - } - placeholder="Search a movie" - itemToString={item => item && item.Title} - /> - +function () { + const [value, setValue] = useState('') + + const handleChange = (newValue) => { + setValue(newValue) + } + + return ( + + item && ( +
+ + + + {item.Title} ({item.Year}) +
+ ) + } + placeholder="Search a movie" + itemToString={item => item && item.Title} + onChange={handleChange} + value={value} + search={async function asyncSearch(s) { + const response = await fetch(`https://www.omdbapi.com?apikey=41514363&s=${s}`) + const data = await response.json() + return data.Search + }} + /> + ) +} ``` ## With option groups @@ -52,57 +60,67 @@ This allows you to search data from a remote API. It is based on the [downshift] To use option groups, you must provide two additional props: `groupsEnabled` that allow nested options and `renderGroupHeader` that renders the header of a specific group ```jsx -
- { - if (item.Type === 'movie') { - acc.movies.push(item) - } else { - acc.series.push(item) - } - return acc - }, - { movies: [], series: [] } - ) - - return [ - { label: 'Movies', options: searchResults.movies }, - { label: 'Series', options: searchResults.series }, - ] - }} - label="Movies & Series" - name="movies_series" - renderItem={item => - item && ( -
- - - - {item.Title} ({item.Year}) -
- ) - } - placeholder="Search a movie or series" - itemToString={item => item && item.Title} - groupsEnabled - renderGroupHeader={({ label, options }) => ( - - - - {label} - - {options.length} - - {options.length === 0 && No results found} - - )} - /> - +function () { + const [value, setValue] = useState('') + + const handleChange = (newValue) => { + setValue(newValue) + } + + return ( + + + item && ( +
+ + + + {item.Title} ({item.Year}) +
+ ) + } + placeholder="Search a movie or series" + itemToString={item => item && item.Title} + groupsEnabled + renderGroupHeader={({ label, options }) => ( + + + + {label} + + {options.length} + + {options.length === 0 && No results found} + + )} + onChange={handleChange} + value={value} + search={async function asyncSearch(s) { + const response = await fetch(`https://www.omdbapi.com?apikey=41514363&s=${s}`) + const data = await response.json() + const searchResults = (data.Search || []).reduce( + (acc, item) => { + if (item.Type === 'movie') { + acc.movies.push(item) + } else { + acc.series.push(item) + } + return acc + }, + { movies: [], series: [] } + ) + + return [ + { label: 'Movies', options: searchResults.movies }, + { label: 'Series', options: searchResults.series }, + ] + }} + /> +
+ ) +} ``` ## Properties diff --git a/docs/pages/components/select.mdx b/docs/pages/components/select.mdx index db15056662..34cdcf54b7 100644 --- a/docs/pages/components/select.mdx +++ b/docs/pages/components/select.mdx @@ -21,28 +21,51 @@ It is based on the [downshift](https://github.com/downshift-js/downshift) librar ## Default ```jsx -
- - +function () { + const [value, setValue] = useState(null) + + const handleChange = (newValue) => { + setValue(newValue) + } + + return + + ) +} ``` ## Clearable ```jsx -
- - +function () { + const [value, setValue] = useState('github') + + const handleChange = (newValue) => { + setValue(newValue) + } + + return ( + + + + ) +} ``` Passing a `renderMultiple` function allows you to format the selected items below the select. ```jsx -
- { - return selected.map(option => { - const Icon = option.icon - return ( - handleRemove(option.value)} - mr="sm" - mt="sm" - size="lg" - > - - - {option.label} - - - ) - }) - }} - /> - +function () { + const [value, setValue] = useState(['github', 'twitter']) + + const handleChange = (newValue) => { + setValue(newValue) + } + + return ( + + + + ) +} ``` ## Add an icon @@ -116,15 +157,25 @@ To be able to filter (i.e. search) the results, add the `isSearchable` prop. Pass `icon` to decorate your `Select` ```jsx -
- } - name="welcome6" - label="Social networks" - options={constants.ITEMS} - /> - +function () { + const [value, setValue] = useState(null) + + const handleChange = (newValue) => { + setValue(newValue) + } + + return ( + + { + const Icon = option.icon + return ( +
+ {option.label} +
+ ) + }} + /> +
+ ) +} ``` ## Creatable @@ -161,15 +222,19 @@ You can _add_ items by passing the `isCreatable` prop. The returned item will be `{ value: 'name-to-be-kebab-cased', label: 'Name to be kebab-cased' }` ```jsx -
- - +function () { + const [value, setValue] = useState(null) + + const handleChange = (newValue) => { + setValue(newValue) + } + + return ( + + { + return ( + + + + Add {value} as a new social network + + + ) + }} + /> + + ) +} ``` ## Using allowUnselectFromList and disableCloseOnSelect @@ -203,29 +278,39 @@ Passing a `renderCreateItem` function allows you to format the create button in These two options combined allows you, for example, to build a filter dropdown with checkboxes on each items. ```jsx -
- } - isMultiple - isSearchable - options={constants.ITEMS} - name="welcome9" - label="Filters" - allowUnselectFromList - disableCloseOnSelect - renderItem={(item, selected) => { - return ( - - {item.label} - - - - - ) - }} - /> - +function () { + const [value, setValue] = useState(null) + + const handleChange = (newValue) => { + setValue(newValue) + } + + return ( + + } + isCreatable + isMultiple + isSearchable + options={constants.ITEMS} + name="welcome11" + value={value} + onChange={handleChange} + /> + + ) +} ``` ## With option groups @@ -252,26 +347,36 @@ You can pass any combination of the props above. For example below, we have a `S To use option groups, you must provide two additional props: `groupsEnabled` that allow nested options and `renderGroupHeader` that renders the header of a specific group ```jsx -
- ( - - - - {label} - - {options.length} - - {options.length === 0 && No results found} - - )} - /> - +function () { + const [value, setValue] = useState(['github', 'twitter']) + + const handleChange = (newValue) => { + setValue(newValue) + } + + return ( + +