Skip to content

Commit

Permalink
MenuItem: Refactor to TypeScript (#53132)
Browse files Browse the repository at this point in the history
* - Add new type props, combine with WordPressComponentProps

- Convert menu-item.js to tsx

- Update JSDoc

* * Update ChangeLog
  • Loading branch information
bangank36 authored Aug 10, 2023
1 parent 1d7507d commit eb6a8f7
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 4 deletions.
3 changes: 3 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
### Internal

- `ControlGroup`, `FormGroup`, `ControlLabel`, `Spinner`: Remove unused `ui/` components from the codebase ([#52953](https://github.com/WordPress/gutenberg/pull/52953)).
- `MenuItem`: Convert to TypeScript ([#53132](https://github.com/WordPress/gutenberg/pull/53132)).
- `MenuGroup`: Add Storybook stories ([#53090](https://github.com/WordPress/gutenberg/pull/53090)).


## 25.4.0 (2023-07-20)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @ts-nocheck
/**
* External dependencies
*/
import type { ForwardedRef } from 'react';
import classnames from 'classnames';

/**
Expand All @@ -15,8 +15,13 @@ import { cloneElement, forwardRef } from '@wordpress/element';
import Shortcut from '../shortcut';
import Button from '../button';
import Icon from '../icon';
import type { WordPressComponentProps } from '../ui/context';
import type { MenuItemProps } from './types';

export function MenuItem( props, ref ) {
export function MenuItem(
props: WordPressComponentProps< MenuItemProps, 'button', false >,
ref: ForwardedRef< HTMLButtonElement >
) {
let {
children,
info,
Expand Down Expand Up @@ -78,4 +83,26 @@ export function MenuItem( props, ref ) {
);
}

/**
* MenuItem is a component which renders a button intended to be used in combination with the `DropdownMenu` component.
*
* ```jsx
* import { MenuItem } from '@wordpress/components';
* import { useState } from '@wordpress/element';
*
* const MyMenuItem = () => {
* const [ isActive, setIsActive ] = useState( true );
*
* return (
* <MenuItem
* icon={ isActive ? 'yes' : 'no' }
* isSelected={ isActive }
* onClick={ () => setIsActive( ( state ) => ! state ) }
* >
* Toggle
* </MenuItem>
* );
* };
* ```
*/
export default forwardRef( MenuItem );
60 changes: 60 additions & 0 deletions packages/components/src/menu-item/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* External dependencies
*/
import type { ReactNode } from 'react';

/**
* Internal dependencies
*/
import type { ButtonAsButtonProps } from '../button/types';

export type MenuItemProps = ButtonAsButtonProps & {
/**
* A CSS `class` to give to the container element.
*/
className?: string;
/**
* The children elements.
*/
children?: ReactNode;
/**
* Text to use as description for button text.
*/
info?: string;
/**
* The icon to render. Supported values are: Dashicons (specified as
* strings), functions, Component instances and `null`.
*
* @default null
*/
icon?: JSX.Element | null;
/**
* Determines where to display the provided `icon`.
*/
iconPosition?: ButtonAsButtonProps[ 'iconPosition' ];
/**
* Whether or not the menu item is currently selected.
*/
isSelected?: boolean;
/**
* If shortcut is a string, it is expecting the display text. If shortcut is an object,
* it will accept the properties of `display` (string) and `ariaLabel` (string).
*/
shortcut?: string | { display: string; ariaLabel: string };
/**
* If you need to have selectable menu items use menuitemradio for single select,
* and menuitemcheckbox for multiselect.
*
* @default 'menuitem'
*/
role?: string;
/**
* Allows for markup other than icons or shortcuts to be added to the menu item.
*
*/
suffix?: ReactNode;
/**
* Human-readable label for item.
*/
label?: string;
};
2 changes: 1 addition & 1 deletion packages/components/src/menu-items-choice/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function MenuItemsChoice( {
key={ item.value }
role="menuitemradio"
disabled={ item.disabled }
icon={ isSelected && check }
icon={ isSelected ? check : null }
info={ item.info }
isSelected={ isSelected }
shortcut={ item.shortcut }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const OptionalControlsGroup = ( {
return (
<MenuItem
key={ label }
icon={ isSelected && check }
icon={ isSelected ? check : null }
isSelected={ isSelected }
label={ itemLabel }
onClick={ () => {
Expand Down

0 comments on commit eb6a8f7

Please sign in to comment.