Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DropdownMenuV2: add GroupLabel subcomponent #64854

Merged
merged 9 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions packages/block-editor/src/hooks/block-bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,9 @@ function BlockBindingsPanelDropdown( { fieldsList, attribute, binding } ) {
<Fragment key={ name }>
<DropdownMenuV2.Group>
{ Object.keys( fieldsList ).length > 1 && (
<Text
className="block-editor-bindings__source-label"
upperCase
variant="muted"
aria-hidden
>
<DropdownMenuV2.GroupLabel>
{ registeredSources[ name ].label }
</Text>
</DropdownMenuV2.GroupLabel>
) }
{ Object.entries( fields ).map( ( [ key, value ] ) => (
<DropdownMenuV2.RadioItem
Expand Down Expand Up @@ -160,7 +155,6 @@ function EditableBlockBindingsPanelItems( {
isMobile ? 'bottom-start' : 'left-start'
}
gutter={ isMobile ? 8 : 36 }
className="block-editor-bindings__popover"
trigger={
<Item>
<BlockBindingsAttribute
Expand Down
8 changes: 0 additions & 8 deletions packages/block-editor/src/hooks/block-bindings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,3 @@ div.block-editor-bindings__panel {
color: inherit;
}
}

.block-editor-bindings__popover {
ciampo marked this conversation as resolved.
Show resolved Hide resolved
// This won't be needed if `DropdownMenuGroup` component handles the label.
.block-editor-bindings__source-label {
grid-column: 2;
margin: $grid-unit-10 0;
}
}
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
### Internal

- `DropdownMenu` v2: refactor to overloaded naming convention ([#64654](https://github.com/WordPress/gutenberg/pull/64654)).
- `DropdownMenu` v2: add `GroupLabel` subcomponent ([#64854](https://github.com/WordPress/gutenberg/pull/64854)).
- `Composite` V2: fix Storybook docgen ([#64682](https://github.com/WordPress/gutenberg/pull/64682)).

## 28.6.0 (2024-08-21)
Expand Down
18 changes: 16 additions & 2 deletions packages/components/src/dropdown-menu-v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ The help text contents.

- Required: yes

### `DropdownMenuGroup`
### `DropdownMenuV2.Group`

Used to group menu items.

Expand All @@ -325,6 +325,20 @@ The contents of the group.

- Required: yes

### `DropdownMenuSeparatorProps`
### `DropdownMenuV2.GroupLabel`

Used to render a group label. The label text should be kept as short as possible.

#### Props

The component accepts the following props:

##### `children`: `React.ReactNode`

The contents of the group label.

- Required: yes

### `DropdownMenuV2.Separator`

Used to render a visual separator.
37 changes: 37 additions & 0 deletions packages/components/src/dropdown-menu-v2/group-label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* WordPress dependencies
*/
import { forwardRef, useContext } from '@wordpress/element';

/**
* Internal dependencies
*/
import type { WordPressComponentProps } from '../context';
import { DropdownMenuContext } from './context';
import { Text } from '../text';
import type { DropdownMenuGroupLabelProps } from './types';
import * as Styled from './styles';

export const DropdownMenuGroupLabel = forwardRef<
HTMLDivElement,
WordPressComponentProps< DropdownMenuGroupLabelProps, 'div', false >
>( function DropdownMenuGroup( props, ref ) {
const dropdownMenuContext = useContext( DropdownMenuContext );
return (
<Styled.DropdownMenuGroupLabel
ref={ ref }
render={
// @ts-expect-error The `children` prop is passed
<Text
upperCase
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any chance we might want the group label not to be uppercase? Or is this an intentional design decision?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume it's intentional, but i'll let @jameskoster confirm

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type should align to a specific style from the outcome of the work in #64340 (comment).

I don't know how that would be built into the component config file though, or consumed by the Text component. I plan to open a PR soon to add tokens for the individual properties (font, size, line-height, weight), perhaps we can continue the discussion there?

variant="muted"
size="11px"
weight={ 500 }
lineHeight="16px"
/>
}
{ ...props }
store={ dropdownMenuContext?.store }
/>
);
} );
4 changes: 4 additions & 0 deletions packages/components/src/dropdown-menu-v2/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { DropdownMenuItem } from './item';
import { DropdownMenuCheckboxItem } from './checkbox-item';
import { DropdownMenuRadioItem } from './radio-item';
import { DropdownMenuGroup } from './group';
import { DropdownMenuGroupLabel } from './group-label';
import { DropdownMenuSeparator } from './separator';
import { DropdownMenuItemLabel } from './item-label';
import { DropdownMenuItemHelpText } from './item-help-text';
Expand Down Expand Up @@ -215,6 +216,9 @@ export const DropdownMenuV2 = Object.assign(
Group: Object.assign( DropdownMenuGroup, {
displayName: 'DropdownMenuV2.Group',
} ),
GroupLabel: Object.assign( DropdownMenuGroupLabel, {
ciampo marked this conversation as resolved.
Show resolved Hide resolved
displayName: 'DropdownMenuV2.GroupLabel',
} ),
Separator: Object.assign( DropdownMenuSeparator, {
displayName: 'DropdownMenuV2.Separator',
} ),
Expand Down
45 changes: 33 additions & 12 deletions packages/components/src/dropdown-menu-v2/stories/index.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const meta: Meta< typeof DropdownMenuV2 > = {
// @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170
Group: DropdownMenuV2.Group,
// @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170
GroupLabel: DropdownMenuV2.GroupLabel,
// @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170
Separator: DropdownMenuV2.Separator,
// @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170
Context: DropdownMenuV2.Context,
Expand Down Expand Up @@ -83,6 +85,7 @@ export const Default: StoryFn< typeof DropdownMenuV2 > = ( props ) => (
<DropdownMenuV2.Item disabled>Disabled item</DropdownMenuV2.Item>
<DropdownMenuV2.Separator />
<DropdownMenuV2.Group>
<DropdownMenuV2.GroupLabel>Group label</DropdownMenuV2.GroupLabel>
<DropdownMenuV2.Item
prefix={ <Icon icon={ customLink } size={ 24 } /> }
>
Expand Down Expand Up @@ -182,6 +185,9 @@ export const WithCheckboxes: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
return (
<DropdownMenuV2 { ...props }>
<DropdownMenuV2.Group>
<DropdownMenuV2.GroupLabel>
Single selection, uncontrolled
</DropdownMenuV2.GroupLabel>
<DropdownMenuV2.CheckboxItem
name="checkbox-individual-uncontrolled-a"
value="a"
Expand All @@ -191,7 +197,7 @@ export const WithCheckboxes: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Checkbox item A
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Uncontrolled
Initially unchecked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.CheckboxItem>
<DropdownMenuV2.CheckboxItem
Expand All @@ -203,12 +209,15 @@ export const WithCheckboxes: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Checkbox item B
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Uncontrolled, initially checked
Initially checked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.CheckboxItem>
</DropdownMenuV2.Group>
<DropdownMenuV2.Separator />
<DropdownMenuV2.Group>
<DropdownMenuV2.GroupLabel>
Single selection, controlled
</DropdownMenuV2.GroupLabel>
<DropdownMenuV2.CheckboxItem
name="checkbox-individual-controlled-a"
value="a"
Expand All @@ -219,7 +228,7 @@ export const WithCheckboxes: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Checkbox item A
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Controlled
Initially unchecked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.CheckboxItem>
<DropdownMenuV2.CheckboxItem
Expand All @@ -232,12 +241,15 @@ export const WithCheckboxes: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Checkbox item B
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Controlled, initially checked
Initially checked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.CheckboxItem>
</DropdownMenuV2.Group>
<DropdownMenuV2.Separator />
<DropdownMenuV2.Group>
<DropdownMenuV2.GroupLabel>
Multiple selection, uncontrolled
</DropdownMenuV2.GroupLabel>
<DropdownMenuV2.CheckboxItem
name="checkbox-multiple-uncontrolled"
value="a"
Expand All @@ -246,7 +258,7 @@ export const WithCheckboxes: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Checkbox item A
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Uncontrolled, multiple selection
Initially unchecked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.CheckboxItem>
<DropdownMenuV2.CheckboxItem
Expand All @@ -258,12 +270,15 @@ export const WithCheckboxes: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Checkbox item B
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Uncontrolled, multiple selection, initially checked
Initially checked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.CheckboxItem>
</DropdownMenuV2.Group>
<DropdownMenuV2.Separator />
<DropdownMenuV2.Group>
<DropdownMenuV2.GroupLabel>
Multiple selection, controlled
</DropdownMenuV2.GroupLabel>
<DropdownMenuV2.CheckboxItem
name="checkbox-multiple-controlled"
value="a"
Expand All @@ -274,7 +289,7 @@ export const WithCheckboxes: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Checkbox item A
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Controlled, multiple selection
Initially unchecked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.CheckboxItem>
<DropdownMenuV2.CheckboxItem
Expand All @@ -287,7 +302,7 @@ export const WithCheckboxes: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Checkbox item B
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Controlled, multiple selection, initially checked
Initially checked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.CheckboxItem>
</DropdownMenuV2.Group>
Expand All @@ -307,12 +322,15 @@ export const WithRadios: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
return (
<DropdownMenuV2 { ...props }>
<DropdownMenuV2.Group>
<DropdownMenuV2.GroupLabel>
Uncontrolled
</DropdownMenuV2.GroupLabel>
<DropdownMenuV2.RadioItem name="radio-uncontrolled" value="one">
<DropdownMenuV2.ItemLabel>
Radio item 1
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Uncontrolled
Initially unchecked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.RadioItem>
<DropdownMenuV2.RadioItem
Expand All @@ -324,12 +342,15 @@ export const WithRadios: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Radio item 2
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Uncontrolled, initially checked
Initially checked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.RadioItem>
</DropdownMenuV2.Group>
<DropdownMenuV2.Separator />
<DropdownMenuV2.Group>
<DropdownMenuV2.GroupLabel>
Controlled
</DropdownMenuV2.GroupLabel>
<DropdownMenuV2.RadioItem
name="radio-controlled"
value="one"
Expand All @@ -340,7 +361,7 @@ export const WithRadios: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Radio item 1
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Controlled
Initially unchecked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.RadioItem>
<DropdownMenuV2.RadioItem
Expand All @@ -353,7 +374,7 @@ export const WithRadios: StoryFn< typeof DropdownMenuV2 > = ( props ) => {
Radio item 2
</DropdownMenuV2.ItemLabel>
<DropdownMenuV2.ItemHelpText>
Controlled, initially checked
Initially checked
</DropdownMenuV2.ItemHelpText>
</DropdownMenuV2.RadioItem>
</DropdownMenuV2.Group>
Expand Down
9 changes: 9 additions & 0 deletions packages/components/src/dropdown-menu-v2/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,15 @@ export const DropdownMenuGroup = styled( Ariakit.MenuGroup )`
display: contents;
`;

export const DropdownMenuGroupLabel = styled( Ariakit.MenuGroupLabel )`
/* Occupy the width of all grid columns (ie. full width) */
grid-column: 1 / -1;

padding-block-start: ${ space( 3 ) };
padding-block-end: ${ space( 2 ) };
ciampo marked this conversation as resolved.
Show resolved Hide resolved
padding-inline: ${ ITEM_PADDING_INLINE };
`;

export const DropdownMenuSeparator = styled( Ariakit.MenuSeparator )<
Pick< DropdownMenuContext, 'variant' >
>`
Expand Down
7 changes: 7 additions & 0 deletions packages/components/src/dropdown-menu-v2/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ export interface DropdownMenuGroupProps {
children: React.ReactNode;
}

export interface DropdownMenuGroupLabelProps {
/**
* The contents of the dropdown menu group.
*/
children: React.ReactNode;
}

export interface DropdownMenuItemProps {
/**
* The contents of the menu item.
Expand Down
Loading