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

DataViews: use DropdownMenuRadioItem component when possible #57505

Merged
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
6 changes: 4 additions & 2 deletions packages/dataviews/src/add-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export default function AddFilter( { filters, view, onChangeView } ) {
name={ `add-filter-${ filter.field }` }
value={ element.value }
checked={ isActive }
onClick={ () => {
onChange={ ( e ) => {
onChangeView( {
...view,
page: 1,
Expand All @@ -132,7 +132,9 @@ export default function AddFilter( { filters, view, onChangeView } ) {
activeOperator,
value: isActive
? undefined
: element.value,
: e
.target
.value,
},
],
} );
Expand Down
37 changes: 23 additions & 14 deletions packages/dataviews/src/view-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import { memo } from '@wordpress/element';
*/
import { unlock } from './lock-unlock';
import { VIEW_LAYOUTS, LAYOUT_TABLE, SORTING_DIRECTIONS } from './constants';
import { DropdownMenuRadioItemCustom } from './dropdown-menu-helper';

const {
DropdownMenuV2: DropdownMenu,
DropdownMenuGroupV2: DropdownMenuGroup,
DropdownMenuItemV2: DropdownMenuItem,
DropdownMenuRadioItemV2: DropdownMenuRadioItem,
DropdownMenuCheckboxItemV2: DropdownMenuCheckboxItem,
DropdownMenuItemLabelV2: DropdownMenuItemLabel,
} = unlock( componentsPrivateApis );
Expand Down Expand Up @@ -50,7 +50,7 @@ function ViewTypeMenu( { view, onChangeView, supportedLayouts } ) {
>
{ _availableViews.map( ( availableView ) => {
return (
<DropdownMenuRadioItemCustom
<DropdownMenuRadioItem
key={ availableView.type }
value={ availableView.type }
name="view-actions-available-view"
Expand All @@ -66,7 +66,7 @@ function ViewTypeMenu( { view, onChangeView, supportedLayouts } ) {
<DropdownMenuItemLabel>
{ availableView.label }
</DropdownMenuItemLabel>
</DropdownMenuRadioItemCustom>
</DropdownMenuRadioItem>
);
} ) }
</DropdownMenu>
Expand All @@ -90,21 +90,23 @@ function PageSizeMenu( { view, onChangeView } ) {
>
{ PAGE_SIZE_VALUES.map( ( size ) => {
return (
<DropdownMenuRadioItemCustom
<DropdownMenuRadioItem
key={ size }
value={ size }
name="view-actions-page-size"
checked={ view.perPage === size }
onChange={ ( e ) => {
onChange={ () => {
onChangeView( {
...view,
perPage: e.target.value,
// `e.target.value` holds the same value as `size` but as a string,
// so we use `size` directly to avoid parsing to int.
perPage: size,
page: 1,
} );
} }
>
<DropdownMenuItemLabel>{ size }</DropdownMenuItemLabel>
</DropdownMenuRadioItemCustom>
</DropdownMenuRadioItem>
);
} ) }
</DropdownMenu>
Expand Down Expand Up @@ -210,26 +212,33 @@ function SortMenu( { fields, view, onChangeView } ) {
sortedDirection === direction &&
field.id === currentSortedField.id;

const value = `${ field.id }-${ direction }`;

return (
<DropdownMenuRadioItemCustom
key={ direction }
value={ direction }
name={ `view-actions-sorting-${ field.id }` }
<DropdownMenuRadioItem
key={ value }
// All sorting radio items share the same name, so that
// selecting a sorting option automatically deselects the
// previously selected one, even if it is displayed in
// another submenu. The field and direction are passed via
// the `value` prop.
name="view-actions-sorting"
value={ value }
checked={ isChecked }
onChange={ ( e ) => {
onChange={ () => {
onChangeView( {
...view,
sort: {
field: field.id,
direction: e.target.value,
direction,
},
} );
} }
>
<DropdownMenuItemLabel>
{ info.label }
</DropdownMenuItemLabel>
</DropdownMenuRadioItemCustom>
</DropdownMenuRadioItem>
);
}
) }
Expand Down
27 changes: 18 additions & 9 deletions packages/dataviews/src/view-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const {
DropdownMenuV2: DropdownMenu,
DropdownMenuGroupV2: DropdownMenuGroup,
DropdownMenuItemV2: DropdownMenuItem,
DropdownMenuRadioItemV2: DropdownMenuRadioItem,
DropdownMenuSeparatorV2: DropdownMenuSeparator,
DropdownMenuItemLabelV2: DropdownMenuItemLabel,
} = unlock( componentsPrivateApis );
Expand Down Expand Up @@ -93,26 +94,34 @@ function HeaderMenu( { field, view, onChangeView } ) {
const isChecked =
isSorted &&
view.sort.direction === direction;

const value = `${ field.id }-${ direction }`;

return (
<DropdownMenuRadioItemCustom
key={ direction }
name={ `view-table-sort-${ field.id }` }
value={ direction }
<DropdownMenuRadioItem
key={ value }
// All sorting radio items share the same name, so that
// selecting a sorting option automatically deselects the
// previously selected one, even if it is displayed in
// another submenu. The field and direction are passed via
// the `value` prop.
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't use the value right now, so this part of the comment could be removed, right?

Copy link
Contributor Author

@ciampo ciampo Jan 3, 2024

Choose a reason for hiding this comment

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

The value is required by radio items (both the DropdownMenuRadioItem component, the underlying ariakit implementation, and radio inputs in general). In the component's internal logic, it is necessary to distinguish each radio item from the others within the same radio group.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, just referring to The field and direction are passed via the value prop. part of comment. Is this part relevant?

Copy link
Contributor Author

@ciampo ciampo Jan 3, 2024

Choose a reason for hiding this comment

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

In my mind, it is — it complements the fact that name is very generic and doesn't include field and/or direction. But I appreciate that it could sound superfluous to other devs.

name="view-table-sorting"
value={ value }
checked={ isChecked }
onChange={ ( e ) => {
onChange={ () => {
onChangeView( {
...view,
sort: {
field: field.id,
direction: e.target.value,
direction,
},
} );
} }
>
<DropdownMenuItemLabel>
{ info.label }
</DropdownMenuItemLabel>
</DropdownMenuRadioItemCustom>
</DropdownMenuRadioItem>
);
}
) }
Expand Down Expand Up @@ -220,7 +229,7 @@ function HeaderMenu( { field, view, onChangeView } ) {
operator,
{ label, key },
] ) => (
<DropdownMenuRadioItemCustom
<DropdownMenuRadioItem
key={ key }
name={ `view-table-${ filter.field }-conditions` }
value={ operator }
Expand Down Expand Up @@ -248,7 +257,7 @@ function HeaderMenu( { field, view, onChangeView } ) {
<DropdownMenuItemLabel>
{ label }
</DropdownMenuItemLabel>
</DropdownMenuRadioItemCustom>
</DropdownMenuRadioItem>
)
) }
</DropdownMenu>
Expand Down
Loading