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

Add new @wordpress/preferences package #38873

Merged
merged 10 commits into from
Feb 25, 2022
Merged

Conversation

talldan
Copy link
Contributor

@talldan talldan commented Feb 17, 2022

Description

First part of #31965

This PR contains part of the code from #38435, I've separated it out for easier review and will keep the two in sync.

It adds a new @wordpress/preferences package with a data store and a few components.

Here's some links to the documentation for everything this PR introduces:

This is a good time to review the API and do any renaming. At the moment, everything works similarly to the way it does in trunk, but there is scope now to change things.

Currently the only preferences managed in the new package are what we call 'feature' preferences, which are just simple boolean flags. Surprisingly this covers almost all the preferences in our editors, with the exception of a couple of things:

  • The code editor/visual editor toggle (this would be more of an enum type setting, and can be handled in a follow-up)
  • The block manager (which I think should probably be kept entirely separate to preferences because it relies on block registration and block types)

Testing Instructions

For testing use the add/new-preferences-package branch from #38435. Everything should behave the same as trunk in the post editor, widgets editor and customize widgets editor which I've refactored in that PR to use the new preferences store.

Types of changes

New package (non-breaking change which adds functionality)

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all *.native.js files for terms that need renaming or removal).
  • I've updated related schemas if appropriate.

@talldan talldan added the [Type] New API New API to be used by plugin developers or package users. label Feb 17, 2022
@talldan talldan self-assigned this Feb 17, 2022
@talldan talldan requested review from tellthemachines, a team, fullofcaffeine, youknowriad and gziolo and removed request for a team February 17, 2022 04:21
* @param {string} scope The feature scope (e.g. core/edit-post).
* @param {string} featureName The feature name.
*/
export function toggleFeature( scope, featureName ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the future I imagine we'll have not only boolean preferences in this store but also other types. Probably an 'enum' style preference would be next.

I considered whether there should just be one function for setting any kind of preference, but I think a toggle style function is quite a nice convenience compared to a more freeform setPreferenceValue, so I've kept this API similar to the way it is now.

Renaming it from 'feature' is something we might consider though.

*
* @return {Object} Action object.
*/
export function setFeatureDefaults( scope, defaults ) {
Copy link
Contributor Author

@talldan talldan Feb 17, 2022

Choose a reason for hiding this comment

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

In contrast to my previous comment, I think this function could set the defaults for both boolean and enum style settings. So perhaps this is something we might rename to setDefaults.

Thoughts?

Maybe I should also make everything experimental to start with.

@talldan talldan force-pushed the create/new-preferences-package branch from d1ee33a to 8c0be41 Compare February 17, 2022 05:05
@github-actions
Copy link

github-actions bot commented Feb 17, 2022

Size Change: 0 B

Total Size: 1.15 MB

ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/admin-manifest/index.min.js 1.24 kB
build/annotations/index.min.js 2.77 kB
build/api-fetch/index.min.js 2.25 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 487 B
build/block-directory/index.min.js 6.49 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/index.min.js 143 kB
build/block-editor/style-rtl.css 14.8 kB
build/block-editor/style.css 14.8 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 470 B
build/block-library/blocks/button/editor.css 470 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-template/style-rtl.css 127 B
build/block-library/blocks/comment-template/style.css 127 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-query-loop/editor-rtl.css 95 B
build/block-library/blocks/comments-query-loop/editor.css 95 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.57 kB
build/block-library/blocks/cover/style.css 1.57 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 965 B
build/block-library/blocks/gallery/editor.css 967 B
build/block-library/blocks/gallery/style-rtl.css 1.61 kB
build/block-library/blocks/gallery/style.css 1.61 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 731 B
build/block-library/blocks/image/editor.css 730 B
build/block-library/blocks/image/style-rtl.css 518 B
build/block-library/blocks/image/style.css 523 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 447 B
build/block-library/blocks/latest-posts/style.css 446 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 649 B
build/block-library/blocks/navigation-link/editor.css 650 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/view.min.js 375 B
build/block-library/blocks/navigation/editor-rtl.css 1.98 kB
build/block-library/blocks/navigation/editor.css 1.99 kB
build/block-library/blocks/navigation/style-rtl.css 1.89 kB
build/block-library/blocks/navigation/style.css 1.88 kB
build/block-library/blocks/navigation/view.min.js 2.85 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 401 B
build/block-library/blocks/page-list/editor.css 402 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 273 B
build/block-library/blocks/paragraph/style.css 273 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/style-rtl.css 446 B
build/block-library/blocks/post-comments-form/style.css 446 B
build/block-library/blocks/post-comments/style-rtl.css 521 B
build/block-library/blocks/post-comments/style.css 521 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 721 B
build/block-library/blocks/post-featured-image/editor.css 721 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 323 B
build/block-library/blocks/post-template/style.css 323 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 389 B
build/block-library/blocks/pullquote/style.css 388 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 201 B
build/block-library/blocks/quote/style.css 201 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 233 B
build/block-library/blocks/separator/style.css 233 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 744 B
build/block-library/blocks/site-logo/editor.css 744 B
build/block-library/blocks/site-logo/style-rtl.css 181 B
build/block-library/blocks/site-logo/style.css 181 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.37 kB
build/block-library/blocks/social-links/style.css 1.36 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 214 B
build/block-library/blocks/tag-cloud/style.css 215 B
build/block-library/blocks/template-part/editor-rtl.css 235 B
build/block-library/blocks/template-part/editor.css 235 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 921 B
build/block-library/common.css 919 B
build/block-library/editor-rtl.css 9.9 kB
build/block-library/editor.css 9.91 kB
build/block-library/index.min.js 167 kB
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/style-rtl.css 11.3 kB
build/block-library/style.css 11.4 kB
build/block-library/theme-rtl.css 672 B
build/block-library/theme.css 676 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 46.4 kB
build/components/index.min.js 215 kB
build/components/style-rtl.css 15.5 kB
build/components/style.css 15.5 kB
build/compose/index.min.js 11.2 kB
build/core-data/index.min.js 13.9 kB
build/customize-widgets/index.min.js 11.4 kB
build/customize-widgets/style-rtl.css 1.49 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 663 B
build/data/index.min.js 7.48 kB
build/date/index.min.js 31.9 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.53 kB
build/edit-navigation/index.min.js 16.2 kB
build/edit-navigation/style-rtl.css 3.76 kB
build/edit-navigation/style.css 3.76 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 29.9 kB
build/edit-post/style-rtl.css 7.19 kB
build/edit-post/style.css 7.18 kB
build/edit-site/index.min.js 42.1 kB
build/edit-site/style-rtl.css 7.23 kB
build/edit-site/style.css 7.22 kB
build/edit-widgets/index.min.js 16.7 kB
build/edit-widgets/style-rtl.css 4.17 kB
build/edit-widgets/style.css 4.17 kB
build/editor/index.min.js 38.5 kB
build/editor/style-rtl.css 3.71 kB
build/editor/style.css 3.71 kB
build/element/index.min.js 3.32 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 6.62 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.83 kB
build/keycodes/index.min.js 1.41 kB
build/list-reusable-blocks/index.min.js 1.75 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.94 kB
build/notices/index.min.js 957 B
build/nux/index.min.js 2.12 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.98 kB
build/preferences/index.min.js 1.2 kB
build/primitives/index.min.js 949 B
build/priority-queue/index.min.js 611 B
build/react-i18n/index.min.js 704 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/index.min.js 2.24 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.1 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.52 kB
build/token-list/index.min.js 668 B
build/url/index.min.js 1.92 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.18 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.07 kB

compressed-size-action

@talldan talldan mentioned this pull request Feb 17, 2022
7 tasks
@gziolo
Copy link
Member

gziolo commented Feb 17, 2022

What's the rationale behind moving also React components into this package?

I can see how a customizable button component with a preference feature toggle wired would be useful to use in different places. The one proposed in this PR is tied to the More Menu on editor screens, so it's going to be harder to use with 3rd party projects or WordPress plugins. Maybe we should keep those components in @wordpress/interface for the time being to keep the number of dependencies in the package small?

}
```

## API Reference
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we take this opportunity to simplify further. What I have in mind could be something like:

  • drop the "feature" name (as it's a bit weird) and just call them preferences.
  • Basically the main selectors could be just get and set

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, the 'feature' thing doesn't really fit for a generic preferences package. I'll work on the naming. 👍

I think it might good to have a toggle too, most of the preferences are booleans, so it seems like a handy function to have.

On this subject, I've been wondering if we want any built-in type safety for these preferences. Or whether it should just be a freeform key/value store. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

On this subject, I've been wondering if we want any built-in type safety for these preferences. Or whether it should just be a freeform key/value store. What do you think?

If we go the type safety road, it almost feels like we should "register" preferences. I'm not sure it's worth the added complexity. I understand that if we don't do it from the start it might harder to do later. Any use-cases that benefits from the type safety?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any use-cases that benefits from the type safety?

There definitely aren't many in the editor, so I think you're right that it's not worth the complexity. The only one really is the Code Editor/Visual Editor option.

There is also the option of building more complex behavior around the existing actions and selectors. For example, if an editor needed a preference with some kind of validation, it could add that validation in its own action that calls through to dispatch( 'core/preferences' ).set.

} );

// Once we build a more generic persistence plugin that works across types of stores
// we'd be able to replace this with a register call.
Copy link
Contributor

Choose a reason for hiding this comment

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

It feels like a good opportunity to basically deprecated the persistence plugin and have its logic handled directly by the current package.

Copy link
Contributor

Choose a reason for hiding this comment

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

(not necessary for the first release of the package)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, that would be great. Just checked and it looks like there's one other usage in production - enableItems in the interface package.

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

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

Great initiative, we need such package :)

  • If I'm not wrong, this is not used yet, I'm curious to see how the migration of existing preferences would work.
  • I'm curious to see how we can adapt the package in the future to persist using an API (should this be something you can provide as an adapter or built-in in the package)

@talldan
Copy link
Contributor Author

talldan commented Feb 18, 2022

What's the rationale behind moving also React components into this package?

@gziolo Mostly for convenience, but they could also stay in the interface package. I hadn't really thought of that.

If I'm not wrong, this is not used yet, I'm curious to see how the migration of existing preferences would work.

@youknowriad There's another PR (https://github.com/WordPress/gutenberg/pull/38435/files#diff-3201447415d9f0cf361527ea43e669de47f38c3d8df5a848e86a3cdaf21fe057L234) that demonstrates the migration that can also be used for manual testing (and I'm also using it for the automated tests while developing). This PR is a subset of that one that only contains the preference store changes.


### Components

The `MoreMenuDropdown` and `MoreMenuPreferenceToggle` components help to implement an editor menu for changing preferences and feature values.
Copy link
Contributor

Choose a reason for hiding this comment

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

While I think MoreMenuPreferenceToggle makes sense in this package (probably better renamed as just PreferenceToggle), I have some trouble understanding the need of MoreMenuDropdown in the context of the preferences package.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it makes sense to have MoreMenuDropdown here because it ensures the dropdown classname, associated styles in packages/preferences/src/components/more-menu-dropdown/style.scss and button icon are all defined in one place, and don't have to be added to each package where preferences are used.

Copy link
Contributor

Choose a reason for hiding this comment

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

This sounds like sharing code just to share code and avoid duplication. In general, I feel like this might not always be the right argument for code sharing as it makes us create wrong abstractions. I'm fine with a sharable DropdownMenu but this one particularly sounds more suited for the "interface" package instead. It has nothing to do with "preferences".

Copy link
Contributor Author

@talldan talldan Feb 22, 2022

Choose a reason for hiding this comment

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

👍 Interface sounds like a good option. After all there's a bunch of options in this menu that are not related to preferences.

Some of the plugin extensibility that's loosely connected with the dropdown lives in interface, so that works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's all done now. I've renamed MoreMenuPreferenceToggle to PreferenceToggleMenuItem. It's a bit longer than the name suggested, but in future we may add another toggle component for the preferences modal.

Copy link
Contributor

@tellthemachines tellthemachines 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 promising! Just a couple minor comments below.

I notice in the demo PR the site editor isn't updated to use this package. Is that just because it isn't using the current common component in interface, or is there any other obstacle to migrating it?

Also, considering this question, would it make sense to bring the post editor PreferencesModal into this package too? We could at least leverage MoreMenuPreferenceToggle for some of its options.

@@ -0,0 +1,172 @@
# Preferences

Utilities for storing WordPress preferences.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be "editor" instead of "WordPress" preferences?

Copy link
Contributor

Choose a reason for hiding this comment

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

Why should we limit this to "editor"? That's for sure the main use-case for us but does it prevent us to make this package ready for any client-side rendered WP-Admin page?

Copy link
Contributor

Choose a reason for hiding this comment

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

Good point, but should we restrict it to WordPress? This package isn't inherently tied to WP, unless I'm missing something. It could potentially be used by non-WP block editors too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's true. It may depend on how the persistence functionality is implemented in the future, as at some point we'll want to persist settings to the database via the REST API rather than localstorage.

If that can be done in a way where it's configurable or separate to the package (which I think it probably should be), it would be fine to drop the 'WordPress' from this, but for now I don't think it's harmful.


### Components

The `MoreMenuDropdown` and `MoreMenuPreferenceToggle` components help to implement an editor menu for changing preferences and feature values.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it makes sense to have MoreMenuDropdown here because it ensures the dropdown classname, associated styles in packages/preferences/src/components/more-menu-dropdown/style.scss and button icon are all defined in one place, and don't have to be added to each package where preferences are used.

const { toggle } = useDispatch( preferencesStore );
const speakMessage = () => {
if ( isActive ) {
speak( messageDeactivated || __( 'Preference deactivated' ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the default message use the label string to give a bit more context, instead of just saying "Preference"? Otherwise we risk multiple preferences having the exact same message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. I've made that change in dfbdf41

@talldan talldan force-pushed the create/new-preferences-package branch from 8b15daa to 64ed509 Compare February 22, 2022 08:27
@talldan talldan force-pushed the create/new-preferences-package branch from d26afcc to dfbdf41 Compare February 22, 2022 09:12
@talldan
Copy link
Contributor Author

talldan commented Feb 22, 2022

I notice in the demo PR the site editor isn't updated to use this package. Is that just because it isn't using the current common component in interface, or is there any other obstacle to migrating it?

@tellthemachines The site editor isn't using the code that was previously added to interface so it will be different to the other editors. I'm keeping it separate right now, but it's still definitely something to do after this. The demo PR only includes the editors that are needed right now.

Also, considering #38317 (comment), would it make sense to bring the post editor PreferencesModal into this package too? We could at least leverage MoreMenuPreferenceToggle for some of its options.

It could, perhaps either here or interface. Unfortunately that won't be quick. I need to start again on #34195, that code is pretty outdated. It's also a huge change, so will definitely be a separate PR.

@talldan
Copy link
Contributor Author

talldan commented Feb 24, 2022

I think I've addressed all the feedback. Let me know if there's any more.

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

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

LGTM 👍

label={ __( 'My feature' ) }
info={ __( 'A really awesome feature' ) }
messageActivated={ __( 'My feature activated' ) }
messageDeactivated={ __( 'My feature deactivated' ) }
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is not new to this PR but in other components that needed configurable labels, we had a single object prop like messages in FormTokenField. Feels like something we'd need to normalize at some point.

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 can take a look at that in a follow-up. 👍

@ntsekouras
Copy link
Contributor

That is really nice! Great work @talldan 🚀

{
"name": "@wordpress/preferences",
"version": "1.0.0-prerelease",
"private": true,
Copy link
Member

Choose a reason for hiding this comment

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

Other public packages depend on this package so it shouldn't be private. See #39390.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] New API New API to be used by plugin developers or package users.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants