@wordpress/ui 0.9.1-next.v.202603161435.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +76 -1
- package/CONTRIBUTING.md +180 -0
- package/README.md +34 -6
- package/build/alert-dialog/context.cjs +39 -0
- package/build/alert-dialog/context.cjs.map +7 -0
- package/build/alert-dialog/index.cjs +37 -0
- package/build/alert-dialog/index.cjs.map +7 -0
- package/build/alert-dialog/popup.cjs +165 -0
- package/build/alert-dialog/popup.cjs.map +7 -0
- package/build/alert-dialog/root.cjs +152 -0
- package/build/alert-dialog/root.cjs.map +7 -0
- package/build/alert-dialog/trigger.cjs +38 -0
- package/build/alert-dialog/trigger.cjs.map +7 -0
- package/build/alert-dialog/types.cjs +19 -0
- package/build/alert-dialog/types.cjs.map +7 -0
- package/build/badge/badge.cjs +14 -14
- package/build/badge/badge.cjs.map +2 -2
- package/build/button/button.cjs +18 -8
- package/build/button/button.cjs.map +3 -3
- package/build/card/content.cjs +4 -4
- package/build/card/content.cjs.map +2 -2
- package/build/card/full-bleed.cjs +4 -4
- package/build/card/full-bleed.cjs.map +2 -2
- package/build/card/header.cjs +4 -4
- package/build/card/header.cjs.map +2 -2
- package/build/card/root.cjs +6 -6
- package/build/card/root.cjs.map +2 -2
- package/build/card/title.cjs +14 -21
- package/build/card/title.cjs.map +3 -3
- package/build/collapsible-card/content.cjs +24 -3
- package/build/collapsible-card/content.cjs.map +4 -4
- package/build/collapsible-card/context.cjs +35 -0
- package/build/collapsible-card/context.cjs.map +7 -0
- package/build/collapsible-card/header-description.cjs +52 -0
- package/build/collapsible-card/header-description.cjs.map +7 -0
- package/build/collapsible-card/header.cjs +39 -18
- package/build/collapsible-card/header.cjs.map +2 -2
- package/build/collapsible-card/index.cjs +3 -0
- package/build/collapsible-card/index.cjs.map +2 -2
- package/build/collapsible-card/types.cjs.map +1 -1
- package/build/dialog/action.cjs +4 -2
- package/build/dialog/action.cjs.map +2 -2
- package/build/dialog/close-icon.cjs +2 -1
- package/build/dialog/close-icon.cjs.map +2 -2
- package/build/dialog/footer.cjs +3 -3
- package/build/dialog/footer.cjs.map +2 -2
- package/build/dialog/header.cjs +3 -3
- package/build/dialog/header.cjs.map +2 -2
- package/build/dialog/popup.cjs +24 -6
- package/build/dialog/popup.cjs.map +2 -2
- package/build/dialog/title.cjs +10 -19
- package/build/dialog/title.cjs.map +3 -3
- package/build/dialog/types.cjs.map +1 -1
- package/build/empty-state/actions.cjs +66 -0
- package/build/empty-state/actions.cjs.map +7 -0
- package/build/empty-state/description.cjs +69 -0
- package/build/empty-state/description.cjs.map +7 -0
- package/build/empty-state/icon.cjs +69 -0
- package/build/empty-state/icon.cjs.map +7 -0
- package/build/empty-state/index.cjs +46 -0
- package/build/empty-state/index.cjs.map +7 -0
- package/build/empty-state/root.cjs +66 -0
- package/build/empty-state/root.cjs.map +7 -0
- package/build/empty-state/title.cjs +71 -0
- package/build/empty-state/title.cjs.map +7 -0
- package/build/empty-state/types.cjs +19 -0
- package/build/empty-state/types.cjs.map +7 -0
- package/build/empty-state/visual.cjs +66 -0
- package/build/empty-state/visual.cjs.map +7 -0
- package/build/form/index.cjs +27 -0
- package/build/form/index.cjs.map +7 -0
- package/build/form/input-control/index.cjs +31 -0
- package/build/form/input-control/index.cjs.map +7 -0
- package/build/form/input-control/input-control.cjs +50 -0
- package/build/form/input-control/input-control.cjs.map +7 -0
- package/build/form/input-control/types.cjs +19 -0
- package/build/form/input-control/types.cjs.map +7 -0
- package/build/form/primitives/field/description.cjs +17 -4
- package/build/form/primitives/field/description.cjs.map +3 -3
- package/build/form/primitives/field/details.cjs +4 -4
- package/build/form/primitives/field/details.cjs.map +2 -2
- package/build/form/primitives/field/label.cjs +8 -8
- package/build/form/primitives/field/label.cjs.map +2 -2
- package/build/form/primitives/field/root.cjs +2 -2
- package/build/form/primitives/field/root.cjs.map +1 -1
- package/build/form/primitives/fieldset/description.cjs +20 -4
- package/build/form/primitives/fieldset/description.cjs.map +3 -3
- package/build/form/primitives/fieldset/details.cjs +3 -3
- package/build/form/primitives/fieldset/details.cjs.map +2 -2
- package/build/form/primitives/fieldset/legend.cjs +8 -7
- package/build/form/primitives/fieldset/legend.cjs.map +2 -2
- package/build/form/primitives/fieldset/root.cjs +2 -2
- package/build/form/primitives/fieldset/root.cjs.map +1 -1
- package/build/form/primitives/input/input.cjs +23 -7
- package/build/form/primitives/input/input.cjs.map +3 -3
- package/build/form/primitives/input-layout/input-layout.cjs +15 -5
- package/build/form/primitives/input-layout/input-layout.cjs.map +3 -3
- package/build/form/primitives/input-layout/slot.cjs +6 -5
- package/build/form/primitives/input-layout/slot.cjs.map +2 -2
- package/build/form/primitives/select/item.cjs +5 -5
- package/build/form/primitives/select/item.cjs.map +2 -2
- package/build/form/primitives/select/popup.cjs +9 -9
- package/build/form/primitives/select/popup.cjs.map +2 -2
- package/build/form/primitives/select/trigger.cjs +6 -6
- package/build/form/primitives/select/trigger.cjs.map +2 -2
- package/build/form/primitives/select/types.cjs.map +1 -1
- package/build/form/primitives/textarea/textarea.cjs +23 -4
- package/build/form/primitives/textarea/textarea.cjs.map +3 -3
- package/build/form/types.cjs +19 -0
- package/build/form/types.cjs.map +7 -0
- package/build/icon-button/icon-button.cjs +2 -2
- package/build/icon-button/icon-button.cjs.map +1 -1
- package/build/index.cjs +11 -2
- package/build/index.cjs.map +2 -2
- package/build/link/link.cjs +18 -8
- package/build/link/link.cjs.map +3 -3
- package/build/notice/action-button.cjs +3 -3
- package/build/notice/action-button.cjs.map +2 -2
- package/build/notice/action-link.cjs +3 -3
- package/build/notice/action-link.cjs.map +2 -2
- package/build/notice/actions.cjs +3 -3
- package/build/notice/actions.cjs.map +2 -2
- package/build/notice/close-icon.cjs +3 -3
- package/build/notice/close-icon.cjs.map +2 -2
- package/build/notice/description.cjs +3 -3
- package/build/notice/description.cjs.map +2 -2
- package/build/notice/index.cjs.map +1 -1
- package/build/notice/root.cjs +5 -5
- package/build/notice/root.cjs.map +2 -2
- package/build/notice/title.cjs +3 -3
- package/build/notice/title.cjs.map +2 -2
- package/build/popover/arrow.cjs +94 -0
- package/build/popover/arrow.cjs.map +7 -0
- package/build/popover/close.cjs +45 -0
- package/build/popover/close.cjs.map +7 -0
- package/build/popover/context.cjs +76 -0
- package/build/popover/context.cjs.map +7 -0
- package/build/popover/description.cjs +70 -0
- package/build/popover/description.cjs.map +7 -0
- package/build/popover/index.cjs +49 -0
- package/build/popover/index.cjs.map +7 -0
- package/build/popover/popup.cjs +138 -0
- package/build/popover/popup.cjs.map +7 -0
- package/build/popover/root.cjs +35 -0
- package/build/popover/root.cjs.map +7 -0
- package/build/popover/title.cjs +56 -0
- package/build/popover/title.cjs.map +7 -0
- package/build/popover/trigger.cjs +38 -0
- package/build/popover/trigger.cjs.map +7 -0
- package/build/popover/types.cjs +19 -0
- package/build/popover/types.cjs.map +7 -0
- package/build/stack/stack.cjs +2 -2
- package/build/stack/stack.cjs.map +1 -1
- package/build/tabs/context.cjs +121 -0
- package/build/tabs/context.cjs.map +7 -0
- package/build/tabs/list.cjs +3 -4
- package/build/tabs/list.cjs.map +2 -2
- package/build/tabs/panel.cjs +5 -3
- package/build/tabs/panel.cjs.map +2 -2
- package/build/tabs/root.cjs +2 -1
- package/build/tabs/root.cjs.map +2 -2
- package/build/tabs/tab.cjs +5 -3
- package/build/tabs/tab.cjs.map +2 -2
- package/build/text/text.cjs +20 -5
- package/build/text/text.cjs.map +3 -3
- package/build/tooltip/popup.cjs +7 -6
- package/build/tooltip/popup.cjs.map +2 -2
- package/build/tooltip/root.cjs.map +2 -2
- package/build/tooltip/types.cjs.map +1 -1
- package/build/utils/types.cjs.map +1 -1
- package/build/utils/use-deprioritized-initial-focus.cjs +64 -0
- package/build/utils/use-deprioritized-initial-focus.cjs.map +7 -0
- package/build/visually-hidden/visually-hidden.cjs +2 -2
- package/build/visually-hidden/visually-hidden.cjs.map +2 -2
- package/build-module/alert-dialog/context.mjs +14 -0
- package/build-module/alert-dialog/context.mjs.map +7 -0
- package/build-module/alert-dialog/index.mjs +10 -0
- package/build-module/alert-dialog/index.mjs.map +7 -0
- package/build-module/alert-dialog/popup.mjs +132 -0
- package/build-module/alert-dialog/popup.mjs.map +7 -0
- package/build-module/alert-dialog/root.mjs +133 -0
- package/build-module/alert-dialog/root.mjs.map +7 -0
- package/build-module/alert-dialog/trigger.mjs +13 -0
- package/build-module/alert-dialog/trigger.mjs.map +7 -0
- package/build-module/alert-dialog/types.mjs +1 -0
- package/build-module/alert-dialog/types.mjs.map +7 -0
- package/build-module/badge/badge.mjs +14 -14
- package/build-module/badge/badge.mjs.map +2 -2
- package/build-module/button/button.mjs +18 -8
- package/build-module/button/button.mjs.map +3 -3
- package/build-module/card/content.mjs +4 -4
- package/build-module/card/content.mjs.map +2 -2
- package/build-module/card/full-bleed.mjs +4 -4
- package/build-module/card/full-bleed.mjs.map +2 -2
- package/build-module/card/header.mjs +4 -4
- package/build-module/card/header.mjs.map +2 -2
- package/build-module/card/root.mjs +6 -6
- package/build-module/card/root.mjs.map +2 -2
- package/build-module/card/title.mjs +14 -21
- package/build-module/card/title.mjs.map +3 -3
- package/build-module/collapsible-card/content.mjs +24 -3
- package/build-module/collapsible-card/content.mjs.map +3 -3
- package/build-module/collapsible-card/context.mjs +10 -0
- package/build-module/collapsible-card/context.mjs.map +7 -0
- package/build-module/collapsible-card/header-description.mjs +27 -0
- package/build-module/collapsible-card/header-description.mjs.map +7 -0
- package/build-module/collapsible-card/header.mjs +40 -19
- package/build-module/collapsible-card/header.mjs.map +2 -2
- package/build-module/collapsible-card/index.mjs +2 -0
- package/build-module/collapsible-card/index.mjs.map +2 -2
- package/build-module/dialog/action.mjs +4 -2
- package/build-module/dialog/action.mjs.map +2 -2
- package/build-module/dialog/close-icon.mjs +2 -1
- package/build-module/dialog/close-icon.mjs.map +2 -2
- package/build-module/dialog/footer.mjs +3 -3
- package/build-module/dialog/footer.mjs.map +2 -2
- package/build-module/dialog/header.mjs +3 -3
- package/build-module/dialog/header.mjs.map +2 -2
- package/build-module/dialog/popup.mjs +24 -6
- package/build-module/dialog/popup.mjs.map +2 -2
- package/build-module/dialog/title.mjs +10 -9
- package/build-module/dialog/title.mjs.map +2 -2
- package/build-module/empty-state/actions.mjs +31 -0
- package/build-module/empty-state/actions.mjs.map +7 -0
- package/build-module/empty-state/description.mjs +34 -0
- package/build-module/empty-state/description.mjs.map +7 -0
- package/build-module/empty-state/icon.mjs +34 -0
- package/build-module/empty-state/icon.mjs.map +7 -0
- package/build-module/empty-state/index.mjs +16 -0
- package/build-module/empty-state/index.mjs.map +7 -0
- package/build-module/empty-state/root.mjs +31 -0
- package/build-module/empty-state/root.mjs.map +7 -0
- package/build-module/empty-state/title.mjs +36 -0
- package/build-module/empty-state/title.mjs.map +7 -0
- package/build-module/empty-state/types.mjs +1 -0
- package/build-module/empty-state/types.mjs.map +7 -0
- package/build-module/empty-state/visual.mjs +31 -0
- package/build-module/empty-state/visual.mjs.map +7 -0
- package/build-module/form/index.mjs +4 -0
- package/build-module/form/index.mjs.map +7 -0
- package/build-module/form/input-control/index.mjs +6 -0
- package/build-module/form/input-control/index.mjs.map +7 -0
- package/build-module/form/input-control/input-control.mjs +25 -0
- package/build-module/form/input-control/input-control.mjs.map +7 -0
- package/build-module/form/input-control/types.mjs +1 -0
- package/build-module/form/input-control/types.mjs.map +7 -0
- package/build-module/form/primitives/field/description.mjs +17 -4
- package/build-module/form/primitives/field/description.mjs.map +3 -3
- package/build-module/form/primitives/field/details.mjs +4 -4
- package/build-module/form/primitives/field/details.mjs.map +2 -2
- package/build-module/form/primitives/field/label.mjs +8 -8
- package/build-module/form/primitives/field/label.mjs.map +2 -2
- package/build-module/form/primitives/field/root.mjs +2 -2
- package/build-module/form/primitives/field/root.mjs.map +1 -1
- package/build-module/form/primitives/fieldset/description.mjs +20 -4
- package/build-module/form/primitives/fieldset/description.mjs.map +3 -3
- package/build-module/form/primitives/fieldset/details.mjs +3 -3
- package/build-module/form/primitives/fieldset/details.mjs.map +2 -2
- package/build-module/form/primitives/fieldset/legend.mjs +8 -7
- package/build-module/form/primitives/fieldset/legend.mjs.map +2 -2
- package/build-module/form/primitives/fieldset/root.mjs +2 -2
- package/build-module/form/primitives/fieldset/root.mjs.map +1 -1
- package/build-module/form/primitives/input/input.mjs +23 -7
- package/build-module/form/primitives/input/input.mjs.map +3 -3
- package/build-module/form/primitives/input-layout/input-layout.mjs +15 -5
- package/build-module/form/primitives/input-layout/input-layout.mjs.map +3 -3
- package/build-module/form/primitives/input-layout/slot.mjs +6 -5
- package/build-module/form/primitives/input-layout/slot.mjs.map +2 -2
- package/build-module/form/primitives/select/item.mjs +5 -5
- package/build-module/form/primitives/select/item.mjs.map +2 -2
- package/build-module/form/primitives/select/popup.mjs +9 -9
- package/build-module/form/primitives/select/popup.mjs.map +2 -2
- package/build-module/form/primitives/select/trigger.mjs +6 -6
- package/build-module/form/primitives/select/trigger.mjs.map +2 -2
- package/build-module/form/primitives/textarea/textarea.mjs +23 -4
- package/build-module/form/primitives/textarea/textarea.mjs.map +3 -3
- package/build-module/form/types.mjs +1 -0
- package/build-module/form/types.mjs.map +7 -0
- package/build-module/icon-button/icon-button.mjs +2 -2
- package/build-module/icon-button/icon-button.mjs.map +1 -1
- package/build-module/index.mjs +7 -1
- package/build-module/index.mjs.map +2 -2
- package/build-module/link/link.mjs +18 -8
- package/build-module/link/link.mjs.map +3 -3
- package/build-module/notice/action-button.mjs +3 -3
- package/build-module/notice/action-button.mjs.map +2 -2
- package/build-module/notice/action-link.mjs +3 -3
- package/build-module/notice/action-link.mjs.map +2 -2
- package/build-module/notice/actions.mjs +3 -3
- package/build-module/notice/actions.mjs.map +2 -2
- package/build-module/notice/close-icon.mjs +3 -3
- package/build-module/notice/close-icon.mjs.map +2 -2
- package/build-module/notice/description.mjs +3 -3
- package/build-module/notice/description.mjs.map +2 -2
- package/build-module/notice/index.mjs.map +1 -1
- package/build-module/notice/root.mjs +5 -5
- package/build-module/notice/root.mjs.map +2 -2
- package/build-module/notice/title.mjs +3 -3
- package/build-module/notice/title.mjs.map +2 -2
- package/build-module/popover/arrow.mjs +59 -0
- package/build-module/popover/arrow.mjs.map +7 -0
- package/build-module/popover/close.mjs +20 -0
- package/build-module/popover/close.mjs.map +7 -0
- package/build-module/popover/context.mjs +57 -0
- package/build-module/popover/context.mjs.map +7 -0
- package/build-module/popover/description.mjs +35 -0
- package/build-module/popover/description.mjs.map +7 -0
- package/build-module/popover/index.mjs +18 -0
- package/build-module/popover/index.mjs.map +7 -0
- package/build-module/popover/popup.mjs +105 -0
- package/build-module/popover/popup.mjs.map +7 -0
- package/build-module/popover/root.mjs +10 -0
- package/build-module/popover/root.mjs.map +7 -0
- package/build-module/popover/title.mjs +31 -0
- package/build-module/popover/title.mjs.map +7 -0
- package/build-module/popover/trigger.mjs +13 -0
- package/build-module/popover/trigger.mjs.map +7 -0
- package/build-module/popover/types.mjs +1 -0
- package/build-module/popover/types.mjs.map +7 -0
- package/build-module/stack/stack.mjs +2 -2
- package/build-module/stack/stack.mjs.map +1 -1
- package/build-module/tabs/context.mjs +101 -0
- package/build-module/tabs/context.mjs.map +7 -0
- package/build-module/tabs/list.mjs +3 -4
- package/build-module/tabs/list.mjs.map +2 -2
- package/build-module/tabs/panel.mjs +5 -3
- package/build-module/tabs/panel.mjs.map +2 -2
- package/build-module/tabs/root.mjs +2 -1
- package/build-module/tabs/root.mjs.map +2 -2
- package/build-module/tabs/tab.mjs +5 -3
- package/build-module/tabs/tab.mjs.map +2 -2
- package/build-module/text/text.mjs +20 -5
- package/build-module/text/text.mjs.map +3 -3
- package/build-module/tooltip/popup.mjs +7 -6
- package/build-module/tooltip/popup.mjs.map +2 -2
- package/build-module/tooltip/root.mjs.map +2 -2
- package/build-module/utils/use-deprioritized-initial-focus.mjs +39 -0
- package/build-module/utils/use-deprioritized-initial-focus.mjs.map +7 -0
- package/build-module/visually-hidden/visually-hidden.mjs +2 -2
- package/build-module/visually-hidden/visually-hidden.mjs.map +2 -2
- package/build-types/alert-dialog/context.d.ts +11 -0
- package/build-types/alert-dialog/context.d.ts.map +1 -0
- package/build-types/alert-dialog/index.d.ts +4 -0
- package/build-types/alert-dialog/index.d.ts.map +1 -0
- package/build-types/alert-dialog/popup.d.ts +4 -0
- package/build-types/alert-dialog/popup.d.ts.map +1 -0
- package/build-types/alert-dialog/root.d.ts +18 -0
- package/build-types/alert-dialog/root.d.ts.map +1 -0
- package/build-types/alert-dialog/stories/index.story.d.ts +56 -0
- package/build-types/alert-dialog/stories/index.story.d.ts.map +1 -0
- package/build-types/alert-dialog/test/index.test.d.ts +2 -0
- package/build-types/alert-dialog/test/index.test.d.ts.map +1 -0
- package/build-types/alert-dialog/trigger.d.ts +7 -0
- package/build-types/alert-dialog/trigger.d.ts.map +1 -0
- package/build-types/alert-dialog/types.d.ts +105 -0
- package/build-types/alert-dialog/types.d.ts.map +1 -0
- package/build-types/badge/badge.d.ts.map +1 -1
- package/build-types/button/button.d.ts.map +1 -1
- package/build-types/card/stories/index.story.d.ts.map +1 -1
- package/build-types/card/title.d.ts.map +1 -1
- package/build-types/collapsible/panel.d.ts +2 -1
- package/build-types/collapsible/panel.d.ts.map +1 -1
- package/build-types/collapsible/root.d.ts +2 -1
- package/build-types/collapsible/root.d.ts.map +1 -1
- package/build-types/collapsible/trigger.d.ts +2 -1
- package/build-types/collapsible/trigger.d.ts.map +1 -1
- package/build-types/collapsible-card/content.d.ts.map +1 -1
- package/build-types/collapsible-card/context.d.ts +4 -0
- package/build-types/collapsible-card/context.d.ts.map +1 -0
- package/build-types/collapsible-card/header-description.d.ts +15 -0
- package/build-types/collapsible-card/header-description.d.ts.map +1 -0
- package/build-types/collapsible-card/header.d.ts.map +1 -1
- package/build-types/collapsible-card/index.d.ts +2 -1
- package/build-types/collapsible-card/index.d.ts.map +1 -1
- package/build-types/collapsible-card/stories/index.story.d.ts +10 -0
- package/build-types/collapsible-card/stories/index.story.d.ts.map +1 -1
- package/build-types/collapsible-card/types.d.ts +21 -0
- package/build-types/collapsible-card/types.d.ts.map +1 -1
- package/build-types/dialog/action.d.ts.map +1 -1
- package/build-types/dialog/close-icon.d.ts.map +1 -1
- package/build-types/dialog/popup.d.ts.map +1 -1
- package/build-types/dialog/stories/index.story.d.ts +8 -6
- package/build-types/dialog/stories/index.story.d.ts.map +1 -1
- package/build-types/dialog/title.d.ts +12 -2
- package/build-types/dialog/title.d.ts.map +1 -1
- package/build-types/dialog/types.d.ts +13 -6
- package/build-types/dialog/types.d.ts.map +1 -1
- package/build-types/empty-state/actions.d.ts +7 -0
- package/build-types/empty-state/actions.d.ts.map +1 -0
- package/build-types/empty-state/description.d.ts +7 -0
- package/build-types/empty-state/description.d.ts.map +1 -0
- package/build-types/empty-state/icon.d.ts +7 -0
- package/build-types/empty-state/icon.d.ts.map +1 -0
- package/build-types/empty-state/index.d.ts +8 -0
- package/build-types/empty-state/index.d.ts.map +1 -0
- package/build-types/empty-state/root.d.ts +6 -0
- package/build-types/empty-state/root.d.ts.map +1 -0
- package/build-types/empty-state/stories/index.story.d.ts +8 -0
- package/build-types/empty-state/stories/index.story.d.ts.map +1 -0
- package/build-types/empty-state/test/actions.test.d.ts +2 -0
- package/build-types/empty-state/test/actions.test.d.ts.map +1 -0
- package/build-types/empty-state/test/description.test.d.ts +2 -0
- package/build-types/empty-state/test/description.test.d.ts.map +1 -0
- package/build-types/empty-state/test/icon.test.d.ts +2 -0
- package/build-types/empty-state/test/icon.test.d.ts.map +1 -0
- package/build-types/empty-state/test/root.test.d.ts +2 -0
- package/build-types/empty-state/test/root.test.d.ts.map +1 -0
- package/build-types/empty-state/test/title.test.d.ts +2 -0
- package/build-types/empty-state/test/title.test.d.ts.map +1 -0
- package/build-types/empty-state/test/visual.test.d.ts +2 -0
- package/build-types/empty-state/test/visual.test.d.ts.map +1 -0
- package/build-types/empty-state/title.d.ts +6 -0
- package/build-types/empty-state/title.d.ts.map +1 -0
- package/build-types/empty-state/types.d.ts +40 -0
- package/build-types/empty-state/types.d.ts.map +1 -0
- package/build-types/empty-state/visual.d.ts +7 -0
- package/build-types/empty-state/visual.d.ts.map +1 -0
- package/build-types/form/index.d.ts +3 -0
- package/build-types/form/index.d.ts.map +1 -0
- package/build-types/form/input-control/index.d.ts +2 -0
- package/build-types/form/input-control/index.d.ts.map +1 -0
- package/build-types/form/input-control/input-control.d.ts +6 -0
- package/build-types/form/input-control/input-control.d.ts.map +1 -0
- package/build-types/form/input-control/stories/index.story.d.ts +16 -0
- package/build-types/form/input-control/stories/index.story.d.ts.map +1 -0
- package/build-types/form/input-control/test/index.test.d.ts +2 -0
- package/build-types/form/input-control/test/index.test.d.ts.map +1 -0
- package/build-types/form/input-control/types.d.ts +4 -0
- package/build-types/form/input-control/types.d.ts.map +1 -0
- package/build-types/form/primitives/field/description.d.ts +2 -1
- package/build-types/form/primitives/field/description.d.ts.map +1 -1
- package/build-types/form/primitives/field/details.d.ts +2 -1
- package/build-types/form/primitives/field/details.d.ts.map +1 -1
- package/build-types/form/primitives/field/label.d.ts +2 -1
- package/build-types/form/primitives/field/label.d.ts.map +1 -1
- package/build-types/form/primitives/field/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/description.d.ts +2 -1
- package/build-types/form/primitives/fieldset/description.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/details.d.ts +2 -1
- package/build-types/form/primitives/fieldset/details.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/legend.d.ts +2 -1
- package/build-types/form/primitives/fieldset/legend.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/root.d.ts +2 -1
- package/build-types/form/primitives/fieldset/root.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/input/input.d.ts.map +1 -1
- package/build-types/form/primitives/input/stories/index.story.d.ts +2 -0
- package/build-types/form/primitives/input/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/input-layout/input-layout.d.ts.map +1 -1
- package/build-types/form/primitives/input-layout/slot.d.ts.map +1 -1
- package/build-types/form/primitives/input-layout/stories/index.story.d.ts +5 -0
- package/build-types/form/primitives/input-layout/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/select/item.d.ts +6 -2
- package/build-types/form/primitives/select/item.d.ts.map +1 -1
- package/build-types/form/primitives/select/popup.d.ts +11 -1
- package/build-types/form/primitives/select/popup.d.ts.map +1 -1
- package/build-types/form/primitives/select/trigger.d.ts +12 -2
- package/build-types/form/primitives/select/trigger.d.ts.map +1 -1
- package/build-types/form/primitives/select/types.d.ts +13 -3
- package/build-types/form/primitives/select/types.d.ts.map +1 -1
- package/build-types/form/primitives/textarea/textarea.d.ts.map +1 -1
- package/build-types/form/stories/shared.d.ts +3 -0
- package/build-types/form/stories/shared.d.ts.map +1 -0
- package/build-types/form/types.d.ts +30 -0
- package/build-types/form/types.d.ts.map +1 -0
- package/build-types/index.d.ts +4 -1
- package/build-types/index.d.ts.map +1 -1
- package/build-types/link/link.d.ts.map +1 -1
- package/build-types/notice/index.d.ts +0 -1
- package/build-types/notice/index.d.ts.map +1 -1
- package/build-types/popover/arrow.d.ts +10 -0
- package/build-types/popover/arrow.d.ts.map +1 -0
- package/build-types/popover/close.d.ts +11 -0
- package/build-types/popover/close.d.ts.map +1 -0
- package/build-types/popover/context.d.ts +22 -0
- package/build-types/popover/context.d.ts.map +1 -0
- package/build-types/popover/description.d.ts +10 -0
- package/build-types/popover/description.d.ts.map +1 -0
- package/build-types/popover/index.d.ts +9 -0
- package/build-types/popover/index.d.ts.map +1 -0
- package/build-types/popover/popup.d.ts +11 -0
- package/build-types/popover/popup.d.ts.map +1 -0
- package/build-types/popover/root.d.ts +37 -0
- package/build-types/popover/root.d.ts.map +1 -0
- package/build-types/popover/stories/index.story.d.ts +211 -0
- package/build-types/popover/stories/index.story.d.ts.map +1 -0
- package/build-types/popover/stories/utils.d.ts +25 -0
- package/build-types/popover/stories/utils.d.ts.map +1 -0
- package/build-types/popover/test/index.test.d.ts +2 -0
- package/build-types/popover/test/index.test.d.ts.map +1 -0
- package/build-types/popover/title.d.ts +20 -0
- package/build-types/popover/title.d.ts.map +1 -0
- package/build-types/popover/trigger.d.ts +10 -0
- package/build-types/popover/trigger.d.ts.map +1 -0
- package/build-types/popover/types.d.ts +83 -0
- package/build-types/popover/types.d.ts.map +1 -0
- package/build-types/tabs/context.d.ts +26 -0
- package/build-types/tabs/context.d.ts.map +1 -0
- package/build-types/tabs/list.d.ts +2 -1
- package/build-types/tabs/list.d.ts.map +1 -1
- package/build-types/tabs/panel.d.ts +2 -1
- package/build-types/tabs/panel.d.ts.map +1 -1
- package/build-types/tabs/root.d.ts +2 -1
- package/build-types/tabs/root.d.ts.map +1 -1
- package/build-types/tabs/tab.d.ts +2 -1
- package/build-types/tabs/tab.d.ts.map +1 -1
- package/build-types/text/stories/index.story.d.ts +4 -0
- package/build-types/text/stories/index.story.d.ts.map +1 -1
- package/build-types/text/text.d.ts.map +1 -1
- package/build-types/tooltip/popup.d.ts.map +1 -1
- package/build-types/tooltip/root.d.ts +13 -0
- package/build-types/tooltip/root.d.ts.map +1 -1
- package/build-types/tooltip/stories/index.story.d.ts.map +1 -1
- package/build-types/tooltip/stories/usage-guidelines.story.d.ts +21 -0
- package/build-types/tooltip/stories/usage-guidelines.story.d.ts.map +1 -0
- package/build-types/tooltip/types.d.ts +4 -0
- package/build-types/tooltip/types.d.ts.map +1 -1
- package/build-types/utils/test/use-deprioritized-initial-focus.test.d.ts +2 -0
- package/build-types/utils/test/use-deprioritized-initial-focus.test.d.ts.map +1 -0
- package/build-types/utils/types.d.ts +6 -2
- package/build-types/utils/types.d.ts.map +1 -1
- package/build-types/utils/use-deprioritized-initial-focus.d.ts +36 -0
- package/build-types/utils/use-deprioritized-initial-focus.d.ts.map +1 -0
- package/build-types/visually-hidden/stories/index.story.d.ts +7 -0
- package/build-types/visually-hidden/stories/index.story.d.ts.map +1 -1
- package/build-types/visually-hidden/visually-hidden.d.ts +34 -0
- package/build-types/visually-hidden/visually-hidden.d.ts.map +1 -1
- package/package.json +17 -16
- package/src/alert-dialog/context.tsx +22 -0
- package/src/alert-dialog/index.ts +3 -0
- package/src/alert-dialog/popup.tsx +116 -0
- package/src/alert-dialog/root.tsx +226 -0
- package/src/alert-dialog/stories/index.story.tsx +305 -0
- package/src/alert-dialog/style.module.css +21 -0
- package/src/alert-dialog/test/index.test.tsx +1509 -0
- package/src/alert-dialog/trigger.tsx +15 -0
- package/src/alert-dialog/types.ts +119 -0
- package/src/badge/badge.tsx +11 -14
- package/src/badge/style.module.css +0 -4
- package/src/button/button.tsx +2 -0
- package/src/button/style.module.css +9 -3
- package/src/card/stories/index.story.tsx +4 -5
- package/src/card/style.module.css +4 -10
- package/src/card/test/index.test.tsx +17 -1
- package/src/card/title.tsx +14 -12
- package/src/collapsible-card/content.tsx +16 -3
- package/src/collapsible-card/context.ts +7 -0
- package/src/collapsible-card/header-description.tsx +43 -0
- package/src/collapsible-card/header.tsx +47 -24
- package/src/collapsible-card/index.ts +2 -1
- package/src/collapsible-card/stories/index.story.tsx +102 -4
- package/src/collapsible-card/style.module.css +34 -2
- package/src/collapsible-card/test/index.test.tsx +96 -9
- package/src/collapsible-card/types.ts +22 -0
- package/src/dialog/action.tsx +8 -2
- package/src/dialog/close-icon.tsx +1 -0
- package/src/dialog/popup.tsx +23 -3
- package/src/dialog/stories/index.story.tsx +33 -28
- package/src/dialog/style.module.css +18 -14
- package/src/dialog/test/index.test.tsx +180 -4
- package/src/dialog/title.tsx +21 -9
- package/src/dialog/types.ts +20 -6
- package/src/empty-state/actions.tsx +24 -0
- package/src/empty-state/description.tsx +31 -0
- package/src/empty-state/icon.tsx +24 -0
- package/src/empty-state/index.ts +8 -0
- package/src/empty-state/root.tsx +23 -0
- package/src/empty-state/stories/index.story.tsx +64 -0
- package/src/empty-state/style.module.css +53 -0
- package/src/empty-state/test/actions.test.tsx +18 -0
- package/src/empty-state/test/description.test.tsx +26 -0
- package/src/empty-state/test/icon.test.tsx +13 -0
- package/src/empty-state/test/root.test.tsx +13 -0
- package/src/empty-state/test/title.test.tsx +26 -0
- package/src/empty-state/test/visual.test.tsx +17 -0
- package/src/empty-state/title.tsx +29 -0
- package/src/empty-state/types.ts +45 -0
- package/src/empty-state/visual.tsx +24 -0
- package/src/form/index.ts +3 -0
- package/src/form/input-control/index.ts +1 -0
- package/src/form/input-control/input-control.tsx +33 -0
- package/src/form/input-control/stories/index.story.tsx +163 -0
- package/src/form/input-control/test/index.test.tsx +53 -0
- package/src/form/input-control/types.ts +5 -0
- package/src/form/primitives/field/description.tsx +6 -1
- package/src/form/primitives/field/details.tsx +4 -2
- package/src/form/primitives/field/label.tsx +9 -5
- package/src/form/primitives/field/stories/index.story.tsx +2 -7
- package/src/form/primitives/field/test/index.test.tsx +11 -0
- package/src/form/primitives/fieldset/description.tsx +9 -1
- package/src/form/primitives/fieldset/legend.tsx +9 -4
- package/src/form/primitives/fieldset/stories/index.story.tsx +2 -7
- package/src/form/primitives/fieldset/test/index.test.tsx +22 -0
- package/src/form/primitives/input/input.tsx +6 -1
- package/src/form/primitives/input/stories/index.story.tsx +7 -0
- package/src/form/primitives/input/style.module.css +4 -0
- package/src/form/primitives/input-layout/input-layout.tsx +2 -0
- package/src/form/primitives/input-layout/slot.tsx +6 -2
- package/src/form/primitives/input-layout/stories/index.story.tsx +22 -1
- package/src/form/primitives/input-layout/style.module.css +3 -3
- package/src/form/primitives/select/popup.tsx +5 -2
- package/src/form/primitives/select/test/index.test.tsx +60 -1
- package/src/form/primitives/select/types.ts +14 -4
- package/src/form/primitives/stories/overview.mdx +15 -0
- package/src/form/primitives/textarea/textarea.tsx +11 -2
- package/src/form/stories/shared.tsx +21 -0
- package/src/form/types.ts +34 -0
- package/src/index.ts +4 -1
- package/src/link/link.tsx +2 -0
- package/src/link/style.module.css +11 -1
- package/src/notice/index.ts +0 -2
- package/src/notice/style.module.css +6 -6
- package/src/popover/arrow.tsx +49 -0
- package/src/popover/close.tsx +24 -0
- package/src/popover/context.tsx +100 -0
- package/src/popover/description.tsx +29 -0
- package/src/popover/index.ts +9 -0
- package/src/popover/popup.tsx +106 -0
- package/src/popover/root.tsx +41 -0
- package/src/popover/stories/index.story.tsx +1315 -0
- package/src/popover/stories/utils.tsx +91 -0
- package/src/popover/style.module.css +64 -0
- package/src/popover/test/index.test.tsx +727 -0
- package/src/popover/title.tsx +47 -0
- package/src/popover/trigger.tsx +17 -0
- package/src/popover/types.ts +113 -0
- package/src/tabs/context.tsx +170 -0
- package/src/tabs/list.tsx +0 -1
- package/src/tabs/panel.tsx +3 -0
- package/src/tabs/root.tsx +6 -1
- package/src/tabs/style.module.css +3 -3
- package/src/tabs/tab.tsx +3 -0
- package/src/tabs/test/index.test.tsx +162 -0
- package/src/text/stories/index.story.tsx +4 -2
- package/src/text/style.module.css +62 -36
- package/src/text/test/index.test.tsx +1 -4
- package/src/text/text.tsx +8 -1
- package/src/tooltip/popup.tsx +2 -1
- package/src/tooltip/root.tsx +13 -0
- package/src/tooltip/stories/index.story.tsx +20 -15
- package/src/tooltip/stories/usage-guidelines.mdx +91 -0
- package/src/tooltip/stories/usage-guidelines.story.tsx +119 -0
- package/src/tooltip/style.module.css +2 -2
- package/src/tooltip/test/index.test.tsx +61 -0
- package/src/tooltip/types.ts +5 -0
- package/src/utils/css/field.module.css +12 -9
- package/src/utils/css/focus.module.css +7 -5
- package/src/utils/css/global-css-defense.module.css +117 -0
- package/src/utils/css/item-popup.module.css +3 -2
- package/src/utils/css/select-trigger.module.css +1 -0
- package/src/utils/test/use-deprioritized-initial-focus.test.tsx +230 -0
- package/src/utils/types.ts +7 -2
- package/src/utils/use-deprioritized-initial-focus.ts +84 -0
- package/src/visually-hidden/stories/index.story.tsx +25 -0
- package/src/visually-hidden/visually-hidden.tsx +34 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Popover as _Popover } from '@base-ui/react/popover';
|
|
2
|
+
import { useMergeRefs } from '@wordpress/compose';
|
|
3
|
+
import { forwardRef, useLayoutEffect, useRef } from '@wordpress/element';
|
|
4
|
+
import { Text } from '../text';
|
|
5
|
+
import { usePopoverValidationContext } from './context';
|
|
6
|
+
import type { TitleProps } from './types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Renders a heading that labels the popover for accessibility.
|
|
10
|
+
*
|
|
11
|
+
* **Required** — every popover must include a `Popover.Title`, even if
|
|
12
|
+
* visually hidden. The rendered element is linked to the popup via
|
|
13
|
+
* `aria-labelledby`. Uses the `heading-xl` text variant, matching Dialog.
|
|
14
|
+
*
|
|
15
|
+
* To visually hide the title while keeping it accessible, wrap it with
|
|
16
|
+
* `VisuallyHidden` using the `render` prop:
|
|
17
|
+
*
|
|
18
|
+
* ```jsx
|
|
19
|
+
* <VisuallyHidden render={ <Popover.Title /> }>
|
|
20
|
+
* Accessible title text
|
|
21
|
+
* </VisuallyHidden>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
const Title = forwardRef< HTMLHeadingElement, TitleProps >(
|
|
25
|
+
function PopoverTitle( { className, children, ...props }, forwardedRef ) {
|
|
26
|
+
const validationContext = usePopoverValidationContext();
|
|
27
|
+
const internalRef = useRef< HTMLHeadingElement >( null );
|
|
28
|
+
const mergedRef = useMergeRefs( [ internalRef, forwardedRef ] );
|
|
29
|
+
|
|
30
|
+
useLayoutEffect( () => {
|
|
31
|
+
validationContext?.registerTitle( internalRef.current );
|
|
32
|
+
}, [ validationContext ] );
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Text
|
|
36
|
+
ref={ mergedRef }
|
|
37
|
+
variant="heading-xl"
|
|
38
|
+
render={ <_Popover.Title { ...props } /> }
|
|
39
|
+
className={ className }
|
|
40
|
+
>
|
|
41
|
+
{ children }
|
|
42
|
+
</Text>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
export { Title };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Popover as _Popover } from '@base-ui/react/popover';
|
|
2
|
+
import { forwardRef } from '@wordpress/element';
|
|
3
|
+
import type { TriggerProps } from './types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Renders a button that toggles the popover popup when clicked.
|
|
7
|
+
*
|
|
8
|
+
* Renders as a `<button>` by default. Also supports hover-triggered
|
|
9
|
+
* popovers via the `openOnHover`, `delay`, and `closeDelay` props.
|
|
10
|
+
*/
|
|
11
|
+
const Trigger = forwardRef< HTMLButtonElement, TriggerProps >(
|
|
12
|
+
function PopoverTrigger( props, ref ) {
|
|
13
|
+
return <_Popover.Trigger ref={ ref } { ...props } />;
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export { Trigger };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { Popover as _Popover } from '@base-ui/react/popover';
|
|
3
|
+
import type { ComponentProps } from '../utils/types';
|
|
4
|
+
|
|
5
|
+
export interface RootProps
|
|
6
|
+
extends Pick<
|
|
7
|
+
_Popover.Root.Props,
|
|
8
|
+
'open' | 'onOpenChange' | 'defaultOpen' | 'modal'
|
|
9
|
+
> {
|
|
10
|
+
/**
|
|
11
|
+
* The popover sub-components (`Popover.Trigger`, `Popover.Popup`, etc.).
|
|
12
|
+
*/
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface TriggerProps
|
|
17
|
+
extends ComponentProps< 'button' >,
|
|
18
|
+
Pick< _Popover.Trigger.Props, 'openOnHover' | 'delay' | 'closeDelay' > {
|
|
19
|
+
/**
|
|
20
|
+
* The content to be rendered inside the component.
|
|
21
|
+
*/
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `Popover.Popup` maps to two Base UI elements internally: the
|
|
27
|
+
* **Positioner** (outer, handles fixed positioning and z-index) and the
|
|
28
|
+
* **Popup** (inner, holds content and visual styles).
|
|
29
|
+
*
|
|
30
|
+
* `style` and `className` are forwarded to the **Positioner** so that
|
|
31
|
+
* z-index overrides (`--wp-ui-popover-z-index`) and Base UI CSS variables
|
|
32
|
+
* (`--available-height`, `--available-width`) work correctly. All other
|
|
33
|
+
* HTML attributes are forwarded to the inner **Popup** element.
|
|
34
|
+
*/
|
|
35
|
+
export interface PopupProps
|
|
36
|
+
extends ComponentProps< 'div' >,
|
|
37
|
+
Pick<
|
|
38
|
+
_Popover.Positioner.Props,
|
|
39
|
+
| 'align'
|
|
40
|
+
| 'alignOffset'
|
|
41
|
+
| 'anchor'
|
|
42
|
+
| 'arrowPadding'
|
|
43
|
+
| 'collisionAvoidance'
|
|
44
|
+
| 'collisionBoundary'
|
|
45
|
+
| 'collisionPadding'
|
|
46
|
+
| 'side'
|
|
47
|
+
| 'sideOffset'
|
|
48
|
+
| 'sticky'
|
|
49
|
+
>,
|
|
50
|
+
Pick< _Popover.Popup.Props, 'initialFocus' | 'finalFocus' > {
|
|
51
|
+
/**
|
|
52
|
+
* Whether to render a backdrop overlay behind the popover.
|
|
53
|
+
*
|
|
54
|
+
* Typically used with `modal` to signal that interaction with the rest
|
|
55
|
+
* of the page is blocked. The backdrop is a semi-transparent dark overlay.
|
|
56
|
+
*
|
|
57
|
+
* @default false
|
|
58
|
+
*/
|
|
59
|
+
backdrop?: boolean;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The content to be rendered inside the component.
|
|
63
|
+
*/
|
|
64
|
+
children?: ReactNode;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A parent element to render the portal into.
|
|
68
|
+
*
|
|
69
|
+
* Useful for cross-document rendering, such as rendering a popover
|
|
70
|
+
* in a parent document when the trigger is inside an iframe.
|
|
71
|
+
*/
|
|
72
|
+
container?: _Popover.Portal.Props[ 'container' ];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The visual style variant of the popup.
|
|
76
|
+
*
|
|
77
|
+
* - `'default'` — standard surface styling with background, padding,
|
|
78
|
+
* border radius, and shadow.
|
|
79
|
+
* - `'unstyled'` — no visual treatment; useful as a blank positioning
|
|
80
|
+
* container for fully custom content.
|
|
81
|
+
*
|
|
82
|
+
* @default 'default'
|
|
83
|
+
*/
|
|
84
|
+
variant?: 'default' | 'unstyled';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface ArrowProps extends ComponentProps< 'div' > {
|
|
88
|
+
/**
|
|
89
|
+
* Custom arrow visuals to render inside the positioned container.
|
|
90
|
+
*/
|
|
91
|
+
children?: ReactNode;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface TitleProps extends ComponentProps< 'h2' > {
|
|
95
|
+
/**
|
|
96
|
+
* The title content to be rendered.
|
|
97
|
+
*/
|
|
98
|
+
children?: ReactNode;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface DescriptionProps extends ComponentProps< 'p' > {
|
|
102
|
+
/**
|
|
103
|
+
* The description content to be rendered.
|
|
104
|
+
*/
|
|
105
|
+
children?: ReactNode;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface CloseProps extends ComponentProps< 'button' > {
|
|
109
|
+
/**
|
|
110
|
+
* The content to be rendered inside the component.
|
|
111
|
+
*/
|
|
112
|
+
children?: ReactNode;
|
|
113
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
4
|
+
useCallback,
|
|
5
|
+
useMemo,
|
|
6
|
+
useRef,
|
|
7
|
+
useEffect,
|
|
8
|
+
} from '@wordpress/element';
|
|
9
|
+
|
|
10
|
+
type TabsValidationContextType = {
|
|
11
|
+
registerTab: () => () => void;
|
|
12
|
+
registerPanel: () => () => void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Whether validation is enabled. This is a build-time constant that allows
|
|
17
|
+
* bundlers to tree-shake all validation code in production builds.
|
|
18
|
+
*/
|
|
19
|
+
const VALIDATION_ENABLED = process.env.NODE_ENV !== 'production';
|
|
20
|
+
|
|
21
|
+
const TabsValidationContext = VALIDATION_ENABLED
|
|
22
|
+
? createContext< TabsValidationContextType | null >( null )
|
|
23
|
+
: ( null as unknown as React.Context< TabsValidationContextType | null > );
|
|
24
|
+
|
|
25
|
+
function useRegisterTabDev() {
|
|
26
|
+
const context = useContext( TabsValidationContext );
|
|
27
|
+
|
|
28
|
+
useEffect( () => {
|
|
29
|
+
if ( context ) {
|
|
30
|
+
return context.registerTab();
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}, [ context ] );
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function useRegisterTabProd() {
|
|
37
|
+
// No-op in production.
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Hook that registers a Tab for count validation in development mode.
|
|
42
|
+
*/
|
|
43
|
+
export const useRegisterTab = VALIDATION_ENABLED
|
|
44
|
+
? useRegisterTabDev
|
|
45
|
+
: useRegisterTabProd;
|
|
46
|
+
|
|
47
|
+
function useRegisterPanelDev() {
|
|
48
|
+
const context = useContext( TabsValidationContext );
|
|
49
|
+
|
|
50
|
+
useEffect( () => {
|
|
51
|
+
if ( context ) {
|
|
52
|
+
return context.registerPanel();
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}, [ context ] );
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function useRegisterPanelProd() {
|
|
59
|
+
// No-op in production.
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Hook that registers a Panel for count validation in development mode.
|
|
64
|
+
*/
|
|
65
|
+
export const useRegisterPanel = VALIDATION_ENABLED
|
|
66
|
+
? useRegisterPanelDev
|
|
67
|
+
: useRegisterPanelProd;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Development-only provider that tracks the number of registered tabs and
|
|
71
|
+
* panels, and warns when the counts don't match.
|
|
72
|
+
*/
|
|
73
|
+
function TabsValidationProviderDev( {
|
|
74
|
+
children,
|
|
75
|
+
}: {
|
|
76
|
+
children: React.ReactNode;
|
|
77
|
+
} ) {
|
|
78
|
+
const tabCountRef = useRef( 0 );
|
|
79
|
+
const panelCountRef = useRef( 0 );
|
|
80
|
+
const validationScheduledRef = useRef< ReturnType<
|
|
81
|
+
typeof setTimeout
|
|
82
|
+
> | null >( null );
|
|
83
|
+
|
|
84
|
+
const scheduleValidation = useCallback( () => {
|
|
85
|
+
if ( validationScheduledRef.current ) {
|
|
86
|
+
clearTimeout( validationScheduledRef.current );
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Schedule validation for the next tick to allow all
|
|
90
|
+
// registrations/unregistrations to complete.
|
|
91
|
+
validationScheduledRef.current = setTimeout( () => {
|
|
92
|
+
const tabCount = tabCountRef.current;
|
|
93
|
+
const panelCount = panelCountRef.current;
|
|
94
|
+
|
|
95
|
+
if ( tabCount !== panelCount ) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Tabs: Tab/Panel count mismatch (${ tabCount } Tabs, ${ panelCount } Panels). ` +
|
|
98
|
+
`Each Tab must be associated with exactly one Panel. ` +
|
|
99
|
+
`Mismatched or missing associations can break screen reader navigation ` +
|
|
100
|
+
`and violate WAI-ARIA Tabs pattern requirements.`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
validationScheduledRef.current = null;
|
|
105
|
+
}, 0 );
|
|
106
|
+
}, [] );
|
|
107
|
+
|
|
108
|
+
const registerTab = useCallback( () => {
|
|
109
|
+
tabCountRef.current += 1;
|
|
110
|
+
scheduleValidation();
|
|
111
|
+
|
|
112
|
+
return () => {
|
|
113
|
+
tabCountRef.current -= 1;
|
|
114
|
+
scheduleValidation();
|
|
115
|
+
};
|
|
116
|
+
}, [ scheduleValidation ] );
|
|
117
|
+
|
|
118
|
+
const registerPanel = useCallback( () => {
|
|
119
|
+
panelCountRef.current += 1;
|
|
120
|
+
scheduleValidation();
|
|
121
|
+
|
|
122
|
+
return () => {
|
|
123
|
+
panelCountRef.current -= 1;
|
|
124
|
+
scheduleValidation();
|
|
125
|
+
};
|
|
126
|
+
}, [ scheduleValidation ] );
|
|
127
|
+
|
|
128
|
+
useEffect( () => {
|
|
129
|
+
return () => {
|
|
130
|
+
if ( validationScheduledRef.current ) {
|
|
131
|
+
clearTimeout( validationScheduledRef.current );
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}, [] );
|
|
135
|
+
|
|
136
|
+
const contextValue = useMemo(
|
|
137
|
+
() => ( {
|
|
138
|
+
registerTab,
|
|
139
|
+
registerPanel,
|
|
140
|
+
} ),
|
|
141
|
+
[ registerTab, registerPanel ]
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<TabsValidationContext.Provider value={ contextValue }>
|
|
146
|
+
{ children }
|
|
147
|
+
</TabsValidationContext.Provider>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Production no-op provider that just renders children.
|
|
153
|
+
*/
|
|
154
|
+
function TabsValidationProviderProd( {
|
|
155
|
+
children,
|
|
156
|
+
}: {
|
|
157
|
+
children: React.ReactNode;
|
|
158
|
+
} ) {
|
|
159
|
+
return <>{ children }</>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Provider component that validates the number of tabs matches the number
|
|
164
|
+
* of panels in development mode.
|
|
165
|
+
*
|
|
166
|
+
* In production, this component is a no-op and just renders children.
|
|
167
|
+
*/
|
|
168
|
+
export const TabsValidationProvider = VALIDATION_ENABLED
|
|
169
|
+
? TabsValidationProviderDev
|
|
170
|
+
: TabsValidationProviderProd;
|
package/src/tabs/list.tsx
CHANGED
package/src/tabs/panel.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { forwardRef } from '@wordpress/element';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import { Tabs as _Tabs } from '@base-ui/react/tabs';
|
|
4
|
+
import { useRegisterPanel } from './context';
|
|
4
5
|
import styles from './style.module.css';
|
|
5
6
|
import type { TabPanelProps } from './types';
|
|
6
7
|
|
|
@@ -12,6 +13,8 @@ import type { TabPanelProps } from './types';
|
|
|
12
13
|
*/
|
|
13
14
|
export const Panel = forwardRef< HTMLDivElement, TabPanelProps >(
|
|
14
15
|
function TabPanel( { className, ...otherProps }, forwardedRef ) {
|
|
16
|
+
useRegisterPanel();
|
|
17
|
+
|
|
15
18
|
return (
|
|
16
19
|
<_Tabs.Panel
|
|
17
20
|
ref={ forwardedRef }
|
package/src/tabs/root.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { forwardRef } from '@wordpress/element';
|
|
2
2
|
import { Tabs as _Tabs } from '@base-ui/react/tabs';
|
|
3
|
+
import { TabsValidationProvider } from './context';
|
|
3
4
|
import type { TabRootProps } from './types';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -10,6 +11,10 @@ import type { TabRootProps } from './types';
|
|
|
10
11
|
*/
|
|
11
12
|
export const Root = forwardRef< HTMLDivElement, TabRootProps >(
|
|
12
13
|
function TabsRoot( { ...otherProps }, forwardedRef ) {
|
|
13
|
-
return
|
|
14
|
+
return (
|
|
15
|
+
<TabsValidationProvider>
|
|
16
|
+
<_Tabs.Root ref={ forwardedRef } { ...otherProps } />
|
|
17
|
+
</TabsValidationProvider>
|
|
18
|
+
);
|
|
14
19
|
}
|
|
15
20
|
);
|
|
@@ -119,11 +119,11 @@
|
|
|
119
119
|
align-items: center;
|
|
120
120
|
|
|
121
121
|
/* Appearance */
|
|
122
|
-
cursor:
|
|
122
|
+
cursor: var(--wpds-cursor-control);
|
|
123
123
|
|
|
124
124
|
/* Typography */
|
|
125
|
-
font-family: var(--wpds-font-family-body);
|
|
126
|
-
font-size: var(--wpds-font-size-md);
|
|
125
|
+
font-family: var(--wpds-typography-font-family-body);
|
|
126
|
+
font-size: var(--wpds-typography-font-size-md);
|
|
127
127
|
white-space: nowrap;
|
|
128
128
|
|
|
129
129
|
/* Characters in some languages (e.g. Japanese) may have a native higher line-height. */
|
package/src/tabs/tab.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import clsx from 'clsx';
|
|
|
3
3
|
import { Tabs as _Tabs } from '@base-ui/react/tabs';
|
|
4
4
|
import { chevronRight } from '@wordpress/icons';
|
|
5
5
|
import { Icon } from '../icon';
|
|
6
|
+
import { useRegisterTab } from './context';
|
|
6
7
|
import styles from './style.module.css';
|
|
7
8
|
import type { TabProps } from './types';
|
|
8
9
|
|
|
@@ -16,6 +17,8 @@ export const Tab = forwardRef< HTMLButtonElement, TabProps >( function Tab(
|
|
|
16
17
|
{ className, children, ...otherProps },
|
|
17
18
|
forwardedRef
|
|
18
19
|
) {
|
|
20
|
+
useRegisterTab();
|
|
21
|
+
|
|
19
22
|
return (
|
|
20
23
|
<_Tabs.Tab
|
|
21
24
|
ref={ forwardedRef }
|
|
@@ -2256,5 +2256,167 @@ describe( 'Tabs', () => {
|
|
|
2256
2256
|
);
|
|
2257
2257
|
} );
|
|
2258
2258
|
} );
|
|
2259
|
+
|
|
2260
|
+
describe( 'Development mode validation', () => {
|
|
2261
|
+
function collectUncaughtErrors() {
|
|
2262
|
+
const errors: Error[] = [];
|
|
2263
|
+
const handler = ( event: ErrorEvent ) => {
|
|
2264
|
+
event.preventDefault();
|
|
2265
|
+
errors.push( event.error );
|
|
2266
|
+
};
|
|
2267
|
+
window.addEventListener( 'error', handler );
|
|
2268
|
+
return {
|
|
2269
|
+
errors,
|
|
2270
|
+
cleanup: () => window.removeEventListener( 'error', handler ),
|
|
2271
|
+
};
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
it( 'should throw when there are more Tabs than Panels', async () => {
|
|
2275
|
+
const { errors, cleanup } = collectUncaughtErrors();
|
|
2276
|
+
|
|
2277
|
+
render(
|
|
2278
|
+
<Tabs.Root defaultValue="one">
|
|
2279
|
+
<Tabs.List>
|
|
2280
|
+
<Tabs.Tab value="one">One</Tabs.Tab>
|
|
2281
|
+
<Tabs.Tab value="two">Two</Tabs.Tab>
|
|
2282
|
+
<Tabs.Tab value="three">Three</Tabs.Tab>
|
|
2283
|
+
</Tabs.List>
|
|
2284
|
+
<Tabs.Panel value="one">First panel</Tabs.Panel>
|
|
2285
|
+
<Tabs.Panel value="two">Second panel</Tabs.Panel>
|
|
2286
|
+
</Tabs.Root>
|
|
2287
|
+
);
|
|
2288
|
+
|
|
2289
|
+
await waitForComponentToBeInitializedWithSelectedTab( 'One' );
|
|
2290
|
+
|
|
2291
|
+
await waitFor( () => {
|
|
2292
|
+
expect( errors.length ).toBeGreaterThan( 0 );
|
|
2293
|
+
} );
|
|
2294
|
+
|
|
2295
|
+
expect( errors[ 0 ].message ).toBe(
|
|
2296
|
+
'Tabs: Tab/Panel count mismatch (3 Tabs, 2 Panels). Each Tab must be associated with exactly one Panel. Mismatched or missing associations can break screen reader navigation and violate WAI-ARIA Tabs pattern requirements.'
|
|
2297
|
+
);
|
|
2298
|
+
|
|
2299
|
+
cleanup();
|
|
2300
|
+
} );
|
|
2301
|
+
|
|
2302
|
+
it( 'should throw when there are more Panels than Tabs', async () => {
|
|
2303
|
+
const { errors, cleanup } = collectUncaughtErrors();
|
|
2304
|
+
|
|
2305
|
+
render(
|
|
2306
|
+
<Tabs.Root defaultValue="one">
|
|
2307
|
+
<Tabs.List>
|
|
2308
|
+
<Tabs.Tab value="one">One</Tabs.Tab>
|
|
2309
|
+
<Tabs.Tab value="two">Two</Tabs.Tab>
|
|
2310
|
+
</Tabs.List>
|
|
2311
|
+
<Tabs.Panel value="one">First panel</Tabs.Panel>
|
|
2312
|
+
<Tabs.Panel value="two">Second panel</Tabs.Panel>
|
|
2313
|
+
<Tabs.Panel value="three">Third panel</Tabs.Panel>
|
|
2314
|
+
</Tabs.Root>
|
|
2315
|
+
);
|
|
2316
|
+
|
|
2317
|
+
await waitForComponentToBeInitializedWithSelectedTab( 'One' );
|
|
2318
|
+
|
|
2319
|
+
await waitFor( () => {
|
|
2320
|
+
expect( errors.length ).toBeGreaterThan( 0 );
|
|
2321
|
+
} );
|
|
2322
|
+
|
|
2323
|
+
expect( errors[ 0 ].message ).toBe(
|
|
2324
|
+
'Tabs: Tab/Panel count mismatch (2 Tabs, 3 Panels). Each Tab must be associated with exactly one Panel. Mismatched or missing associations can break screen reader navigation and violate WAI-ARIA Tabs pattern requirements.'
|
|
2325
|
+
);
|
|
2326
|
+
|
|
2327
|
+
cleanup();
|
|
2328
|
+
} );
|
|
2329
|
+
|
|
2330
|
+
it( 'should not throw when Tab and Panel counts match', async () => {
|
|
2331
|
+
const { errors, cleanup } = collectUncaughtErrors();
|
|
2332
|
+
|
|
2333
|
+
render(
|
|
2334
|
+
<Tabs.Root defaultValue="one">
|
|
2335
|
+
<Tabs.List>
|
|
2336
|
+
<Tabs.Tab value="one">One</Tabs.Tab>
|
|
2337
|
+
<Tabs.Tab value="two">Two</Tabs.Tab>
|
|
2338
|
+
</Tabs.List>
|
|
2339
|
+
<Tabs.Panel value="one">First panel</Tabs.Panel>
|
|
2340
|
+
<Tabs.Panel value="two">Second panel</Tabs.Panel>
|
|
2341
|
+
</Tabs.Root>
|
|
2342
|
+
);
|
|
2343
|
+
|
|
2344
|
+
await waitForComponentToBeInitializedWithSelectedTab( 'One' );
|
|
2345
|
+
|
|
2346
|
+
// Wait a bit to ensure validation has run
|
|
2347
|
+
await new Promise( ( resolve ) => setTimeout( resolve, 50 ) );
|
|
2348
|
+
|
|
2349
|
+
expect( errors ).toHaveLength( 0 );
|
|
2350
|
+
|
|
2351
|
+
cleanup();
|
|
2352
|
+
} );
|
|
2353
|
+
|
|
2354
|
+
it( 'should throw when tabs are used without any panels', async () => {
|
|
2355
|
+
const { errors, cleanup } = collectUncaughtErrors();
|
|
2356
|
+
|
|
2357
|
+
render(
|
|
2358
|
+
<Tabs.Root>
|
|
2359
|
+
<Tabs.List>
|
|
2360
|
+
<Tabs.Tab value="one">One</Tabs.Tab>
|
|
2361
|
+
<Tabs.Tab value="two">Two</Tabs.Tab>
|
|
2362
|
+
</Tabs.List>
|
|
2363
|
+
</Tabs.Root>
|
|
2364
|
+
);
|
|
2365
|
+
|
|
2366
|
+
await waitFor( () => {
|
|
2367
|
+
expect( errors.length ).toBeGreaterThan( 0 );
|
|
2368
|
+
} );
|
|
2369
|
+
|
|
2370
|
+
expect( errors[ 0 ].message ).toBe(
|
|
2371
|
+
'Tabs: Tab/Panel count mismatch (2 Tabs, 0 Panels). Each Tab must be associated with exactly one Panel. Mismatched or missing associations can break screen reader navigation and violate WAI-ARIA Tabs pattern requirements.'
|
|
2372
|
+
);
|
|
2373
|
+
|
|
2374
|
+
cleanup();
|
|
2375
|
+
} );
|
|
2376
|
+
|
|
2377
|
+
it( 'should detect count mismatch after dynamic changes', async () => {
|
|
2378
|
+
const { errors, cleanup } = collectUncaughtErrors();
|
|
2379
|
+
|
|
2380
|
+
const { rerender } = render(
|
|
2381
|
+
<Tabs.Root defaultValue="one">
|
|
2382
|
+
<Tabs.List>
|
|
2383
|
+
<Tabs.Tab value="one">One</Tabs.Tab>
|
|
2384
|
+
<Tabs.Tab value="two">Two</Tabs.Tab>
|
|
2385
|
+
</Tabs.List>
|
|
2386
|
+
<Tabs.Panel value="one">First panel</Tabs.Panel>
|
|
2387
|
+
<Tabs.Panel value="two">Second panel</Tabs.Panel>
|
|
2388
|
+
</Tabs.Root>
|
|
2389
|
+
);
|
|
2390
|
+
|
|
2391
|
+
await waitForComponentToBeInitializedWithSelectedTab( 'One' );
|
|
2392
|
+
|
|
2393
|
+
// Wait for validation
|
|
2394
|
+
await new Promise( ( resolve ) => setTimeout( resolve, 50 ) );
|
|
2395
|
+
|
|
2396
|
+
// No errors since counts match
|
|
2397
|
+
expect( errors ).toHaveLength( 0 );
|
|
2398
|
+
|
|
2399
|
+
// Remove a panel to create a mismatch
|
|
2400
|
+
rerender(
|
|
2401
|
+
<Tabs.Root defaultValue="one">
|
|
2402
|
+
<Tabs.List>
|
|
2403
|
+
<Tabs.Tab value="one">One</Tabs.Tab>
|
|
2404
|
+
<Tabs.Tab value="two">Two</Tabs.Tab>
|
|
2405
|
+
</Tabs.List>
|
|
2406
|
+
<Tabs.Panel value="one">First panel</Tabs.Panel>
|
|
2407
|
+
</Tabs.Root>
|
|
2408
|
+
);
|
|
2409
|
+
|
|
2410
|
+
await waitFor( () => {
|
|
2411
|
+
expect( errors.length ).toBeGreaterThan( 0 );
|
|
2412
|
+
} );
|
|
2413
|
+
|
|
2414
|
+
expect( errors[ 0 ].message ).toBe(
|
|
2415
|
+
'Tabs: Tab/Panel count mismatch (2 Tabs, 1 Panels). Each Tab must be associated with exactly one Panel. Mismatched or missing associations can break screen reader navigation and violate WAI-ARIA Tabs pattern requirements.'
|
|
2416
|
+
);
|
|
2417
|
+
|
|
2418
|
+
cleanup();
|
|
2419
|
+
} );
|
|
2420
|
+
} );
|
|
2259
2421
|
} );
|
|
2260
2422
|
/* eslint-enable jest/no-conditional-expect */
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable jsx-a11y/heading-has-content */
|
|
2
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
2
|
import { Text } from '../index';
|
|
4
3
|
import { Stack } from '../../stack';
|
|
@@ -18,6 +17,10 @@ export const Default: Story = {
|
|
|
18
17
|
},
|
|
19
18
|
};
|
|
20
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Important: Setting the `variant` prop to a `heading` variant will not automatically render a heading element.
|
|
22
|
+
* Use the `render` prop to render a heading element with the appropriate level.
|
|
23
|
+
*/
|
|
21
24
|
export const AllVariants: Story = {
|
|
22
25
|
render: () => (
|
|
23
26
|
<Stack
|
|
@@ -65,4 +68,3 @@ export const WithRenderProp: Story = {
|
|
|
65
68
|
</Stack>
|
|
66
69
|
),
|
|
67
70
|
};
|
|
68
|
-
/* eslint-enable jsx-a11y/heading-has-content */
|