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

ui-utils: Add new package with two type checking functions #28028

Closed
wants to merge 4 commits into from

Conversation

sarayourfriend
Copy link
Contributor

@sarayourfriend sarayourfriend commented Jan 6, 2021

Description

This is part of #28020. It adds a new ui-utils package which will contain the various utilities useful for building user interfaces like the two functions included in this PR.

How has this been tested?

Build passes (these utilities are currently unused)

Types of changes

New feature/package.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • 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.

@github-actions
Copy link

github-actions bot commented Jan 6, 2021

Size Change: +4.29 kB (0%)

Total Size: 1.3 MB

Filename Size Change
build/annotations/index.js 3.8 kB -3 B (0%)
build/api-fetch/index.js 3.42 kB +1 B (0%)
build/autop/index.js 2.83 kB +1 B (0%)
build/blob/index.js 664 B -1 B (0%)
build/block-directory/index.js 9.04 kB +329 B (+4%)
build/block-editor/index.js 130 kB +1.55 kB (+1%)
build/block-library/index.js 151 kB +1.33 kB (+1%)
build/blocks/index.js 48 kB -28 B (0%)
build/components/index.js 172 kB +1.5 kB (+1%)
build/compose/index.js 11.2 kB +6 B (0%)
build/core-data/index.js 15.2 kB -6 B (0%)
build/data-controls/index.js 830 B +1 B (0%)
build/data/index.js 8.98 kB -5 B (0%)
build/date/index.js 31.8 kB +1 B (0%)
build/dom/index.js 4.95 kB -1 B (0%)
build/edit-navigation/index.js 11.1 kB +5 B (0%)
build/edit-post/index.js 306 kB -104 B (0%)
build/edit-site/index.js 24.4 kB -101 B (0%)
build/edit-widgets/index.js 26.1 kB -284 B (-1%)
build/editor/index.js 42.8 kB -10 B (0%)
build/element/index.js 4.62 kB -5 B (0%)
build/format-library/index.js 6.75 kB +2 B (0%)
build/hooks/index.js 2.27 kB -1 B (0%)
build/html-entities/index.js 623 B +1 B (0%)
build/i18n/index.js 3.57 kB -1 B (0%)
build/keyboard-shortcuts/index.js 2.54 kB +2 B (0%)
build/keycodes/index.js 1.94 kB +2 B (0%)
build/list-reusable-blocks/index.js 3.15 kB +35 B (+1%)
build/list-reusable-blocks/style-rtl.css 629 B +28 B (+5%) 🔍
build/list-reusable-blocks/style.css 628 B +27 B (+4%)
build/media-utils/index.js 5.31 kB +4 B (0%)
build/notices/index.js 1.86 kB -2 B (0%)
build/nux/index.js 3.43 kB +7 B (0%)
build/primitives/index.js 1.43 kB +1 B (0%)
build/priority-queue/index.js 790 B +1 B (0%)
build/redux-routine/index.js 2.84 kB +3 B (0%)
build/reusable-blocks/index.js 2.92 kB -2 B (0%)
build/rich-text/index.js 13.4 kB +2 B (0%)
build/server-side-render/index.js 2.77 kB +1 B (0%)
build/shortcode/index.js 1.7 kB -2 B (0%)
build/url/index.js 3.02 kB -1 B (0%)
build/viewport/index.js 1.86 kB +2 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.14 kB 0 B
build/block-directory/style-rtl.css 1.01 kB 0 B
build/block-directory/style.css 1.01 kB 0 B
build/block-editor/style-rtl.css 11.4 kB 0 B
build/block-editor/style.css 11.3 kB 0 B
build/block-library/blocks/archives/editor-rtl.css 196 B 0 B
build/block-library/blocks/archives/editor.css 196 B 0 B
build/block-library/blocks/audio/editor-rtl.css 194 B 0 B
build/block-library/blocks/audio/editor.css 194 B 0 B
build/block-library/blocks/audio/style-rtl.css 225 B 0 B
build/block-library/blocks/audio/style.css 225 B 0 B
build/block-library/blocks/block/editor-rtl.css 283 B 0 B
build/block-library/blocks/block/editor.css 283 B 0 B
build/block-library/blocks/button/editor-rtl.css 576 B 0 B
build/block-library/blocks/button/editor.css 577 B 0 B
build/block-library/blocks/button/style-rtl.css 552 B 0 B
build/block-library/blocks/button/style.css 552 B 0 B
build/block-library/blocks/buttons/editor-rtl.css 345 B 0 B
build/block-library/blocks/buttons/editor.css 346 B 0 B
build/block-library/blocks/buttons/style-rtl.css 419 B 0 B
build/block-library/blocks/buttons/style.css 419 B 0 B
build/block-library/blocks/calendar/style-rtl.css 319 B 0 B
build/block-library/blocks/calendar/style.css 319 B 0 B
build/block-library/blocks/categories/editor-rtl.css 210 B 0 B
build/block-library/blocks/categories/editor.css 209 B 0 B
build/block-library/blocks/categories/style-rtl.css 208 B 0 B
build/block-library/blocks/categories/style.css 208 B 0 B
build/block-library/blocks/code/style-rtl.css 216 B 0 B
build/block-library/blocks/code/style.css 216 B 0 B
build/block-library/blocks/columns/editor-rtl.css 300 B 0 B
build/block-library/blocks/columns/editor.css 299 B 0 B
build/block-library/blocks/columns/style-rtl.css 529 B 0 B
build/block-library/blocks/columns/style.css 528 B 0 B
build/block-library/blocks/cover/editor-rtl.css 508 B 0 B
build/block-library/blocks/cover/editor.css 506 B 0 B
build/block-library/blocks/cover/style-rtl.css 1.33 kB 0 B
build/block-library/blocks/cover/style.css 1.32 kB 0 B
build/block-library/blocks/embed/editor-rtl.css 594 B 0 B
build/block-library/blocks/embed/editor.css 595 B 0 B
build/block-library/blocks/embed/style-rtl.css 489 B 0 B
build/block-library/blocks/embed/style.css 489 B 0 B
build/block-library/blocks/file/editor-rtl.css 314 B 0 B
build/block-library/blocks/file/editor.css 313 B 0 B
build/block-library/blocks/file/style-rtl.css 352 B 0 B
build/block-library/blocks/file/style.css 352 B 0 B
build/block-library/blocks/freeform/editor-rtl.css 2.55 kB 0 B
build/block-library/blocks/freeform/editor.css 2.55 kB 0 B
build/block-library/blocks/gallery/editor-rtl.css 749 B 0 B
build/block-library/blocks/gallery/editor.css 750 B 0 B
build/block-library/blocks/gallery/style-rtl.css 1.17 kB 0 B
build/block-library/blocks/gallery/style.css 1.17 kB 0 B
build/block-library/blocks/group/editor-rtl.css 433 B 0 B
build/block-library/blocks/group/editor.css 432 B 0 B
build/block-library/blocks/group/style-rtl.css 190 B 0 B
build/block-library/blocks/group/style.css 190 B 0 B
build/block-library/blocks/heading/editor-rtl.css 248 B 0 B
build/block-library/blocks/heading/editor.css 248 B 0 B
build/block-library/blocks/heading/style-rtl.css 212 B 0 B
build/block-library/blocks/heading/style.css 212 B 0 B
build/block-library/blocks/html/editor-rtl.css 384 B 0 B
build/block-library/blocks/html/editor.css 385 B 0 B
build/block-library/blocks/image/editor-rtl.css 801 B 0 B
build/block-library/blocks/image/editor.css 800 B 0 B
build/block-library/blocks/image/style-rtl.css 569 B 0 B
build/block-library/blocks/image/style.css 570 B 0 B
build/block-library/blocks/latest-comments/editor-rtl.css 277 B 0 B
build/block-library/blocks/latest-comments/editor.css 275 B 0 B
build/block-library/blocks/latest-comments/style-rtl.css 382 B 0 B
build/block-library/blocks/latest-comments/style.css 382 B 0 B
build/block-library/blocks/latest-posts/editor-rtl.css 254 B 0 B
build/block-library/blocks/latest-posts/editor.css 254 B 0 B
build/block-library/blocks/latest-posts/style-rtl.css 634 B 0 B
build/block-library/blocks/latest-posts/style.css 634 B 0 B
build/block-library/blocks/list/editor-rtl.css 203 B 0 B
build/block-library/blocks/list/editor.css 203 B 0 B
build/block-library/blocks/list/style-rtl.css 201 B 0 B
build/block-library/blocks/list/style.css 201 B 0 B
build/block-library/blocks/media-text/editor-rtl.css 311 B 0 B
build/block-library/blocks/media-text/editor.css 311 B 0 B
build/block-library/blocks/media-text/style-rtl.css 642 B 0 B
build/block-library/blocks/media-text/style.css 640 B 0 B
build/block-library/blocks/more/editor-rtl.css 545 B 0 B
build/block-library/blocks/more/editor.css 545 B 0 B
build/block-library/blocks/navigation-link/editor-rtl.css 503 B 0 B
build/block-library/blocks/navigation-link/editor.css 504 B 0 B
build/block-library/blocks/navigation-link/style-rtl.css 805 B 0 B
build/block-library/blocks/navigation-link/style.css 803 B 0 B
build/block-library/blocks/navigation/editor-rtl.css 1.38 kB 0 B
build/block-library/blocks/navigation/editor.css 1.38 kB 0 B
build/block-library/blocks/navigation/style-rtl.css 274 B 0 B
build/block-library/blocks/navigation/style.css 274 B 0 B
build/block-library/blocks/nextpage/editor-rtl.css 507 B 0 B
build/block-library/blocks/nextpage/editor.css 507 B 0 B
build/block-library/blocks/paragraph/editor-rtl.css 236 B 0 B
build/block-library/blocks/paragraph/editor.css 236 B 0 B
build/block-library/blocks/paragraph/style-rtl.css 351 B 0 B
build/block-library/blocks/paragraph/style.css 352 B 0 B
build/block-library/blocks/post-author/editor-rtl.css 329 B 0 B
build/block-library/blocks/post-author/editor.css 329 B 0 B
build/block-library/blocks/post-author/style-rtl.css 303 B 0 B
build/block-library/blocks/post-author/style.css 303 B 0 B
build/block-library/blocks/post-comments-form/style-rtl.css 358 B 0 B
build/block-library/blocks/post-comments-form/style.css 358 B 0 B
build/block-library/blocks/post-content/editor-rtl.css 262 B 0 B
build/block-library/blocks/post-content/editor.css 262 B 0 B
build/block-library/blocks/post-excerpt/editor-rtl.css 206 B 0 B
build/block-library/blocks/post-excerpt/editor.css 206 B 0 B
build/block-library/blocks/post-featured-image/editor-rtl.css 453 B 0 B
build/block-library/blocks/post-featured-image/editor.css 453 B 0 B
build/block-library/blocks/post-featured-image/style-rtl.css 223 B 0 B
build/block-library/blocks/post-featured-image/style.css 223 B 0 B
build/block-library/blocks/preformatted/style-rtl.css 193 B 0 B
build/block-library/blocks/preformatted/style.css 193 B 0 B
build/block-library/blocks/pullquote/editor-rtl.css 304 B 0 B
build/block-library/blocks/pullquote/editor.css 304 B 0 B
build/block-library/blocks/pullquote/style-rtl.css 428 B 0 B
build/block-library/blocks/pullquote/style.css 428 B 0 B
build/block-library/blocks/query-loop/editor-rtl.css 217 B 0 B
build/block-library/blocks/query-loop/editor.css 216 B 0 B
build/block-library/blocks/query-loop/style-rtl.css 427 B 0 B
build/block-library/blocks/query-loop/style.css 429 B 0 B
build/block-library/blocks/query/editor-rtl.css 279 B 0 B
build/block-library/blocks/query/editor.css 279 B 0 B
build/block-library/blocks/quote/editor-rtl.css 195 B 0 B
build/block-library/blocks/quote/editor.css 195 B 0 B
build/block-library/blocks/quote/style-rtl.css 284 B 0 B
build/block-library/blocks/quote/style.css 285 B 0 B
build/block-library/blocks/rss/editor-rtl.css 307 B 0 B
build/block-library/blocks/rss/editor.css 309 B 0 B
build/block-library/blocks/rss/style-rtl.css 394 B 0 B
build/block-library/blocks/rss/style.css 393 B 0 B
build/block-library/blocks/search/editor-rtl.css 285 B 0 B
build/block-library/blocks/search/editor.css 285 B 0 B
build/block-library/blocks/search/style-rtl.css 454 B 0 B
build/block-library/blocks/search/style.css 456 B 0 B
build/block-library/blocks/separator/editor-rtl.css 229 B 0 B
build/block-library/blocks/separator/editor.css 229 B 0 B
build/block-library/blocks/separator/style-rtl.css 352 B 0 B
build/block-library/blocks/separator/style.css 352 B 0 B
build/block-library/blocks/shortcode/editor-rtl.css 603 B 0 B
build/block-library/blocks/shortcode/editor.css 603 B 0 B
build/block-library/blocks/site-logo/editor-rtl.css 321 B 0 B
build/block-library/blocks/site-logo/editor.css 321 B 0 B
build/block-library/blocks/site-logo/style-rtl.css 238 B 0 B
build/block-library/blocks/site-logo/style.css 238 B 0 B
build/block-library/blocks/social-link/editor-rtl.css 283 B 0 B
build/block-library/blocks/social-link/editor.css 283 B 0 B
build/block-library/blocks/social-links/editor-rtl.css 811 B 0 B
build/block-library/blocks/social-links/editor.css 810 B 0 B
build/block-library/blocks/social-links/style-rtl.css 1.44 kB 0 B
build/block-library/blocks/social-links/style.css 1.44 kB 0 B
build/block-library/blocks/spacer/editor-rtl.css 390 B 0 B
build/block-library/blocks/spacer/editor.css 390 B 0 B
build/block-library/blocks/spacer/style-rtl.css 184 B 0 B
build/block-library/blocks/spacer/style.css 184 B 0 B
build/block-library/blocks/subhead/editor-rtl.css 223 B 0 B
build/block-library/blocks/subhead/editor.css 223 B 0 B
build/block-library/blocks/subhead/style-rtl.css 210 B 0 B
build/block-library/blocks/subhead/style.css 210 B 0 B
build/block-library/blocks/table/editor-rtl.css 593 B 0 B
build/block-library/blocks/table/editor.css 593 B 0 B
build/block-library/blocks/table/style-rtl.css 501 B 0 B
build/block-library/blocks/table/style.css 501 B 0 B
build/block-library/blocks/tag-cloud/editor-rtl.css 237 B 0 B
build/block-library/blocks/tag-cloud/editor.css 235 B 0 B
build/block-library/blocks/tag-cloud/style-rtl.css 221 B 0 B
build/block-library/blocks/tag-cloud/style.css 221 B 0 B
build/block-library/blocks/template-part/editor-rtl.css 714 B 0 B
build/block-library/blocks/template-part/editor.css 714 B 0 B
build/block-library/blocks/text-columns/editor-rtl.css 220 B 0 B
build/block-library/blocks/text-columns/editor.css 220 B 0 B
build/block-library/blocks/text-columns/style-rtl.css 283 B 0 B
build/block-library/blocks/text-columns/style.css 283 B 0 B
build/block-library/blocks/verse/editor-rtl.css 194 B 0 B
build/block-library/blocks/verse/editor.css 194 B 0 B
build/block-library/blocks/verse/style-rtl.css 214 B 0 B
build/block-library/blocks/verse/style.css 214 B 0 B
build/block-library/blocks/video/editor-rtl.css 617 B 0 B
build/block-library/blocks/video/editor.css 617 B 0 B
build/block-library/blocks/video/style-rtl.css 303 B 0 B
build/block-library/blocks/video/style.css 304 B 0 B
build/block-library/common-rtl.css 1.01 kB 0 B
build/block-library/common.css 1.01 kB 0 B
build/block-library/editor-rtl.css 8.93 kB 0 B
build/block-library/editor.css 8.93 kB 0 B
build/block-library/style-rtl.css 8.53 kB 0 B
build/block-library/style.css 8.53 kB 0 B
build/block-library/theme-rtl.css 860 B 0 B
build/block-library/theme.css 860 B 0 B
build/block-serialization-default-parser/index.js 1.88 kB 0 B
build/block-serialization-spec-parser/index.js 3.06 kB 0 B
build/components/style-rtl.css 15.5 kB 0 B
build/components/style.css 15.5 kB 0 B
build/deprecated/index.js 768 B 0 B
build/dom-ready/index.js 571 B 0 B
build/edit-navigation/style-rtl.css 938 B 0 B
build/edit-navigation/style.css 944 B 0 B
build/edit-post/style-rtl.css 6.64 kB 0 B
build/edit-post/style.css 6.63 kB 0 B
build/edit-site/style-rtl.css 4.04 kB 0 B
build/edit-site/style.css 4.04 kB 0 B
build/edit-widgets/style-rtl.css 3.22 kB 0 B
build/edit-widgets/style.css 3.22 kB 0 B
build/editor/editor-styles-rtl.css 476 B 0 B
build/editor/editor-styles.css 478 B 0 B
build/editor/style-rtl.css 3.89 kB 0 B
build/editor/style.css 3.89 kB 0 B
build/escape-html/index.js 735 B 0 B
build/format-library/style-rtl.css 620 B 0 B
build/format-library/style.css 621 B 0 B
build/is-shallow-equal/index.js 698 B 0 B
build/nux/style-rtl.css 731 B 0 B
build/nux/style.css 727 B 0 B
build/plugins/index.js 2.54 kB 0 B
build/token-list/index.js 1.27 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.22 kB 0 B

