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 list view: do not use Composite store #64987

Merged

Conversation

ciampo
Copy link
Contributor

@ciampo ciampo commented Sep 2, 2024

What?

Extracted from #64723

Refactor the dataviews list view component so that it doesn't use the store from useCompositeStore

Why?

See #63704 (comment)

How?

By controlling the activeId state via props and internal logic

Follow-ups

  • Look into the styles, and see if we can use [data-focus-visible] instead of :focus-visible and :focus-within in order to follow ariakit's guidelines better.

Testing Instructions (with related video captures)

Note: this PR shouldn't change how the app behaves compared to trunk.

General navigation when loading the pages' screen

When focusing the widget for the first time, the active composite item should be the first one in the list — it should receive focus when tabbing on the composite widget.

dw-list-load.mp4

The active item matches the selected page on load

When loading the screen and a page is already selected (ie via the postId query parameter), the initial active composite item should be the one associated to the selected page. It should receive focus when tabbing on the composite widget for the first time.

dw-list-load-with-selected.mp4

Using up/down arrows correctly moves the selection

While focus in on the composite widget, left/right arrow keys should move focus of the composite items in the same row. Up/down arrow keys should focus the equivalent composite item from the previous/next row.

This should still happen even when pressing the up/down arrow keys while focussing the dropdown menu trigger buttons. In this case, the dropdown menu should not open, and the composite selection should be updated instead.

dw-list-up-down-dropdownmenu-trigger.mp4

Deleting a page shouldn't cause the active item to get out of sync

If the page associated with the currently active composite item gets deleted, a new active composite item should be automatically picked — if possible, the item after the one that got deleted, otherwise the one before (in case the last page in the list was deleted).

dw-list-delete.mp4

@ciampo ciampo self-assigned this Sep 2, 2024
@ciampo ciampo added [Type] Enhancement A suggestion for improvement. [Package] DataViews /packages/dataviews labels Sep 2, 2024
@ciampo ciampo force-pushed the feat/stabilize-composite/dataviews-list-view-no-composite-store branch 2 times, most recently from 2c97dca to 8782bd0 Compare September 3, 2024 08:57
Comment on lines +58 to +69
function generateItemWrapperCompositeId( idPrefix: string ) {
return `${ idPrefix }-item-wrapper`;
}
function generatePrimaryActionCompositeId(
idPrefix: string,
primaryActionId: string
) {
return `${ idPrefix }-primary-action-${ primaryActionId }`;
}
function generateDropdownTriggerCompositeId( idPrefix: string ) {
return `${ idPrefix }-dropdown`;
}
Copy link
Contributor Author

@ciampo ciampo Sep 3, 2024

Choose a reason for hiding this comment

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

These three functions are used to generate an id that gets associated with the different Composite.Item components — the idea is that we explicitly assign those IDs, so that we can also use them to programmatically select a new active composite item when needed.

All composite Items share the same "prefix", which is determined by the data item that the list receives.

return `${ idPrefix }-dropdown`;
}

function PrimaryActionGridCell< Item >( {
Copy link
Contributor Author

@ciampo ciampo Sep 3, 2024

Choose a reason for hiding this comment

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

I decided to extract this component because the markup was already quite nested. Also, the new version makes it clear that there are two Composite.Item that are exclusive to each other, based on the ( 'RenderModal' in primaryAction ) check.

There shouldn't be any changes to how this component works, apart from the explicit id assignment to the Composite.Item components, instead of passing the store.

);
}
} }
onKeyDown={
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved the logic to the parent component, where the rest of the active composite ID logic is.

const getItemDomId = useCallback(
( item?: Item ) =>
item ? `${ baseId }-${ getItemId( item ) }` : undefined,
const generateCompositeItemIdPrefix = useCallback(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed getItemDomId to generateCompositeItemIdPrefix, as it better explains how composite items IDs are generated and assigned (also see https://github.com/WordPress/gutenberg/pull/64987/files#r1741698739).

I slightly changed the function's signature so that undefined items are not accepted, which allows for simplifying the code below in a few places

const previousActiveItemIndex = usePrevious( activeItemIndex );
const isActiveIdInList = activeItemIndex !== -1;

const selectCompositeItem = useCallback(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function allows selecting + focusing a composite item, given its index. It's the common code behind the two main bits of "controlled state" logic in this component:

  • select a new active item if the current one gets removed (deleted);
  • move the composite active selection up/down even when focussing a dropdown menu trigger button.

@ciampo ciampo force-pushed the feat/stabilize-composite/dataviews-list-view-no-composite-store branch from 8782bd0 to 81ce43d Compare September 3, 2024 09:19
Comment on lines +373 to +382
// Update the active composite item when the selected item changes.
useEffect( () => {
if ( selectedItem ) {
setActiveCompositeId(
generateItemWrapperCompositeId(
generateCompositeItemIdPrefix( selectedItem )
)
);
}
}, [ selectedItem, generateCompositeItemIdPrefix ] );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This replicates the same logic previously used for the defaultActiveId prop in useCompositeStore()

@ciampo ciampo marked this pull request as ready for review September 3, 2024 10:00
Copy link

github-actions bot commented Sep 3, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: tyxla <tyxla@git.wordpress.org>
Co-authored-by: ntsekouras <ntsekouras@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link
Member

@tyxla tyxla left a comment

Choose a reason for hiding this comment

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

This worked well in my testing according to the test instructions 👍

Code-wise, I had a look on the surface and things looked well, but I'd prefer if @jorgefilipecosta or @oandregal could do a more thorough review to ensure we're not missing something.

@ciampo ciampo force-pushed the feat/stabilize-composite/dataviews-list-view-no-composite-store branch from 4f3f816 to 0033f7a Compare September 3, 2024 15:06
Copy link
Contributor

@ntsekouras ntsekouras left a comment

Choose a reason for hiding this comment

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

This looks and tests well. I couldn't spot any regression. Thank you!

@ciampo ciampo merged commit 14a8cf3 into trunk Sep 3, 2024
62 of 63 checks passed
@ciampo ciampo deleted the feat/stabilize-composite/dataviews-list-view-no-composite-store branch September 3, 2024 16:10
@github-actions github-actions bot added this to the Gutenberg 19.2 milestone Sep 3, 2024
@bph bph added the [Feature] Data Views Work surrounding upgrading and evolving views in the site editor and beyond label Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Data Views Work surrounding upgrading and evolving views in the site editor and beyond [Package] DataViews /packages/dataviews [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants