From d50f8a68e3d6b316a58c02154a22fe39c2e69b84 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Thu, 31 Oct 2024 03:38:03 +0900 Subject: [PATCH 01/12] Button: Auto-generate README --- packages/components/src/button/README.md | 327 ++++++------------ .../components/src/button/docs-manifest.json | 5 + packages/components/src/button/types.ts | 10 +- 3 files changed, 117 insertions(+), 225 deletions(-) create mode 100644 packages/components/src/button/docs-manifest.json diff --git a/packages/components/src/button/README.md b/packages/components/src/button/README.md index d458771494a338..4c5254fe91549b 100644 --- a/packages/components/src/button/README.md +++ b/packages/components/src/button/README.md @@ -1,304 +1,191 @@ # Button -Buttons let users take actions and make choices with a single click or tap. + -![Button components](https://make.wordpress.org/design/files/2019/03/button.png) +

See the WordPress Storybook for more detailed, interactive documentation.

-## Design guidelines - -### Usage - -Buttons tell users what actions they can take and give them a way to interact with the interface. You’ll find them throughout a UI, particularly in places like: - -- Modals -- Forms -- Toolbars - -### Best practices - -Buttons should: - -- **Be clearly and accurately labeled.** -- **Clearly communicate that clicking or tapping will trigger an action.** -- **Use established colors appropriately.** For example, only use red buttons for actions that are difficult or impossible to undo. -- **Prioritize the most important actions.** This helps users focus. Too many calls to action on one screen can be confusing, making users unsure what to do next. -- **Have consistent locations in the interface.** - -### Content guidelines - -Buttons should be clear and predictable—users should be able to anticipate what will happen when they click a button. Never deceive a user by mislabeling a button. - -Buttons text should lead with a strong verb that encourages action, and add a noun that clarifies what will actually change. The only exceptions are common actions like Save, Close, Cancel, or OK. Otherwise, use the {verb}+{noun} format to ensure that your button gives the user enough information. - -Button text should also be quickly scannable — avoid unnecessary words and articles like the, an, or a. - -### Types - -#### Link button - -Link buttons have low emphasis. They don’t stand out much on the page, so they’re used for less-important actions. What’s less important can vary based on context, but it’s usually a supplementary action to the main action we want someone to take. Link buttons are also useful when you don’t want to distract from the content. - -![Link button](https://make.wordpress.org/design/files/2019/03/link-button.png) - -#### Default button - -Default buttons have medium emphasis. The button appearance helps differentiate them from the page background, so they’re useful when you want more emphasis than a link button offers. - -![Default button](https://make.wordpress.org/design/files/2019/03/default-button.png) - -#### Primary button - -Primary buttons have high emphasis. Their color fill and shadow means they pop off the background. - -Since a high-emphasis button commands the most attention, a layout should contain a single primary button. This makes it clear that other buttons have less importance and helps users understand when an action requires their attention. - -![Primary button](https://make.wordpress.org/design/files/2019/03/primary-button.png) - -#### Text label - -All button types use text labels to describe the action that happens when a user taps a button. If there’s no text label, there needs to be a [label](#label) added and an icon to signify what the button does. - -![](https://make.wordpress.org/design/files/2019/03/do-link-button.png) - -**Do** -Use color to distinguish link button labels from other text. - -![](https://make.wordpress.org/design/files/2019/03/dont-wrap-button-text.png) - -**Don’t** -Don’t wrap button text. For maximum legibility, keep text labels on a single line. - -### Hierarchy - -![A layout with a single prominent button](https://make.wordpress.org/design/files/2019/03/button.png) - -A layout should contain a single prominently-located button. If multiple buttons are required, a single high-emphasis button can be joined by medium- and low-emphasis buttons mapped to less-important actions. When using multiple buttons, make sure the available state of one button doesn’t look like the disabled state of another. - -![A diagram showing high emphasis at the top, medium emphasis in the middle, and low emphasis at the bottom](https://make.wordpress.org/design/files/2019/03/button-hierarchy.png) - -A button’s level of emphasis helps determine its appearance, typography, and placement. - -#### Placement - -Use button types to express different emphasis levels for all the actions a user can perform. - -![A link, default, and primary button](https://make.wordpress.org/design/files/2019/03/button-layout.png) - -This screen layout uses: - -1. A primary button for high emphasis. -2. A default button for medium emphasis. -3. A link button for low emphasis. - -Placement best practices: - -- **Do**: When using multiple buttons in a row, show users which action is more important by placing it next to a button with a lower emphasis (e.g. a primary button next to a default button, or a default button next to a link button). -- **Don’t**: Don’t place two primary buttons next to one another — they compete for focus. Only use one primary button per view. -- **Don’t**: Don’t place a button below another button if there is space to place them side by side. -- **Caution**: Avoid using too many buttons on a single page. When designing pages in the app or website, think about the most important actions for users to take. Too many calls to action can cause confusion and make users unsure what to do next — we always want users to feel confident and capable. - -## Development guidelines - -### Usage - -Renders a button with default style. +Lets users take actions and make choices with a single click or tap. ```jsx import { Button } from '@wordpress/components'; - -const MyButton = () => ; +const Mybutton = () => ( + +); ``` +## Props -### Props +### `__next40pxDefaultSize` -The presence of a `href` prop determines whether an `anchor` element is rendered instead of a `button`. +Start opting into the larger default height that will become the +default size in a future version. -Props not included in this set will be applied to the `a` or `button` element. + - Type: `boolean` + - Required: No + - Default: `false` -#### `accessibleWhenDisabled`: `boolean` +### `accessibleWhenDisabled` Whether to keep the button focusable when disabled. -In most cases, it is recommended to set this to `true`. Disabling a control without maintaining focusability can cause accessibility issues, by hiding their presence from screen reader users, or by preventing focus from returning to a trigger element. +In most cases, it is recommended to set this to `true`. Disabling a control without maintaining focusability +can cause accessibility issues, by hiding their presence from screen reader users, +or by preventing focus from returning to a trigger element. -Learn more about the [focusability of disabled controls](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols) in the WAI-ARIA Authoring Practices Guide. +Learn more about the [focusability of disabled controls](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols) +in the WAI-ARIA Authoring Practices Guide. -- Required: No -- Default: `false` + - Type: `boolean` + - Required: No + - Default: `false` -#### `children`: `ReactNode` +### `children` The button's children. -- Required: No - -#### `className`: `string` + - Type: `ReactNode` + - Required: No -An optional additional class name to apply to the rendered button. +### `description` -- Required: No +A visually hidden accessible description for the button. -#### `description`: `string` + - Type: `string` + - Required: No -An accessible description for the button. +### `disabled` -- Required: No - -#### `disabled`: `boolean` - -Whether the button is disabled. If `true`, this will force a `button` element to be rendered, even when an `href` is given. +Whether the button is disabled. If `true`, this will force a `button` element +to be rendered, even when an `href` is given. In most cases, it is recommended to also set the `accessibleWhenDisabled` prop to `true`. -- Required: No + - Type: `boolean` + - Required: No -#### `href`: `string` +### `href` If provided, renders `a` instead of `button`. -- Required: No + - Type: `string` + - Required: Yes -#### `icon`: `IconProps< unknown >[ 'icon' ]` +### `icon` -If provided, renders an [Icon](/packages/components/src/icon/README.md) component inside the button. +If provided, renders an Icon component inside the button. -- Required: No + - Type: `IconType` + - Required: No -#### `iconPosition`: `'left' | 'right'` +### `iconPosition` -If provided with `icon`, sets the position of icon relative to the `text`. Available options are `left|right`. +If provided with `icon`, sets the position of icon relative to the `text`. -- Required: No -- Default: `left` + - Type: `"left" | "right"` + - Required: No + - Default: `'left'` -#### `iconSize`: `IconProps< unknown >[ 'size' ]` +### `iconSize` -If provided with `icon`, sets the icon size. Please refer to the [Icon](/packages/components/src/icon/README.md) component for more details regarding the default value of its `size` prop. +If provided with `icon`, sets the icon size. +Please refer to the Icon component for more details regarding +the default value of its `size` prop. -- Required: No + - Type: `number` + - Required: No -#### `isBusy`: `boolean` +### `isBusy` Indicates activity while a action is being performed. -- Required: No + - Type: `boolean` + - Required: No -#### `isDestructive`: `boolean` +### `isDestructive` Renders a red text-based button style to indicate destructive behavior. -- Required: No - -#### `isLink`: `boolean` - -Deprecated: Renders a button with an anchor style. -Use `variant` prop with `link` value instead. + - Type: `boolean` + - Required: No -- Required: No -- Default: `false` - -#### `isPressed`: `boolean` +### `isPressed` Renders a pressed button style. -If the native `aria-pressed` attribute is also set, it will take precedence. - -- Required: No - -#### `isPrimary`: `boolean` - -Deprecated: Renders a primary button style. -Use `variant` prop with `primary` value instead. + - Type: `boolean` + - Required: No -- Required: No -- Default: `false` +### `label` -#### `isSecondary`: `boolean` +Sets the `aria-label` of the component, if none is provided. +Sets the Tooltip content if `showTooltip` is provided. -Deprecated: Renders a default button style. -Use `variant` prop with `secondary` value instead. + - Type: `string` + - Required: No -- Required: No -- Default: `false` +### `shortcut` -#### `isSmall`: `boolean` +If provided with `showTooltip`, appends the Shortcut label to the tooltip content. +If an object is provided, it should contain `display` and `ariaLabel` keys. -Decreases the size of the button. + - Type: `string | { display: string; ariaLabel: string; }` + - Required: No -Deprecated in favor of the `size` prop. If both props are defined, the `size` prop will take precedence. +### `showTooltip` -- Required: No +If provided, renders a Tooltip component for the button. -#### `isTertiary`: `boolean` + - Type: `boolean` + - Required: No -Deprecated: Renders a text-based button style. -Use `variant` prop with `tertiary` value instead. - -- Required: No -- Default: `false` - -#### `label`: `string` - -Sets the `aria-label` of the component, if none is provided. Sets the Tooltip content if `showTooltip` is provided. - -- Required: No - -#### `shortcut`: `string | { display: string; ariaLabel: string; }` - -If provided with `showTooltip`, appends the Shortcut label to the tooltip content. If an object is provided, it should contain `display` and `ariaLabel` keys. - -- Required: No - -#### `showTooltip`: `boolean` - -If provided, renders a [Tooltip](/packages/components/src/tooltip/README.md) component for the button. - -- Required: No - -#### `size`: `'default'` | `'compact'` | `'small'` +### `size` The size of the button. -- `'default'`: For normal text-label buttons, unless it is a toggle button. -- `'compact'`: For toggle buttons, icon buttons, and buttons when used in context of either. -- `'small'`: For icon buttons associated with more advanced or auxiliary features. +- `'default'`: For normal text-label buttons, unless it is a toggle button. +- `'compact'`: For toggle buttons, icon buttons, and buttons when used in context of either. +- `'small'`: For icon buttons associated with more advanced or auxiliary features. If the deprecated `isSmall` prop is also defined, this prop will take precedence. -- Required: No -- Default: `'default'` - -#### `target`: `string` - -If provided with `href`, sets the `target` attribute to the `a`. - -- Required: No + - Type: `"small" | "default" | "compact"` + - Required: No + - Default: `'default'` -#### `text`: `string` +### `text` If provided, displays the given text inside the button. If the button contains children elements, the text is displayed before them. -- Required: No + - Type: `string` + - Required: No -#### `tooltipPosition`: `PopoverProps[ 'position' ]` +### `tooltipPosition` -If provided with`showTooltip`, sets the position of the tooltip. Please refer to the [Tooltip](/packages/components/src/tooltip/README.md) component for more details regarding the defaults. +If provided with `showTooltip`, sets the position of the tooltip. +Please refer to the Tooltip component for more details regarding the defaults. -- Required: No + - Type: `"top" | "middle" | "bottom" | "top center" | "top left" | "top right" | "middle center" | "middle left" | "middle right" | "bottom center" | ...` + - Required: No -#### `variant`: `'primary' | 'secondary' | 'tertiary' | 'link'` +### `target` -Specifies the button's style. The accepted values are `'primary'` (the primary button styles), `'secondary'` (the default button styles), `'tertiary'` (the text-based button styles), and `'link'` (the link button styles). - -- Required: No +If provided with `href`, sets the `target` attribute to the `a`. -#### `__next40pxDefaultSize`: `boolean` + - Type: `string` + - Required: No -Start opting into the larger default height that will become the default size in a future version. +### `variant` -- Required: No -- Default: `false` +Specifies the button's style. -## Related components +- `'primary'` (the primary button styles) +- `'secondary'` (the default button styles) +- `'tertiary'` (the text-based button styles) +- `'link'` (the link button styles) -- To group buttons together, use the [ButtonGroup](/packages/components/src/button-group/README.md) component. + - Type: `"link" | "primary" | "secondary" | "tertiary"` + - Required: No diff --git a/packages/components/src/button/docs-manifest.json b/packages/components/src/button/docs-manifest.json new file mode 100644 index 00000000000000..0fd0f84f44e102 --- /dev/null +++ b/packages/components/src/button/docs-manifest.json @@ -0,0 +1,5 @@ +{ + "$schema": "../../schemas/docs-manifest.json", + "displayName": "Button", + "filePath": "./index.tsx" +} diff --git a/packages/components/src/button/types.ts b/packages/components/src/button/types.ts index 7d67b721a5036d..ff11e858ae8aca 100644 --- a/packages/components/src/button/types.ts +++ b/packages/components/src/button/types.ts @@ -111,11 +111,11 @@ type BaseButtonProps = { tooltipPosition?: PopoverProps[ 'position' ]; /** * Specifies the button's style. - * The accepted values are: - * 'primary' (the primary button styles) - * 'secondary' (the default button styles) - * 'tertiary' (the text-based button styles) - * 'link' (the link button styles) + * + * - `'primary'` (the primary button styles) + * - `'secondary'` (the default button styles) + * - `'tertiary'` (the text-based button styles) + * - `'link'` (the link button styles) */ variant?: 'primary' | 'secondary' | 'tertiary' | 'link'; }; From 0711230b37ce6e648d2db5b038e63c3a9e7e4346 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Thu, 31 Oct 2024 03:41:35 +0900 Subject: [PATCH 02/12] Add additional mdx file --- .../components/src/button/stories/best-practices.mdx | 9 +++++++++ storybook/main.js | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 packages/components/src/button/stories/best-practices.mdx diff --git a/packages/components/src/button/stories/best-practices.mdx b/packages/components/src/button/stories/best-practices.mdx new file mode 100644 index 00000000000000..b8eef75c7ba921 --- /dev/null +++ b/packages/components/src/button/stories/best-practices.mdx @@ -0,0 +1,9 @@ +import { Meta } from '@storybook/blocks'; + + + +# Button + +## Best Practices + +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \ No newline at end of file diff --git a/storybook/main.js b/storybook/main.js index e482ee23c2e5fc..bf101c57a2e2d0 100644 --- a/storybook/main.js +++ b/storybook/main.js @@ -31,7 +31,8 @@ const stories = [ process.env.NODE_ENV !== 'test' && './stories/**/*.story.@(js|tsx)', process.env.NODE_ENV !== 'test' && './stories/**/*.mdx', '../packages/block-editor/src/**/stories/*.story.@(js|tsx|mdx)', - '../packages/components/src/**/stories/*.story.@(js|tsx|mdx)', + '../packages/components/src/**/stories/*.story.@(js|tsx)', + '../packages/components/src/**/stories/*.mdx', '../packages/icons/src/**/stories/*.story.@(js|tsx|mdx)', '../packages/edit-site/src/**/stories/*.story.@(js|tsx|mdx)', '../packages/dataviews/src/**/stories/*.story.@(js|tsx|mdx)', From f3db348ded5f538f5c3ffc148e0492f93365ea16 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Thu, 31 Oct 2024 16:51:55 +0900 Subject: [PATCH 03/12] Fixup to prevent merging consecutive lists --- packages/components/src/button/README.md | 10 ++++++---- packages/components/src/button/types.ts | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/components/src/button/README.md b/packages/components/src/button/README.md index 4c5254fe91549b..99a6d0f9c24cfb 100644 --- a/packages/components/src/button/README.md +++ b/packages/components/src/button/README.md @@ -182,10 +182,12 @@ If provided with `href`, sets the `target` attribute to the `a`. Specifies the button's style. -- `'primary'` (the primary button styles) -- `'secondary'` (the default button styles) -- `'tertiary'` (the text-based button styles) -- `'link'` (the link button styles) +The accepted values are: + +1. `'primary'` (the primary button styles) +2. `'secondary'` (the default button styles) +3. `'tertiary'` (the text-based button styles) +4. `'link'` (the link button styles) - Type: `"link" | "primary" | "secondary" | "tertiary"` - Required: No diff --git a/packages/components/src/button/types.ts b/packages/components/src/button/types.ts index ff11e858ae8aca..d730f49b1e8138 100644 --- a/packages/components/src/button/types.ts +++ b/packages/components/src/button/types.ts @@ -112,10 +112,12 @@ type BaseButtonProps = { /** * Specifies the button's style. * - * - `'primary'` (the primary button styles) - * - `'secondary'` (the default button styles) - * - `'tertiary'` (the text-based button styles) - * - `'link'` (the link button styles) + * The accepted values are: + * + * 1. `'primary'` (the primary button styles) + * 2. `'secondary'` (the default button styles) + * 3. `'tertiary'` (the text-based button styles) + * 4. `'link'` (the link button styles) */ variant?: 'primary' | 'secondary' | 'tertiary' | 'link'; }; From ec69ef6879a2323abcf9422c46216efbefc7345c Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Fri, 15 Nov 2024 00:01:09 +0900 Subject: [PATCH 04/12] Add FigmaEmbed component --- .../src/button/stories/best-practices.mdx | 5 +- storybook/components/figma-embed/index.js | 47 +++++++++++++++++++ storybook/components/figma-embed/style.scss | 4 ++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 storybook/components/figma-embed/index.js create mode 100644 storybook/components/figma-embed/style.scss diff --git a/packages/components/src/button/stories/best-practices.mdx b/packages/components/src/button/stories/best-practices.mdx index b8eef75c7ba921..d5bde053a0519b 100644 --- a/packages/components/src/button/stories/best-practices.mdx +++ b/packages/components/src/button/stories/best-practices.mdx @@ -1,4 +1,5 @@ import { Meta } from '@storybook/blocks'; +import FigmaEmbed from '/storybook/components/figma-embed'; @@ -6,4 +7,6 @@ import { Meta } from '@storybook/blocks'; ## Best Practices -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \ No newline at end of file +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + + \ No newline at end of file diff --git a/storybook/components/figma-embed/index.js b/storybook/components/figma-embed/index.js new file mode 100644 index 00000000000000..8d8ac6488a9334 --- /dev/null +++ b/storybook/components/figma-embed/index.js @@ -0,0 +1,47 @@ +/** + * Internal dependencies + */ +import './style.scss'; + +// See https://www.figma.com/developers/embed#embed-a-figma-file +const CONFIG = { + 'embed-host': 'wordpress-storybook', + footer: false, + 'page-selector': false, + 'viewport-controls': true, +}; + +/** + * Embed Figma links in the Storybook. + * + * @param {Object} props + * @param {string} props.url - Figma URL to embed. + * @param {string} props.title - Accessible title for the iframe. + */ +function FigmaEmbed( { url, title, ...props } ) { + const urlObj = new URL( url ); + + const queryParams = new URLSearchParams( urlObj.search ); + Object.entries( CONFIG ).forEach( ( [ key, value ] ) => { + queryParams.set( key, value ); + } ); + urlObj.search = queryParams.toString(); + + urlObj.hostname = urlObj.hostname.replace( + 'www.figma.com', + 'embed.figma.com' + ); + + const normalizedUrl = urlObj.toString(); + + return ( +