compressed-size-action

@ItsJonQ
Copy link

ItsJonQ commented Jan 6, 2021

@saramarcondes Thank you for working on this 🙏 !

I checked out the failing tests.

The Static Analysis one is reporting:

[1] /home/runner/work/gutenberg/gutenberg/packages/interface/src/components/interface-skeleton/index.js
[1]   75:4  error  Deprecated functions must be removed before releasing this version  no-restricted-syntax

I'm not sure if your change is related.

I'm seeing common E2E Admin 4 failures across recent commits:
https://github.com/WordPress/gutenberg/commits/master

@sarayourfriend
Copy link
Contributor Author

@ItsJonQ That's a common failure that is being addressed in this issue: #28027

@ItsJonQ
Copy link

ItsJonQ commented Jan 6, 2021

The compose package looks like it's for custom hooks and HOCs. I'm not sure if is should go there (agreed with your PR description)

My initial PR attempt added is to a new @wordpress/ui-utils package.
I think that ui-* (or something similar) would be a good namespace for the other packages from the new Component System.

🤗

Update: Linking to my original PR, just in case it helps:
#27486

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

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

@wordpress/compose contains higher-order components (now considered legacy) and React hooks to reuse with React components. I don't think that those utils are good fit here.

In general, all those utils are so simple or re-exported from lodash that we could as well inline them as we need them. Many of them can be also replace with a simple check like:

