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

compose: Add types to useRefEffect and clipboard hooks #31603

Merged
merged 7 commits into from
May 27, 2021

Conversation

sarayourfriend
Copy link
Contributor

@sarayourfriend sarayourfriend commented May 7, 2021

Description

Adds types to the useRefEffect, useCopyOnClick and useCopyToClipboard hooks.

Only minimal runtime changes were necessary, but some are kind of scary so we'll want to make sure to test this correctly.

How has this been tested?

Go to the block settings dropdown menu and ensure that copying the menu items works.

Screenshots

Captura de Tela 2021-05-07 às 07 17 00

Types of changes

New feature (types!)

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).

@sarayourfriend sarayourfriend added [Type] Code Quality Issues or PRs that relate to code quality [Package] Compose /packages/compose labels May 7, 2021
@sarayourfriend sarayourfriend self-assigned this May 7, 2021
@sarayourfriend sarayourfriend marked this pull request as ready for review May 7, 2021 14:16
@sarayourfriend sarayourfriend requested a review from ajitbohra as a code owner May 7, 2021 14:16
@github-actions
Copy link

github-actions bot commented May 7, 2021

Size Change: +5 B (0%)

Total Size: 1.86 MB

Filename Size Change
build/compose/index.js 10 kB +5 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.12 kB 0 B
build/annotations/index.js 2.93 kB 0 B
build/api-fetch/index.js 2.42 kB 0 B
build/autop/index.js 2.28 kB 0 B
build/blob/index.js 673 B 0 B
build/block-directory/index.js 6.62 kB 0 B
build/block-directory/style-rtl.css 989 B 0 B
build/block-directory/style.css 990 B 0 B
build/block-editor/index.js 118 kB 0 B
build/block-editor/style-rtl.css 12.9 kB 0 B
build/block-editor/style.css 12.9 kB 0 B
build/block-library/blocks/archives/editor-rtl.css 61 B 0 B
build/block-library/blocks/archives/editor.css 60 B 0 B
build/block-library/blocks/archives/style-rtl.css 65 B 0 B
build/block-library/blocks/archives/style.css 65 B 0 B
build/block-library/blocks/audio/editor-rtl.css 58 B 0 B
build/block-library/blocks/audio/editor.css 58 B 0 B
build/block-library/blocks/audio/style-rtl.css 112 B 0 B
build/block-library/blocks/audio/style.css 112 B 0 B
build/block-library/blocks/block/editor-rtl.css 161 B 0 B
build/block-library/blocks/block/editor.css 161 B 0 B
build/block-library/blocks/button/editor-rtl.css 475 B 0 B
build/block-library/blocks/button/editor.css 474 B 0 B
build/block-library/blocks/button/style-rtl.css 603 B 0 B
build/block-library/blocks/button/style.css 602 B 0 B
build/block-library/blocks/buttons/editor-rtl.css 315 B 0 B
build/block-library/blocks/buttons/editor.css 315 B 0 B
build/block-library/blocks/buttons/style-rtl.css 375 B 0 B
build/block-library/blocks/buttons/style.css 375 B 0 B
build/block-library/blocks/calendar/style-rtl.css 208 B 0 B
build/block-library/blocks/calendar/style.css 208 B 0 B
build/block-library/blocks/categories/editor-rtl.css 84 B 0 B
build/block-library/blocks/categories/editor.css 83 B 0 B
build/block-library/blocks/categories/style-rtl.css 79 B 0 B
build/block-library/blocks/categories/style.css 79 B 0 B
build/block-library/blocks/code/style-rtl.css 90 B 0 B
build/block-library/blocks/code/style.css 90 B 0 B
build/block-library/blocks/columns/editor-rtl.css 190 B 0 B
build/block-library/blocks/columns/editor.css 190 B 0 B
build/block-library/blocks/columns/style-rtl.css 422 B 0 B
build/block-library/blocks/columns/style.css 422 B 0 B
build/block-library/blocks/cover/editor-rtl.css 644 B 0 B
build/block-library/blocks/cover/editor.css 646 B 0 B
build/block-library/blocks/cover/style-rtl.css 1.22 kB 0 B
build/block-library/blocks/cover/style.css 1.23 kB 0 B
build/block-library/blocks/embed/editor-rtl.css 486 B 0 B
build/block-library/blocks/embed/editor.css 486 B 0 B
build/block-library/blocks/embed/style-rtl.css 401 B 0 B
build/block-library/blocks/embed/style.css 400 B 0 B
build/block-library/blocks/file/editor-rtl.css 301 B 0 B
build/block-library/blocks/file/editor.css 300 B 0 B
build/block-library/blocks/file/frontend.js 771 B 0 B
build/block-library/blocks/file/style-rtl.css 255 B 0 B
build/block-library/blocks/file/style.css 255 B 0 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB 0 B
build/block-library/blocks/freeform/editor.css 2.44 kB 0 B
build/block-library/blocks/gallery/editor-rtl.css 704 B 0 B
build/block-library/blocks/gallery/editor.css 705 B 0 B
build/block-library/blocks/gallery/style-rtl.css 1.06 kB 0 B
build/block-library/blocks/gallery/style.css 1.06 kB 0 B
build/block-library/blocks/group/editor-rtl.css 160 B 0 B
build/block-library/blocks/group/editor.css 160 B 0 B
build/block-library/blocks/group/style-rtl.css 57 B 0 B
build/block-library/blocks/group/style.css 57 B 0 B
build/block-library/blocks/heading/editor-rtl.css 129 B 0 B
build/block-library/blocks/heading/editor.css 129 B 0 B
build/block-library/blocks/heading/style-rtl.css 76 B 0 B
build/block-library/blocks/heading/style.css 76 B 0 B
build/block-library/blocks/home-link/style-rtl.css 259 B 0 B
build/block-library/blocks/home-link/style.css 259 B 0 B
build/block-library/blocks/html/editor-rtl.css 281 B 0 B
build/block-library/blocks/html/editor.css 281 B 0 B
build/block-library/blocks/image/editor-rtl.css 717 B 0 B
build/block-library/blocks/image/editor.css 716 B 0 B
build/block-library/blocks/image/style-rtl.css 481 B 0 B
build/block-library/blocks/image/style.css 485 B 0 B
build/block-library/blocks/latest-comments/style-rtl.css 281 B 0 B
build/block-library/blocks/latest-comments/style.css 282 B 0 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B 0 B
build/block-library/blocks/latest-posts/editor.css 137 B 0 B
build/block-library/blocks/latest-posts/style-rtl.css 529 B 0 B
build/block-library/blocks/latest-posts/style.css 529 B 0 B
build/block-library/blocks/legacy-widget/editor-rtl.css 557 B 0 B
build/block-library/blocks/legacy-widget/editor.css 557 B 0 B
build/block-library/blocks/list/style-rtl.css 63 B 0 B
build/block-library/blocks/list/style.css 63 B 0 B
build/block-library/blocks/media-text/editor-rtl.css 176 B 0 B
build/block-library/blocks/media-text/editor.css 176 B 0 B
build/block-library/blocks/media-text/style-rtl.css 492 B 0 B
build/block-library/blocks/media-text/style.css 489 B 0 B
build/block-library/blocks/more/editor-rtl.css 434 B 0 B
build/block-library/blocks/more/editor.css 434 B 0 B
build/block-library/blocks/navigation-link/editor-rtl.css 633 B 0 B
build/block-library/blocks/navigation-link/editor.css 634 B 0 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B 0 B
build/block-library/blocks/navigation-link/style.css 94 B 0 B
build/block-library/blocks/navigation/editor-rtl.css 1.54 kB 0 B
build/block-library/blocks/navigation/editor.css 1.54 kB 0 B
build/block-library/blocks/navigation/frontend.js 2.85 kB 0 B
build/block-library/blocks/navigation/style-rtl.css 1.8 kB 0 B
build/block-library/blocks/navigation/style.css 1.8 kB 0 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B 0 B
build/block-library/blocks/nextpage/editor.css 395 B 0 B
build/block-library/blocks/page-list/editor-rtl.css 310 B 0 B
build/block-library/blocks/page-list/editor.css 311 B 0 B
build/block-library/blocks/page-list/style-rtl.css 233 B 0 B
build/block-library/blocks/page-list/style.css 233 B 0 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B 0 B
build/block-library/blocks/paragraph/editor.css 157 B 0 B
build/block-library/blocks/paragraph/style-rtl.css 247 B 0 B
build/block-library/blocks/paragraph/style.css 248 B 0 B
build/block-library/blocks/post-author/editor-rtl.css 209 B 0 B
build/block-library/blocks/post-author/editor.css 209 B 0 B
build/block-library/blocks/post-author/style-rtl.css 183 B 0 B
build/block-library/blocks/post-author/style.css 184 B 0 B
build/block-library/blocks/post-comments-form/style-rtl.css 140 B 0 B
build/block-library/blocks/post-comments-form/style.css 140 B 0 B
build/block-library/blocks/post-comments/style-rtl.css 360 B 0 B
build/block-library/blocks/post-comments/style.css 359 B 0 B
build/block-library/blocks/post-content/editor-rtl.css 139 B 0 B
build/block-library/blocks/post-content/editor.css 139 B 0 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B 0 B
build/block-library/blocks/post-excerpt/editor.css 73 B 0 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B 0 B
build/block-library/blocks/post-excerpt/style.css 69 B 0 B
build/block-library/blocks/post-featured-image/editor-rtl.css 338 B 0 B
build/block-library/blocks/post-featured-image/editor.css 338 B 0 B
build/block-library/blocks/post-featured-image/style-rtl.css 141 B 0 B
build/block-library/blocks/post-featured-image/style.css 141 B 0 B
build/block-library/blocks/post-title/style-rtl.css 60 B 0 B
build/block-library/blocks/post-title/style.css 60 B 0 B
build/block-library/blocks/preformatted/style-rtl.css 103 B 0 B
build/block-library/blocks/preformatted/style.css 103 B 0 B
build/block-library/blocks/pullquote/editor-rtl.css 183 B 0 B
build/block-library/blocks/pullquote/editor.css 183 B 0 B
build/block-library/blocks/pullquote/style-rtl.css 318 B 0 B
build/block-library/blocks/pullquote/style.css 318 B 0 B
build/block-library/blocks/query-loop/editor-rtl.css 98 B 0 B
build/block-library/blocks/query-loop/editor.css 97 B 0 B
build/block-library/blocks/query-loop/style-rtl.css 315 B 0 B
build/block-library/blocks/query-loop/style.css 317 B 0 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B 0 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B 0 B
build/block-library/blocks/query-pagination/editor-rtl.css 270 B 0 B
build/block-library/blocks/query-pagination/editor.css 262 B 0 B
build/block-library/blocks/query-pagination/style-rtl.css 168 B 0 B
build/block-library/blocks/query-pagination/style.css 168 B 0 B
build/block-library/blocks/query-title/editor-rtl.css 86 B 0 B
build/block-library/blocks/query-title/editor.css 86 B 0 B
build/block-library/blocks/query/editor-rtl.css 131 B 0 B
build/block-library/blocks/query/editor.css 132 B 0 B
build/block-library/blocks/quote/style-rtl.css 169 B 0 B
build/block-library/blocks/quote/style.css 169 B 0 B
build/block-library/blocks/rss/editor-rtl.css 201 B 0 B
build/block-library/blocks/rss/editor.css 202 B 0 B
build/block-library/blocks/rss/style-rtl.css 290 B 0 B
build/block-library/blocks/rss/style.css 290 B 0 B
build/block-library/blocks/search/editor-rtl.css 189 B 0 B
build/block-library/blocks/search/editor.css 189 B 0 B
build/block-library/blocks/search/style-rtl.css 359 B 0 B
build/block-library/blocks/search/style.css 362 B 0 B
build/block-library/blocks/separator/editor-rtl.css 99 B 0 B
build/block-library/blocks/separator/editor.css 99 B 0 B
build/block-library/blocks/separator/style-rtl.css 251 B 0 B
build/block-library/blocks/separator/style.css 251 B 0 B
build/block-library/blocks/shortcode/editor-rtl.css 512 B 0 B
build/block-library/blocks/shortcode/editor.css 512 B 0 B
build/block-library/blocks/site-logo/editor-rtl.css 440 B 0 B
build/block-library/blocks/site-logo/editor.css 441 B 0 B
build/block-library/blocks/site-logo/style-rtl.css 154 B 0 B
build/block-library/blocks/site-logo/style.css 154 B 0 B
build/block-library/blocks/social-link/editor-rtl.css 164 B 0 B
build/block-library/blocks/social-link/editor.css 165 B 0 B
build/block-library/blocks/social-links/editor-rtl.css 800 B 0 B
build/block-library/blocks/social-links/editor.css 799 B 0 B
build/block-library/blocks/social-links/style-rtl.css 1.32 kB 0 B
build/block-library/blocks/social-links/style.css 1.33 kB 0 B
build/block-library/blocks/spacer/editor-rtl.css 308 B 0 B
build/block-library/blocks/spacer/editor.css 308 B 0 B
build/block-library/blocks/spacer/style-rtl.css 48 B 0 B
build/block-library/blocks/spacer/style.css 48 B 0 B
build/block-library/blocks/table/editor-rtl.css 478 B 0 B
build/block-library/blocks/table/editor.css 478 B 0 B
build/block-library/blocks/table/style-rtl.css 480 B 0 B
build/block-library/blocks/table/style.css 480 B 0 B
build/block-library/blocks/tag-cloud/editor-rtl.css 118 B 0 B
build/block-library/blocks/tag-cloud/editor.css 118 B 0 B
build/block-library/blocks/tag-cloud/style-rtl.css 94 B 0 B
build/block-library/blocks/tag-cloud/style.css 94 B 0 B
build/block-library/blocks/template-part/editor-rtl.css 551 B 0 B
build/block-library/blocks/template-part/editor.css 550 B 0 B
build/block-library/blocks/term-description/editor-rtl.css 90 B 0 B
build/block-library/blocks/term-description/editor.css 90 B 0 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B 0 B
build/block-library/blocks/text-columns/editor.css 95 B 0 B
build/block-library/blocks/text-columns/style-rtl.css 166 B 0 B
build/block-library/blocks/text-columns/style.css 166 B 0 B
build/block-library/blocks/verse/style-rtl.css 87 B 0 B
build/block-library/blocks/verse/style.css 87 B 0 B
build/block-library/blocks/video/editor-rtl.css 569 B 0 B
build/block-library/blocks/video/editor.css 570 B 0 B
build/block-library/blocks/video/style-rtl.css 173 B 0 B
build/block-library/blocks/video/style.css 173 B 0 B
build/block-library/common-rtl.css 1.26 kB 0 B
build/block-library/common.css 1.26 kB 0 B
build/block-library/editor-rtl.css 9.93 kB 0 B
build/block-library/editor.css 9.92 kB 0 B
build/block-library/index.js 147 kB 0 B
build/block-library/reset-rtl.css 506 B 0 B
build/block-library/reset.css 507 B 0 B
build/block-library/style-rtl.css 10.3 kB 0 B
build/block-library/style.css 10.3 kB 0 B
build/block-library/theme-rtl.css 692 B 0 B
build/block-library/theme.css 693 B 0 B
build/block-serialization-default-parser/index.js 1.29 kB 0 B
build/block-serialization-spec-parser/index.js 3.06 kB 0 B
build/blocks/index.js 47.2 kB 0 B
build/components/index.js 189 kB 0 B
build/components/style-rtl.css 16.2 kB 0 B
build/components/style.css 16.2 kB 0 B
build/core-data/index.js 12.1 kB 0 B
build/customize-widgets/index.js 43.2 kB 0 B
build/customize-widgets/style-rtl.css 1.49 kB 0 B
build/customize-widgets/style.css 1.49 kB 0 B
build/data-controls/index.js 829 B 0 B
build/data/index.js 7.22 kB 0 B
build/date/index.js 31.8 kB 0 B
build/deprecated/index.js 739 B 0 B
build/dom-ready/index.js 577 B 0 B
build/dom/index.js 4.62 kB 0 B
build/edit-navigation/index.js 13.8 kB 0 B
build/edit-navigation/style-rtl.css 3.08 kB 0 B
build/edit-navigation/style.css 3.08 kB 0 B
build/edit-post/classic-rtl.css 454 B 0 B
build/edit-post/classic.css 454 B 0 B
build/edit-post/index.js 571 kB 0 B
build/edit-post/style-rtl.css 6.81 kB 0 B
build/edit-post/style.css 6.8 kB 0 B
build/edit-site/index.js 25.7 kB 0 B
build/edit-site/style-rtl.css 4.75 kB 0 B
build/edit-site/style.css 4.75 kB 0 B
build/edit-widgets/index.js 292 kB 0 B
build/edit-widgets/style-rtl.css 3.46 kB 0 B
build/edit-widgets/style.css 3.47 kB 0 B
build/editor/index.js 38.4 kB 0 B
build/editor/style-rtl.css 3.92 kB 0 B
build/editor/style.css 3.91 kB 0 B
build/element/index.js 3.44 kB 0 B
build/escape-html/index.js 739 B 0 B
build/format-library/index.js 5.67 kB 0 B
build/format-library/style-rtl.css 637 B 0 B
build/format-library/style.css 639 B 0 B
build/hooks/index.js 1.76 kB 0 B
build/html-entities/index.js 627 B 0 B
build/i18n/index.js 3.73 kB 0 B
build/is-shallow-equal/index.js 710 B 0 B
build/keyboard-shortcuts/index.js 1.65 kB 0 B
build/keycodes/index.js 1.43 kB 0 B
build/list-reusable-blocks/index.js 2.07 kB 0 B
build/list-reusable-blocks/style-rtl.css 629 B 0 B
build/list-reusable-blocks/style.css 628 B 0 B
build/media-utils/index.js 3.08 kB 0 B
build/notices/index.js 1.07 kB 0 B
build/nux/index.js 2.31 kB 0 B
build/nux/style-rtl.css 718 B 0 B
build/nux/style.css 716 B 0 B
build/plugins/index.js 1.99 kB 0 B
build/primitives/index.js 1.03 kB 0 B
build/priority-queue/index.js 791 B 0 B
build/react-i18n/index.js 923 B 0 B
build/redux-routine/index.js 2.82 kB 0 B
build/reusable-blocks/index.js 2.53 kB 0 B
build/reusable-blocks/style-rtl.css 225 B 0 B
build/reusable-blocks/style.css 225 B 0 B
build/rich-text/index.js 10.6 kB 0 B
build/server-side-render/index.js 1.63 kB 0 B
build/shortcode/index.js 1.68 kB 0 B
build/token-list/index.js 846 B 0 B
build/url/index.js 1.95 kB 0 B
build/viewport/index.js 1.28 kB 0 B
build/warning/index.js 1.13 kB 0 B
build/widgets/index.js 1.66 kB 0 B
build/wordcount/index.js 1.24 kB 0 B

compressed-size-action

* @param {Object} ref Reference with the element.
* @param {string|Function} text The text to copy.
* @param {number} timeout Optional timeout to reset the returned
* @param {import('react').RefObject<string | Element | NodeListOf<Element>>} ref Reference with the element.
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we import from @wordpress/element?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@wordpress/element doesn't export all the types, just the functions. We import the types directly from react everywhere else as well so it's just following the already established pattern.

Copy link
Member

Choose a reason for hiding this comment

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

I also prefer importing the types in a comment above to leave more room for parameter descriptions

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I think there's lots of places where we import from @wordpress/element. Why don't we export the patterns there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Frankly there are a lot of types to export if we were to export them from @wordpress/element. This would increase the maintenance cost of that already quite non-standard package. We've also already accepted importing them directly from react in this case, so it would be a departure from what's already been going on.

I think @sirreal had some opinions about this that he might want to chime in with.

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 also prefer importing the types in a comment above to leave more room for parameter descriptions

Doing this pollutes the exported types of a module, which is why I avoid it.

Copy link
Member

Choose a reason for hiding this comment

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

Re-exporting React types from @wordpress/element was discussed here: #21767

From memory:

  • Re-exporting the types in JSDoc is extremely costly. Remember that we'd need to completely reproduce in JSDoc anything that accepts a type argument, e.g.
  • We could re-evaluate that now that some TypeScript language is allowed. However, I don't believe we have a "full" re-export of React, so we'd still need to re-export every single type we want.
  • Using types from React is "free". I don't see downsides to using it for the types especially considering the costs of the alternative.

