From e610f546d558cef550d544080f7e2b0674146901 Mon Sep 17 00:00:00 2001 From: atomicpages Date: Wed, 9 Sep 2020 12:39:42 -0700 Subject: [PATCH] docs(:pencil:) mo' docs - More IA reorganization - Adding docs for components - Adding notes regarding tree-shaking and building from source --- docs/docs/checkbox.md | 258 ++++++++++++++++++++++++++ docs/docs/checkbox.mdx | 57 ------ docs/docs/main-concepts/components.md | 46 +++++ docs/docs/main-concepts/controlled.md | 2 +- docs/docs/main-concepts/i18n.md | 14 ++ docs/docs/radio.md | 120 ++++++++++++ docs/docs/switch.md | 112 +++++++++++ docs/sidebars.js | 3 +- 8 files changed, 553 insertions(+), 59 deletions(-) create mode 100644 docs/docs/checkbox.md delete mode 100644 docs/docs/checkbox.mdx create mode 100644 docs/docs/main-concepts/i18n.md create mode 100644 docs/docs/radio.md create mode 100644 docs/docs/switch.md diff --git a/docs/docs/checkbox.md b/docs/docs/checkbox.md new file mode 100644 index 0000000..3e9959e --- /dev/null +++ b/docs/docs/checkbox.md @@ -0,0 +1,258 @@ +--- +id: checkbox +title: Checkbox +--- + +At the heart and soul of every application is at least one checkbox. It might be a terms and conditions agreement, +"Do not sell" CCPA notice, or something else; whatever it is, `pretty-checkbox-react` (PCR) has your back. + +## Shapes, Variants, & States + +There's no "one size fits all" for input controls like Checkbox. +Thankfully, PCR allows you to represent Checkbox in various ways via the `shape` and `variant` prop +for pre-bundled fun. See the [`shapes`](props/shapes-size) docs for more details. + +```jsx live +<> + Regular + + Thick Curve + + + Fill Round + + +``` + +### Disabled & Locked + +Of course `disabled` is supported, but there's also a secondary state called `locked`. +See the [states](props/states) docs for more details. + +```jsx live +<> + Regular + Disabled + Locked + +``` + +### Scalability + +Out of the box, PCR offers a `bigger` prop to make all input controls just a tad bit larger. +For more fine-grained control check out the [size docs](props/shapes-size#size). + +```jsx live +<> + Regular + Bigger + +``` + +## Uncontrolled + +`Checkbox` forwards `refs` to the input element :smile:. +See the [uncontrolled component docs](main-concepts/uncontrolled) for more info. + +```jsx live +function App() { + const ref = React.useRef(null); + + React.useEffect(() => { + if (ref.current) { + console.log(ref.current); + } + }, []); + + return Uncontrolled Usage; +} +``` + +## Controlled + +PCR exposes helpful state hooks to make managing state a breeze. For checkbox you should use `useCheckboxState`. +See the [controlled component docs](main-concepts/controlled) for more info. + +### Boolean Checkboxes + +For simple yes/no, or true/false usage, you can use the hook as-is without any extra config needed 😲: + +```jsx live +function App() { + const checkbox = useCheckboxState(); + + return Checked: {checkbox.state + ''}; +} +``` + +### Named Checkbox + +PCR supports checkbox controls with a `value` prop too! The resulting state will be an `array` – even if it's a single item. + +:::note +The initial `state` will be `false` unless specified otherwise. +::: + +```jsx live +function App() { + const checkbox = useCheckboxState(); + + return ( + + Checked: {checkbox.state + ''} + + ); +} +``` + +### Grouped Controls + +PCR represents _named_ checkboxes as an array which allows us to use the same state hook for multiple checkboxes! +Not only does this keep your code clean, but keeps th footprint of PCR extra small :sunglasses: + +```jsx live +function App() { + const fruits = ['apples', 'oranges', 'bananas']; + const checkbox = useCheckboxState({ state: [] }); + + return ( + <> + {fruits.map(fruit => ( + + {fruit} + + ))} +

Selected items: {checkbox.state.join(', ')}

+ + ); +} +``` + +## Indeterminate + +`indeterminate`, or tri-state checkboxes are relative niche, but have their place in the wild. +PCR supports state-driven tri-state as well as an `indeterminate` prop for uncontrolled usage. + +### Uncontrolled Indeterminate + +Using the `indeterminate`, PCR sets two things: + +1. `aria-checked` to `mixed` +2. `indeterminate` property on the `input` element to true + +:::info +As of `alpha.2` the second point isn't true. A fixed is needed on pretty-checkbox to +ensure `:indeterminate` selectors style the checkbo as checked. +::: + +```jsx live +Indeterminate +``` + +### Controlled Indeterminate + +For controlled usage, you can use the `indeterminate` _or_ use "indeterminate" as a special state keyword: + +```jsx live +function App() { + const checkbox = useCheckboxState(); + + return ( + <> + + } + {...checkbox}> + Controlled Indeterminate + + + + ); +} +``` + +Controlled indeterminates have a whole host of usages including trees! + +

+ + Credit where credit is due. This example is{' '} + + adapted from reakit + + +

+ +```jsx live +(function () { + function useTreeState({ values }) { + const group = useCheckboxState(); + const items = useCheckboxState(); + + // updates items when group is toggled + React.useEffect(() => { + if (group.state === true) { + items.setState(values); + } else if (group.state === false) { + items.setState([]); + } + }, [group.state]); + + // updates group when items is toggled + React.useEffect(() => { + if (items.state.length === values.length) { + group.setState(true); + } else if (items.state.length) { + group.setState('indeterminate'); + } else { + group.setState(false); + } + }, [items.state]); + + return { group, items }; + } + + function Icon({ state }) { + return ; + } + + function App() { + const values = ['Apple', 'Orange', 'Watermelon']; + const { group, items } = useTreeState({ values }); + + return ( + + ); + } + + return App; +})() +``` diff --git a/docs/docs/checkbox.mdx b/docs/docs/checkbox.mdx deleted file mode 100644 index ab98a15..0000000 --- a/docs/docs/checkbox.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -id: checkbox -title: Checkbox -sidebar_label: Checkbox ---- - -At the heart and soul of every application is at least one checkbox. It might be a terms and conditions agreement, -"Do not sell" CCPA notice, or something else; whatever it is, `pretty-checkbox-react` (PCR) has your back. - -## Shapes, Variants, & States - -There's no "one size fits all" for input controls like Checkbox. -Thankfully, PCR allows you to represent Checkbox in various ways via the `shape` and `variant` prop -for pre-bundled fun. See the [`shapes`](getting-started/shapes-size) docs for more details. - -```jsx live -<> - Regular - Thick Curve - Fill Round - -``` - -### Disabled & Locked - -Of course `disabled` is supported, but there's also a secondary state called `locked`. -See the [states](getting-started/states) docs for more details. - -```jsx live -<> - Regular - Disabled - Locked - -``` - -### Scalability - -Out of the box, PCR offers a `bigger` prop to make all input controls just a tad bit larger. -For more fine-grained control check out the [size docs](getting-started/shapes-size#size). - -```jsx live -<> - Regular - Bigger - -``` - -## Uncontrolled - -## Controlled - -## Indeterminate - -Building a wickedly awesome control that needs `indeterminate`, or tri-state support? -PCR has you covered for controlled and uncontrolled components. - diff --git a/docs/docs/main-concepts/components.md b/docs/docs/main-concepts/components.md index 45aef0a..688d9b8 100644 --- a/docs/docs/main-concepts/components.md +++ b/docs/docs/main-concepts/components.md @@ -97,3 +97,49 @@ Custom `data-*` attribute or something else? PCR has your back :sunglasses: ```jsx @testing-library/react ready ``` + +## Tree Shaking & Modules + +PCR is totally modular and is [side-effect free](https://webpack.js.org/guides/tree-shaking/#clarifying-tree-shaking-and-sideeffects). If you're using webpack, snowpack, or another modern bundler that supports [ES Modules or CJS Modules](https://webpack.js.org/concepts/modules/). + +### Transpiling from Source + +In addition to ES and CJS modules, PCR also packages the transpiled typescript source code for special application needs 🙂. A typical flow might look like: + +```js title="App.js" +import { Checkbox, useCheckboxState } from 'pretty-checkbox-react/dist-src/index'; + +// use your imports +``` + +If you're using babel make sure you have the following: + +- presets + - `@babel/preset-react` +- plugins + - `@babel/plugin-proposal-optional-chaining` + +```js title="webpack.config.js" +module.exports = { + module: { + rules: [ + { + test: /\.jsx?/, + // prevent exclusion of PCR from node_modules + // to allow babel to transpile for you + exclude: /(?!node_modules\/pretty-checkbox-react\/)/, + options: { + presets: [ + [ + '@babel/preset-env', + { corejs: 3 } + ], + '@babel/preset-react' + ], + plugins: ['@babel/plugin-proposal-optional-chaining'], + }, + }, + ], + }, +}; +``` diff --git a/docs/docs/main-concepts/controlled.md b/docs/docs/main-concepts/controlled.md index f700f3d..0b5239e 100644 --- a/docs/docs/main-concepts/controlled.md +++ b/docs/docs/main-concepts/controlled.md @@ -111,7 +111,7 @@ Not sold on the PCR's super awesome hooks? That's okay :cry:. Because our hooks ### React `useState` :::note -Passing `setState` while optional, is recommended since PCR internally handles different types of state. For full control use the `checked` prop instead of passing `setState`. +Passing `setState` while optional, is recommended since PCR internally handles different types of state. For full control use the `checked` prop. ::: ```jsx live diff --git a/docs/docs/main-concepts/i18n.md b/docs/docs/main-concepts/i18n.md new file mode 100644 index 0000000..4964375 --- /dev/null +++ b/docs/docs/main-concepts/i18n.md @@ -0,0 +1,14 @@ +--- +id: internationalization +title: Internationalization +--- + +PCR doesn't contain any locale-specific strings that are rendered in the browser. Since you, the super awesome user of PCR, provides all the content, it seamlessly integrates into your i18n/l10n/g11n solution :smile: + +## RTL Usage + +PCR is a stylish wrapper around standard HTML elements which means LTR support requires **zero configuration**. + +```jsx live +Hello +``` diff --git a/docs/docs/radio.md b/docs/docs/radio.md new file mode 100644 index 0000000..bbb73c9 --- /dev/null +++ b/docs/docs/radio.md @@ -0,0 +1,120 @@ +--- +id: radio +title: Radio +--- + +Radio controls are pretty much essential for any application. PCR makes it easy to add stylish radio controls to your application :+1: + +## Shapes, Variants, & States + +There's no "one size fits all" for input controls like Radio. +Thankfully, PCR allows you to represent Radio in various ways via the `shape` and `variant` prop +for pre-bundled fun. See the [`shapes`](props/shapes-size) docs for more details. + +```jsx live +<> + Regular + + Thick Curve + + + Fill Square + + +``` + +### Disabled & Locked + +Of course `disabled` is supported, but there's also a secondary state called `locked`. +See the [states](props/states) docs for more details. + +```jsx live +<> + Regular + Disabled + Locked + +``` + +### Scalability + +Out of the box, PCR offers a `bigger` prop to make all input controls just a tad bit larger. +For more fine-grained control check out the [size docs](props/shapes-size#size). + +```jsx live +<> + Regular + + Bigger + + +``` + +## Uncontrolled + +`Radio` forwards `refs` to the input element :smile:. +See the [uncontrolled component docs](main-concepts/uncontrolled) for more info. + +```jsx live +function App() { + const ref = React.useRef(null); + + React.useEffect(() => { + if (ref.current) { + console.log(ref.current); + } + }, []); + + return Uncontrolled Usage; +} +``` + +## Controlled + +PCR exposes helpful state hooks to make managing state a breeze. For radio you should use `useRadioState`. +See the [controlled component docs](main-concepts/controlled) for more info. + +### Boolean Radios + +Like checkbox, `Radio` supports boolean modes for simple yes/no options: + +```jsx live +function App() { + const radio = useRadioState(); + + return ( + <> + + Single Radio + + +

Selected: {radio.state + ''}

+ + ); +} +``` + +### Named Radios + +Typically `Radio` will have a `value` associated with the control. Unlike checkbox, `Radio` works with _single_ controls and **does not** store named results in an array. + +```jsx live +function App() { + const radio = useRadioState(); + + return ( + <> + + Thin Crust + + + Deep Dish + + + Regular Crust + +

Selected Item: {radio.state}

+ + ); +} +``` diff --git a/docs/docs/switch.md b/docs/docs/switch.md new file mode 100644 index 0000000..c417575 --- /dev/null +++ b/docs/docs/switch.md @@ -0,0 +1,112 @@ +--- +id: switch +title: Switch +--- + +In addition to Checkbox and Radio, PCR also provides a `Switch` control to provide a mobile-like experience on the web. Switches have dual-use as radio controls _or_ as checkboxes. + +## Usage + +By default `Switch` behaves like a checkbox. To make the switch behave lke a radio, use the `type` prop: + +```jsx live +<> + Basic Switch + Radio Switch + +``` + +## Shapes, Variants, & States + +There's no "one size fits all" for input controls like Switch. +Thankfully, PCR allows you to represent Radio in various ways via the `shape` prop +for pre-bundled fun. See the [`shapes`](props/shapes-size#switch) docs for more details. + +```jsx live +<> + Regular + Fill + Slim + +``` + +### Disabled & Locked + +Of course `disabled` is supported, but there's also a secondary state called `locked`. +See the [states](props/states) docs for more details. + +```jsx live +<> + Regular + Disabled + Locked + +``` + +## Uncontrolled + +`Switch` forwards `refs` to the input element :smile:. +See the [uncontrolled component docs](main-concepts/uncontrolled) for more info. + +```jsx live +function App() { + const ref = React.useRef(null); + + React.useEffect(() => { + if (ref.current) { + console.log(ref.current); + } + }, []); + + return Uncontrolled Usage; +} +``` + +## Controlled + +Switch can be used as a radio _or_ a checkbox. Because of this duality, you can use either of the following state hooks: + +- `useCheckboxState` +- `useRadioState` + +### Controlled as a Checkbox + +Like [checkbox](checkbox#controlled), you can use the state hook as a boolean, named, or grouped controls. + +:::danger Danger, Will Robinson! +`switch` is a **reserved word** and the browser will throw an error if you attempt to use the word as a variable 🙃 + +```js +const switch = useCheckboxState(); +``` + +::: + +```jsx live +function App() { + const state = useCheckboxState(); + + return Switch: {state.state + ''}; +} +``` + +### Controlled as a Radio + +Like [radio](radio#controlled) you can use the state hook as a boolean or a named value: + +```jsx live +function App() { + const radio = useRadioState(); + + return ( + <> + + Yes + + + No + + + ); +} +``` diff --git a/docs/sidebars.js b/docs/sidebars.js index 7f70898..4b7e323 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -4,6 +4,7 @@ module.exports = { { 'Main Concepts': [ 'main-concepts/components', + // 'main-concepts/internationalization', 'main-concepts/accessibility', 'main-concepts/uncontrolled', 'main-concepts/controlled', @@ -19,7 +20,7 @@ module.exports = { ], }, { - Components: ['checkbox'], + Components: ['checkbox', 'radio', 'switch'], }, { 'API Reference': ['api/checkbox', 'api/radio', 'api/switch'],