x === null;
y typeof Number;
z === undefined;

In general, we aim to stop using lodash at scale as discussed in #17025. It's quite a challenge to refactor old code but if it could be avoided for new code then it would be fantastic.

@gziolo gziolo added the [Feature] Component System WordPress component system label Jan 7, 2021
@sarayourfriend
Copy link
Contributor Author

I don't think that those utils are good fit here.

I agree, I just wasn't sure where to put it 😅

However it sounds like the preferrence is not to add this at all, in the first place.

Personally I think that's fine, opting for hand written type checks accomplishes much of the same thing as these functions. There are, however, a couple that are particularly useful for G2. is.defined and is.objectInterpolation get used specifically in ways that are cumbersome to write out manually. Are you (@gziolo) okay with paring down these declarations to just these two and moving them into a ui-utils package which would contain a number of other UI utility functions outlined in the issue linked above? The rest could then be inlined as you suggested, avoiding lodash altogether.

@gziolo
Copy link
Member

gziolo commented Jan 7, 2021

Are you okay with paring down these declarations to just these two and moving them into a ui-utils package which would contain a number of other UI utility functions outlined in the issue linked above?

If it isn't possible to keep them internal to @wordpress/components then a new package sounds good for this more complex logic.

The reality of having another package is a bit different in the WordPress world than in web apps that have a single entry point and use code splitting. Here we will create another entry point that is also exposed as wp.uiUtils global in the browser. It means that its API can't be never fully removed because it can break websites 😃