@@ -59,7 +67,9 @@ export default function useCopyOnClick( ref, text, timeout = 4000 ) {
} );

return () => {
clipboard.current.destroy();
if ( clipboard.current ) {
Copy link
Member

Choose a reason for hiding this comment

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

Could we pull clipboard this inside the effect?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry I'm not sure what you are suggesting 😞

Copy link
Member

Choose a reason for hiding this comment

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

It seems clipboard doesn't need to be a ref and can be pulled into useEffect, but maybe that's out of scope for this PR. :)

Copy link
Member

@ellatrix ellatrix May 19, 2021

Choose a reason for hiding this comment

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

The good thing would be that you wouldn't have to check if it exists

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ahhh gotcha. Let me tinker around with it and see if I can get it to work.

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, given it's actually deprecated I feel weird trying to refactor it 😅 Do you think it's still worth it?

Copy link
Member

Choose a reason for hiding this comment

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

I don't have a strong opinion on this, it's just a generally suggestion. It's totally fine to leave it :)

*
* @return {Function} Ref callback.
* @return {(node: Node) => void} Ref callback.
Copy link
Member

Choose a reason for hiding this comment

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

There's a RefCallback type for this I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

RefCallback isn't generic though and in this case we want specifically to return the Node => void function, not just any old callback function.

If you remove the return type annotation and inspect the inferred type of the return from this function you'll see that it's what's written there.

Copy link
Member

Choose a reason for hiding this comment

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

not just any old callback function

What do you mean?

Copy link
Contributor Author

@sarayourfriend sarayourfriend May 17, 2021

Choose a reason for hiding this comment

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

Ah I see what you meant now, I guess we can use the RefCallback type in this case... but why would we when (node: Node) => void is more straightforward to read and matches the literal return type of useCallback in this case?

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I just thought is was easier to use RefCallback, because it's a common thing. How do we add that node can be null 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.

Done! You can do that just by passing Node | null to RefCallback.

@sarayourfriend sarayourfriend force-pushed the add/types-compose-copy branch 3 times, most recently from eaab6c1 to 82d13e5 Compare May 24, 2021 19:10
@sarayourfriend
Copy link
Contributor Author

sarayourfriend commented May 25, 2021

@ellatrix @tyxla @ciampo are any of y'all willing to give this PR a final seal of approval? 🙂 useRefEffect blocks quite a few other hooks from being typed.

@@ -37,11 +44,11 @@ export default function useCopyToClipboard( text, onSuccess ) {
const onSuccesRef = useUpdatedRef( onSuccess );
return useRefEffect( ( node ) => {
// Clipboard listens to click events.
const clipboard = new Clipboard( node, {
const clipboard = new Clipboard( /** @type {Element} */ ( node ), {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the cast from Node to Element safe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I think the type of node should just be HTMLElement to begin with, making it unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay actually I went ahead and made useRefEffect generic, defaulting to Node but making it possible to make it HTMLElement for this function. This should be the safest option 🙂

@sarayourfriend sarayourfriend requested a review from oandregal as a code owner May 25, 2021 13:39
@sarayourfriend
Copy link
Contributor Author

@ciampo this PR now also includes a change to docgen to fix an issue with default exports 😞

@sarayourfriend sarayourfriend added [Tool] Docgen /packages/docgen [Type] Bug An existing feature does not function as intended labels May 25, 2021
@sarayourfriend sarayourfriend force-pushed the add/types-compose-copy branch from e83f9e4 to 628b096 Compare May 25, 2021 19:38
* @param {number} timeout Optional timeout to reset the returned
* @param {import('react').RefObject<string | Element | NodeListOf<Element>>} ref Reference with the element.
* @param {string|Function} text The text to copy.
* @param {number} timeout Optional timeout to reset the returned
Copy link
Contributor

Choose a reason for hiding this comment

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

If it's optional, should it become [timeout] ?

Copy link
Contributor

@ciampo ciampo left a comment

Choose a reason for hiding this comment

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

Apart from this last pending comment, this PR LGTM!

this PR now also includes a change to docgen to fix an issue with default exports 😞

Just to confirm, I ran npx docgen packages/compose/src/hooks/use-ref-effect/index.ts and successfully generated the index-api.md file. Was this the way of testing the docgen fix?

@sarayourfriend
Copy link
Contributor Author

I ran npx docgen packages/compose/src/hooks/use-ref-effect/index.ts and successfully generated the index-api.md file. Was this the way of testing the docgen fix?

Sure that's one way. docgen was completely crashing previously so just the fact that the docgen check passes means it's working 🙂

@sarayourfriend sarayourfriend force-pushed the add/types-compose-copy branch from 628b096 to a45dd1d Compare May 26, 2021 13:41
@sarayourfriend sarayourfriend force-pushed the add/types-compose-copy branch from 5bdb77f to 74f22f7 Compare May 26, 2021 15:03
@sarayourfriend sarayourfriend force-pushed the add/types-compose-copy branch from 74f22f7 to 6f3c3ce Compare May 27, 2021 13:11
@sarayourfriend sarayourfriend merged commit 33d709b into trunk May 27, 2021
@sarayourfriend sarayourfriend deleted the add/types-compose-copy branch May 27, 2021 14:51
@github-actions github-actions bot added this to the Gutenberg 10.8 milestone May 27, 2021
@@ -48,7 +56,7 @@ export default function useCopyOnClick( ref, text, timeout = 4000 ) {

// Handle ClipboardJS focus bug, see https://github.com/zenorocha/clipboard.js/issues/680
if ( trigger ) {
trigger.focus();
/** @type {HTMLElement} */ ( trigger ).focus();
Copy link
Member

Choose a reason for hiding this comment

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

I know this has been merged already, but just curious: why did you wrap trigger in parenthesis here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's how you do a type cast of a variable in JSDoc flavored TypeScript: microsoft/TypeScript#5158

const cleanup = useRef();
return useCallback( ( node ) => {
export default function useRefEffect< TElement = Node >(
callback: ( node: TElement ) => ( () => void ) | undefined,
Copy link
Contributor

Choose a reason for hiding this comment

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

@sarayourfriend: can we use EffectCallback now? Like:

callback: ( node: TElement ) => EffectCallback,

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 don't believe so because that would imply that the callback's return is also able to return a desctructor function which will go one level too deep I think?

Here's the definition for EffectCallback:

type EffectCallback = () => (void | (() => void | undefined));

If we used EffectCallback then the cleanup function, which is the current optional return of the callback parameter, would itself also be allowed to return a function, but we completely ignore the return type of the cleanup function.

If EffectCallback was a generic type that allowed us to add an input parameter type, then we could use it like this:

callback: EffectCallback<TElement>

But effects take no input for their callback so that will never be the case.

I could be confused here though, let me know if you're seeing something I'm not.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, you're totally right, I was the one confused. I misread some type definitions in a different module and thought we were missing an opportunity to use a predefined type. Thanks for humouring me. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Compose /packages/compose [Tool] Docgen /packages/docgen [Type] Bug An existing feature does not function as intended [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants