Skip to content

Commit

Permalink
Refactor Button component to TypeScript (#46997)
Browse files Browse the repository at this point in the history
* Rename button/index.js to .jsx

* Possible approach to the prop types

* Simplify the tag container

* Allow passing childrent to TagElement

* Fix the type of onKeyDown

* Rename test/index.js to .tsx, fix some errors

* Fix an eslint error from children being defined in the outer scope

* Rename stories/index.js to .tsx, add type annotations

* Alphabetize types.ts types

* Refactor TagElement to element

* Alphabetize an import

* Revert changes to element, this will fail type checking

* Use the [] array type syntax

* Improve the typing of hasChildren

* Fix the typing of chilren.length

* Revert "Revert changes to element, this will fail type checking"

This reverts commit 0b616c7.

* Pass the generic of WordPressComponentProps a second argument

* Don't destructure out children, simply let them be in props

* Use React.MousEvent

* Update README.md with types from types.ts

* Fix the type of shortcut

* Remove unnecessary Type annotations

* In README.md, alphabetize the props

* Add a Required annotation to the variant prop

* Add a JS DocBlock to Button

* Add a CHANGELOG entry

* Commit Lena's suggestion: Update packages/components/src/button/types.ts

Co-authored-by: Lena Morita <lena@jaguchi.com>

* Commit Lena's suggestion: Update packages/components/src/button/deprecated.tsx

Co-authored-by: Lena Morita <lena@jaguchi.com>

* Commit Lena's suggestion: Update packages/components/src/button/index.tsx

Co-authored-by: Lena Morita <lena@jaguchi.com>

* Apply Lena's suggestion to change 'div' to 'button'

Also, correct some typing errors.

* Remvoe needless type DisabledEvent

* Remove needless argTypes that Storybook will infer from types

* Restore a deleted test, thanks to Lena's idea

As Lena mentioned, the intent of this test looks like
ensuring that additional props are passed to the element.

* Don't expect the console to error

* Update tooltipPosition in README.md

* Move the CHANGELOG entry to Unreleased

* Cherry-pick @mirka 's  commit to make Button types specific to a or button

* Commit Lena's static tests verbatim

#46997 (review)

* Fix a failed test run that I caused

* Rename CommonButtonProps to BaseButtonProps

* Commit Lena's suggestion: Update packages/components/src/button/stories/index.tsx

Co-authored-by: Lena Morita <lena@jaguchi.com>

* Commit Lena's diff for static typing test

Co-authored-by: Lena Morita <lena@jaguchi.com>
  • Loading branch information
kienstra and mirka committed Jan 24, 2023
1 parent 5115017 commit c160a7f
Show file tree
Hide file tree
Showing 16 changed files with 447 additions and 287 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Expand Up @@ -14,6 +14,7 @@
- `DropdownMenu`: migrate Storybook to controls ([47149](https://github.com/WordPress/gutenberg/pull/47149)).
- Removed deprecated `@storybook/addon-knobs` dependency from the package ([47152](https://github.com/WordPress/gutenberg/pull/47152)).
- `ColorListPicker`: Convert to TypeScript ([#46358](https://github.com/WordPress/gutenberg/pull/46358)).
- `Button`: Convert to TypeScript ([#46997](https://github.com/WordPress/gutenberg/pull/46997)).

### Bug Fix

Expand Down
Expand Up @@ -16,7 +16,7 @@ import { useBorderBoxControlLinkedButton } from './hook';
import type { LinkedButtonProps } from '../types';

const BorderBoxControlLinkedButton = (
props: WordPressComponentProps< LinkedButtonProps, 'div' >,
props: WordPressComponentProps< LinkedButtonProps, 'button' >,
forwardedRef: React.ForwardedRef< any >
) => {
const { className, isLinked, ...buttonProps } =
Expand Down
Expand Up @@ -13,7 +13,7 @@ import { useCx } from '../../utils/hooks/use-cx';
import type { LinkedButtonProps } from '../types';

export function useBorderBoxControlLinkedButton(
props: WordPressComponentProps< LinkedButtonProps, 'div' >
props: WordPressComponentProps< LinkedButtonProps, 'button' >
) {
const {
className,
Expand Down
Expand Up @@ -166,7 +166,7 @@ const BorderControlDropdown = (
onClick={ onToggle }
variant="tertiary"
aria-label={ toggleAriaLabel }
position={ dropdownPosition }
tooltipPosition={ dropdownPosition }
label={ __( 'Border color and style picker' ) }
showTooltip={ true }
>
Expand Down
104 changes: 49 additions & 55 deletions packages/components/src/button/README.md
Expand Up @@ -121,131 +121,125 @@ The presence of a `href` prop determines whether an `anchor` element is rendered

Props not included in this set will be applied to the `a` or `button` element.

#### disabled
#### `children`: `ReactNode`

Whether the button is disabled. If `true`, this will force a `button` element to be rendered.
The button's children.

- Type: `Boolean`
- Required: No

#### href
#### `className`: `string`

If provided, renders `a` instead of `button`.
An optional additional class name to apply to the rendered button.

- Type: `String`
- Required: No

#### variant
#### `describedBy`: `string`

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).
An accessible description for the button.

- Type: `String`
- Required: No

#### isDestructive
#### `disabled`: `boolean`

Renders a red text-based button style to indicate destructive behavior.
Whether the button is disabled. If `true`, this will force a `button` element to be rendered.

- Type: `Boolean`
- Required: No

#### isSmall
#### `focus`: `boolean`

Decreases the size of the button.
Whether the button is focused.

- Type: `Boolean`
- Required: No

#### isPressed
#### `href`: `string`

Renders a pressed button style.
If provided, renders `a` instead of `button`.

- Type: `Boolean`
- Required: No

#### isBusy
#### `icon`: `IconProps< unknown >[ 'icon' ]`

Indicates activity while a action is being performed.
If provided, renders an [Icon](/packages/components/src/icon/README.md) component inside the button.

- Type: `Boolean`
- Required: No

#### focus
#### `iconPosition`: `'left' | 'right'`

Whether the button is focused.
If provided with `icon`, sets the position of icon relative to the `text`. Available options are `left|right`.

- Type: `Boolean`
- Required: No
- Default: `left`

#### target
#### `iconSize`: `IconProps< unknown >[ 'size' ]`

If provided with `href`, sets the `target` attribute to the `a`.
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.

- Type: `String`
- Required: No

#### className
#### `isBusy`: `boolean`

An optional additional class name to apply to the rendered button.
Indicates activity while a action is being performed.

- Type: `String`
- Required: No

#### icon
#### `isDestructive`: `boolean`

If provided, renders an [Icon](/packages/components/src/icon/README.md) component inside the button.
Renders a red text-based button style to indicate destructive behavior.

- Type: `String|Function|WPComponent|null`
- Required: No

#### iconSize
#### `isPressed`: `boolean`

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.
Renders a pressed button style.

- Type: `Number`
- Required: No

#### iconPosition
#### `isSmall`: `boolean`

If provided with `icon`, sets the position of icon relative to the `text`. Available options are `left|right`.
Decreases the size of the button.

- Type: `string`
- Required: No
- Default: `left`

#### text
#### `label`: `string`

If provided, displays the given text inside the button. If the button contains children elements, the text is displayed before them.
Sets the `aria-label` of the component, if none is provided. Sets the Tooltip content if `showTooltip` is provided.

- Type: `String`
- Required: No

#### showTooltip
#### `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.

- Type: `Boolean`
- Required: No

#### tooltipPosition
#### `target`: `string`

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 `href`, sets the `target` attribute to the `a`.

- Type: `String`
- Require: No
- Required: No

#### shortcut
#### `text`: `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.
If provided, displays the given text inside the button. If the button contains children elements, the text is displayed before them.

- Type: `String|Object`
- Required: No

#### label
#### `tooltipPosition`: `PopoverProps[ 'position' ]`

Sets the `aria-label` of the component, if none is provided. Sets the Tooltip content if `showTooltip` is provided.
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.

- Required: No

#### `variant`: `'primary' | 'secondary' | 'tertiary' | 'link'`

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).

- Type: `String`
- Required: No

## Related components
Expand Down
@@ -1,4 +1,8 @@
// @ts-nocheck
/**
* External dependencies
*/
import type { ForwardedRef } from 'react';

/**
* WordPress dependencies
*/
Expand All @@ -8,9 +12,20 @@ import { forwardRef } from '@wordpress/element';
/**
* Internal dependencies
*/
import Button from '../button';
import Button from '.';
import type { DeprecatedIconButtonProps } from './types';

function IconButton( { labelPosition, size, tooltip, label, ...props }, ref ) {
function UnforwardedIconButton(
{
label,
labelPosition,
size,
tooltip,
...props
}: React.ComponentPropsWithoutRef< typeof Button > &
DeprecatedIconButtonProps,
ref: ForwardedRef< any >
) {
deprecated( 'wp.components.IconButton', {
since: '5.4',
alternative: 'wp.components.Button',
Expand All @@ -29,4 +44,4 @@ function IconButton( { labelPosition, size, tooltip, label, ...props }, ref ) {
);
}

export default forwardRef( IconButton );
export default forwardRef( UnforwardedIconButton );

0 comments on commit c160a7f

Please sign in to comment.