@sarayourfriend
Copy link
Contributor Author

If it isn't possible to keep them internal to @wordpress/components then a new package sounds good for this more complex logic.

Unfortunately they're used in multiple different packages like create-styles, styles, context and components.

I'll update this PR with the pared down version.

@gziolo
Copy link
Member

gziolo commented Jan 7, 2021

I think that @youknowriad found some way to keep packages public on npm and hide them from exposing in WordPress globals. He would be the best person to recommend how to move forward.

@sarayourfriend sarayourfriend changed the title Compose: Add is util ui-utils: Add new package with two type checking functions Jan 7, 2021
@sarayourfriend
Copy link
Contributor Author

@gziolo None of the G2 packages should probably be exposed in the global object at all (at least not for a long time, if not never) so if we can figure that out for this package it would be a boon for future packages like context, create-styles and styles.

Copy link

@ItsJonQ ItsJonQ left a comment

Choose a reason for hiding this comment

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

The new utils and package are a 👍 from me! Thank you so much @saramarcondes !!

As @gziolo has mentioned, hopefully we'll be able hide them from the global WP object 🙏

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.

It seems to me all these functions already exist in lodash, not sure we should be adding a new package for that

@@ -1817,6 +1817,12 @@
"markdown_source": "../packages/token-list/README.md",
"parent": "packages"
},
{
"title": "@wordpress/ui-utils",
Copy link
Contributor

Choose a reason for hiding this comment

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

ui-utils as a name doesn't make sense for me. These utilities can be useful for any code. Why not @wordpress/is

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess this comment doesn't make sense if we decide to drop the package.

Copy link

Choose a reason for hiding this comment

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

ui-utils as a name doesn't make sense for me.

The reason for this PR and for this package is to provide a space for us to migrate the other utilities found in the G2 Component system:

https://github.com/ItsJonQ/g2/tree/master/packages/utils/src

Why not @wordpress/is

I'm happy renaming it to @wordpress/utils package if that were the case.

Copy link
Contributor

Choose a reason for hiding this comment

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

We used to have a @wordpress/utils a long time ago and we removed it in favor of smaller packages with clear purpose. A @wordpress/is would have been a good one here but IMO, lodash offers already all of these functions and since lodash is already used across our codebase, I'd just continue using it instead of replacing it with our custom lodash.

* @param {T | undefined | null} value The value to check.
* @return {value is T} Whether the value is undefined.
*/
const isDefined = ( value ) => value !== null && value !== undefined;
Copy link
Contributor

Choose a reason for hiding this comment

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

This already exists in lodash isNil

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, but if we'd like to remove lodash at scale, as described by #17025, we'd need to replace this utility (it's a quite useful one, if you search through G2 for is.defined you'll see it's used almost everywhere).

We could replace it with ! isNil but that doesn't accomplish getting rid of lodash at all.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I agree with "getting rid of lodash by adding our own utils". I think getting rid of lodash by using native functions is definitely a good thing but other than that:

  • Lodash can be replaced with lodash-es for npm consumers
  • Lodash is only loaded once in WordPress, it's better that bundling the same utils multiple times.

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 to me. We'll replace is.defined with ! isNil everywhere then?

* @param {TemplateStringsArray | import('create-emotion').Interpolation} value The value to check.
* @return {value is import('create-emotion').ObjectInterpolation} Whether the value is an ObjectInterpolation.
*/
const isObjectInterpolation = ( value ) => isPlainObject( value );
Copy link
Contributor

Choose a reason for hiding this comment

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

why not just use isPlainObject directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The usefulness of this function comes primarily from the type defintions. It's impossible to refine the type any other way other than through type definitions which TypeScript will trust implicitly. This allows the newly added packages to be fully and completely typed.

For example, given the following (real) code example:

/**
 * @param {TemplateStringsArray | import('create-emotion').Interpolation<undefined>} template
 * @param {import('create-emotion').Interpolation<undefined>[]} args The styles to compile.
 * @returns {ReturnType<compile>} The compiled styles.
 */
export function css(template, ...args) {
	if (isObjectInterpolation(template)) {
		return compile(responsive(template));
	}

	if (Array.isArray(template)) { // => TemplateStringsArray
		for (let i = 0, len = template.length; i < len; i++) {
			const n = template[i];
			if (isObjectInterpolation(n)) {
				template[i] = responsive(n);
			}
		}
		return compile(template, ...args);
	}

	return compile(template, ...args);
}

If you replace isObjectInterpolation with isPlainObject and responsive's first argument will not be refined enough to be accepted as responsive only accepts an ObjectInterpolation for it's first argument.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it's a valid reason for us at least to add a new package to be honest. Can't this be solved by an explicit type cast instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, this package isn't complete as it stands, so it's justification can't live on just these two utilities. The issue linked in the PR description has a short list of utilities that would live in this package (and those are just the ones used by the Text and Truncate components, there are many more if you check out the G2 repo).

FWIW I hadn't tried to type cast it but it does work, so we can remove this utility if you'd prefer to just use type casts (that's all this function does anyhow).

Regardless, I'll open a separate PR with a different utility adding the same ui-utils package for getOptimalTextShade, getDisplayName, and getComputedColor as the issue linked in the PR describes. This was just meant as an incremental way of doing it without moving more code at one time than is possible for a person to effectively review.

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 adding packages shouldn't be seen as something we should do easily especially in the context of WordPress, so I'd personally feel better if we start by doing inline utilities in the "components" package and discuss whether it deserves a separate package or not as the usage grows.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What about utilities used by mulitple packages like getDisplayName? Where should that live? We can't introduce them in components as that would create a circular dependency. We can duplicate the code in the packages if you'd prefer that. Or we can export them from an unrelated package, but then that package will be responsible for something that it shouldn't care about.

Copy link
Contributor

Choose a reason for hiding this comment

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

What does getDisplayName do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/**
 * Gets the displayName of a React Component or element.
 *
 * @param {string | import('react').ComponentType} tagName
 *
 * @return {string} The display name of the Component / tagName.
 */
export function getDisplayName(tagName) {
	const displayName =
		typeof tagName === 'string'
			? tagName
			: tagName.displayName || tagName.name || 'Component';

	return displayName;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

So looking a g2. It seems to be only used once. That said it seems to be used to compute components display name? In fact we have something close to it in createHigherOrderComponent in @wordpress/compose so it does seem like a natural place for it if its usage grows.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, you're right, I thought context used it as well but I was wrong. We'll inline that one too I guess.

@sarayourfriend sarayourfriend deleted the add/is-util branch January 8, 2021 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Component System WordPress component system
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants