@wordpress/ui 0.8.1-next.v.202602271551.0 → 0.9.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 +32 -1
- package/README.md +106 -0
- package/build/badge/badge.cjs +3 -3
- package/build/badge/badge.cjs.map +2 -2
- package/build/button/button.cjs +7 -7
- package/build/button/button.cjs.map +2 -2
- package/build/card/content.cjs +54 -0
- package/build/card/content.cjs.map +7 -0
- package/build/card/full-bleed.cjs +57 -0
- package/build/card/full-bleed.cjs.map +7 -0
- package/build/card/header.cjs +54 -0
- package/build/card/header.cjs.map +7 -0
- package/build/card/index.cjs +43 -0
- package/build/card/index.cjs.map +7 -0
- package/build/card/root.cjs +73 -0
- package/build/card/root.cjs.map +7 -0
- package/build/card/title.cjs +55 -0
- package/build/card/title.cjs.map +7 -0
- package/build/card/types.cjs +19 -0
- package/build/card/types.cjs.map +7 -0
- package/build/collapsible/index.cjs +37 -0
- package/build/collapsible/index.cjs.map +7 -0
- package/build/{form/primitives/input-layout/context.cjs → collapsible/panel.cjs} +12 -23
- package/build/collapsible/panel.cjs.map +7 -0
- package/build/collapsible/root.cjs +38 -0
- package/build/collapsible/root.cjs.map +7 -0
- package/build/collapsible/trigger.cjs +38 -0
- package/build/collapsible/trigger.cjs.map +7 -0
- package/build/collapsible/types.cjs +19 -0
- package/build/collapsible/types.cjs.map +7 -0
- package/build/collapsible-card/content.cjs +77 -0
- package/build/collapsible-card/content.cjs.map +7 -0
- package/build/collapsible-card/header.cjs +102 -0
- package/build/collapsible-card/header.cjs.map +7 -0
- package/build/collapsible-card/index.cjs +37 -0
- package/build/collapsible-card/index.cjs.map +7 -0
- package/build/collapsible-card/root.cjs +56 -0
- package/build/collapsible-card/root.cjs.map +7 -0
- package/build/collapsible-card/types.cjs +19 -0
- package/build/collapsible-card/types.cjs.map +7 -0
- 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 +3 -3
- package/build/dialog/popup.cjs.map +2 -2
- package/build/dialog/title.cjs +3 -3
- package/build/dialog/title.cjs.map +2 -2
- package/build/dialog/types.cjs.map +1 -1
- package/build/form/primitives/field/label.cjs +6 -1
- package/build/form/primitives/field/label.cjs.map +2 -2
- package/build/form/primitives/field/types.cjs.map +1 -1
- package/build/form/primitives/fieldset/legend.cjs +5 -1
- package/build/form/primitives/fieldset/legend.cjs.map +2 -2
- package/build/form/primitives/fieldset/types.cjs.map +1 -1
- package/build/form/primitives/input/input.cjs +4 -4
- package/build/form/primitives/input/input.cjs.map +2 -2
- package/build/form/primitives/input-layout/input-layout.cjs +20 -7
- package/build/form/primitives/input-layout/input-layout.cjs.map +2 -2
- package/build/form/primitives/input-layout/slot.cjs +7 -15
- package/build/form/primitives/input-layout/slot.cjs.map +2 -2
- package/build/form/primitives/input-layout/types.cjs.map +1 -1
- package/build/form/primitives/select/item.cjs +3 -3
- package/build/form/primitives/select/item.cjs.map +2 -2
- package/build/form/primitives/select/popup.cjs +3 -3
- package/build/form/primitives/select/popup.cjs.map +2 -2
- package/build/form/primitives/select/trigger.cjs +7 -7
- package/build/form/primitives/select/trigger.cjs.map +2 -2
- package/build/index.cjs +13 -0
- package/build/index.cjs.map +2 -2
- package/build/link/index.cjs +31 -0
- package/build/link/index.cjs.map +7 -0
- package/build/link/link.cjs +125 -0
- package/build/link/link.cjs.map +7 -0
- package/build/link/types.cjs +19 -0
- package/build/link/types.cjs.map +7 -0
- package/build/notice/action-button.cjs +3 -3
- package/build/notice/action-button.cjs.map +2 -2
- package/build/notice/action-link.cjs +17 -18
- 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 +26 -15
- package/build/notice/description.cjs.map +3 -3
- package/build/notice/root.cjs +3 -3
- package/build/notice/root.cjs.map +2 -2
- package/build/notice/title.cjs +26 -12
- package/build/notice/title.cjs.map +3 -3
- package/build/notice/types.cjs.map +1 -1
- package/build/tabs/list.cjs +3 -3
- package/build/tabs/list.cjs.map +2 -2
- package/build/tabs/panel.cjs +3 -3
- package/build/tabs/panel.cjs.map +2 -2
- package/build/tabs/tab.cjs +3 -3
- package/build/tabs/tab.cjs.map +2 -2
- package/build/text/index.cjs +31 -0
- package/build/text/index.cjs.map +7 -0
- package/build/text/text.cjs +65 -0
- package/build/text/text.cjs.map +7 -0
- package/build/text/types.cjs +19 -0
- package/build/text/types.cjs.map +7 -0
- package/build/tooltip/popup.cjs +1 -1
- package/build/tooltip/popup.cjs.map +1 -1
- package/build/visually-hidden/visually-hidden.cjs +3 -3
- package/build/visually-hidden/visually-hidden.cjs.map +2 -2
- package/build-module/badge/badge.mjs +3 -3
- package/build-module/badge/badge.mjs.map +2 -2
- package/build-module/button/button.mjs +7 -7
- package/build-module/button/button.mjs.map +2 -2
- package/build-module/card/content.mjs +29 -0
- package/build-module/card/content.mjs.map +7 -0
- package/build-module/card/full-bleed.mjs +32 -0
- package/build-module/card/full-bleed.mjs.map +7 -0
- package/build-module/card/header.mjs +29 -0
- package/build-module/card/header.mjs.map +7 -0
- package/build-module/card/index.mjs +14 -0
- package/build-module/card/index.mjs.map +7 -0
- package/build-module/card/root.mjs +38 -0
- package/build-module/card/root.mjs.map +7 -0
- package/build-module/card/title.mjs +30 -0
- package/build-module/card/title.mjs.map +7 -0
- package/build-module/card/types.mjs +1 -0
- package/build-module/card/types.mjs.map +7 -0
- package/build-module/collapsible/index.mjs +10 -0
- package/build-module/collapsible/index.mjs.map +7 -0
- package/build-module/collapsible/panel.mjs +13 -0
- package/build-module/collapsible/panel.mjs.map +7 -0
- package/build-module/collapsible/root.mjs +13 -0
- package/build-module/collapsible/root.mjs.map +7 -0
- package/build-module/collapsible/trigger.mjs +13 -0
- package/build-module/collapsible/trigger.mjs.map +7 -0
- package/build-module/collapsible/types.mjs +1 -0
- package/build-module/collapsible/types.mjs.map +7 -0
- package/build-module/collapsible-card/content.mjs +42 -0
- package/build-module/collapsible-card/content.mjs.map +7 -0
- package/build-module/collapsible-card/header.mjs +67 -0
- package/build-module/collapsible-card/header.mjs.map +7 -0
- package/build-module/collapsible-card/index.mjs +10 -0
- package/build-module/collapsible-card/index.mjs.map +7 -0
- package/build-module/collapsible-card/root.mjs +21 -0
- package/build-module/collapsible-card/root.mjs.map +7 -0
- package/build-module/collapsible-card/types.mjs +1 -0
- package/build-module/collapsible-card/types.mjs.map +7 -0
- 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 +3 -3
- package/build-module/dialog/popup.mjs.map +2 -2
- package/build-module/dialog/title.mjs +3 -3
- package/build-module/dialog/title.mjs.map +2 -2
- package/build-module/form/primitives/field/label.mjs +6 -1
- package/build-module/form/primitives/field/label.mjs.map +2 -2
- package/build-module/form/primitives/fieldset/legend.mjs +5 -1
- package/build-module/form/primitives/fieldset/legend.mjs.map +2 -2
- package/build-module/form/primitives/input/input.mjs +4 -4
- package/build-module/form/primitives/input/input.mjs.map +2 -2
- package/build-module/form/primitives/input-layout/input-layout.mjs +21 -8
- package/build-module/form/primitives/input-layout/input-layout.mjs.map +2 -2
- package/build-module/form/primitives/input-layout/slot.mjs +7 -15
- package/build-module/form/primitives/input-layout/slot.mjs.map +2 -2
- package/build-module/form/primitives/select/item.mjs +3 -3
- package/build-module/form/primitives/select/item.mjs.map +2 -2
- package/build-module/form/primitives/select/popup.mjs +3 -3
- package/build-module/form/primitives/select/popup.mjs.map +2 -2
- package/build-module/form/primitives/select/trigger.mjs +7 -7
- package/build-module/form/primitives/select/trigger.mjs.map +2 -2
- package/build-module/index.mjs +8 -0
- package/build-module/index.mjs.map +2 -2
- package/build-module/link/index.mjs +6 -0
- package/build-module/link/index.mjs.map +7 -0
- package/build-module/link/link.mjs +90 -0
- package/build-module/link/link.mjs.map +7 -0
- package/build-module/link/types.mjs +1 -0
- package/build-module/link/types.mjs.map +7 -0
- 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 +17 -18
- 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 +16 -15
- package/build-module/notice/description.mjs.map +2 -2
- package/build-module/notice/root.mjs +3 -3
- package/build-module/notice/root.mjs.map +2 -2
- package/build-module/notice/title.mjs +16 -12
- package/build-module/notice/title.mjs.map +2 -2
- package/build-module/tabs/list.mjs +3 -3
- package/build-module/tabs/list.mjs.map +2 -2
- package/build-module/tabs/panel.mjs +3 -3
- package/build-module/tabs/panel.mjs.map +2 -2
- package/build-module/tabs/tab.mjs +3 -3
- package/build-module/tabs/tab.mjs.map +2 -2
- package/build-module/text/index.mjs +6 -0
- package/build-module/text/index.mjs.map +7 -0
- package/build-module/text/text.mjs +30 -0
- package/build-module/text/text.mjs.map +7 -0
- package/build-module/text/types.mjs +1 -0
- package/build-module/text/types.mjs.map +7 -0
- package/build-module/tooltip/popup.mjs +1 -1
- package/build-module/tooltip/popup.mjs.map +1 -1
- package/build-module/visually-hidden/visually-hidden.mjs +3 -3
- package/build-module/visually-hidden/visually-hidden.mjs.map +2 -2
- package/build-types/card/content.d.ts +6 -0
- package/build-types/card/content.d.ts.map +1 -0
- package/build-types/card/full-bleed.d.ts +9 -0
- package/build-types/card/full-bleed.d.ts.map +1 -0
- package/build-types/card/header.d.ts +7 -0
- package/build-types/card/header.d.ts.map +1 -0
- package/build-types/card/index.d.ts +7 -0
- package/build-types/card/index.d.ts.map +1 -0
- package/build-types/card/root.d.ts +23 -0
- package/build-types/card/root.d.ts.map +1 -0
- package/build-types/card/stories/index.story.d.ts +22 -0
- package/build-types/card/stories/index.story.d.ts.map +1 -0
- package/build-types/card/test/index.test.d.ts +2 -0
- package/build-types/card/test/index.test.d.ts.map +1 -0
- package/build-types/card/title.d.ts +7 -0
- package/build-types/card/title.d.ts.map +1 -0
- package/build-types/card/types.d.ts +34 -0
- package/build-types/card/types.d.ts.map +1 -0
- package/build-types/collapsible/index.d.ts +5 -0
- package/build-types/collapsible/index.d.ts.map +1 -0
- package/build-types/collapsible/panel.d.ts +16 -0
- package/build-types/collapsible/panel.d.ts.map +1 -0
- package/build-types/collapsible/root.d.ts +15 -0
- package/build-types/collapsible/root.d.ts.map +1 -0
- package/build-types/collapsible/stories/index.story.d.ts +18 -0
- package/build-types/collapsible/stories/index.story.d.ts.map +1 -0
- package/build-types/collapsible/test/index.test.d.ts +2 -0
- package/build-types/collapsible/test/index.test.d.ts.map +1 -0
- package/build-types/collapsible/trigger.d.ts +15 -0
- package/build-types/collapsible/trigger.d.ts.map +1 -0
- package/build-types/collapsible/types.d.ts +22 -0
- package/build-types/collapsible/types.d.ts.map +1 -0
- package/build-types/collapsible-card/content.d.ts +7 -0
- package/build-types/collapsible-card/content.d.ts.map +1 -0
- package/build-types/collapsible-card/header.d.ts +12 -0
- package/build-types/collapsible-card/header.d.ts.map +1 -0
- package/build-types/collapsible-card/index.d.ts +5 -0
- package/build-types/collapsible-card/index.d.ts.map +1 -0
- package/build-types/collapsible-card/root.d.ts +24 -0
- package/build-types/collapsible-card/root.d.ts.map +1 -0
- package/build-types/collapsible-card/stories/index.story.d.ts +28 -0
- package/build-types/collapsible-card/stories/index.story.d.ts.map +1 -0
- package/build-types/collapsible-card/test/index.test.d.ts +2 -0
- package/build-types/collapsible-card/test/index.test.d.ts.map +1 -0
- package/build-types/collapsible-card/types.d.ts +52 -0
- package/build-types/collapsible-card/types.d.ts.map +1 -0
- package/build-types/dialog/types.d.ts +3 -3
- package/build-types/form/primitives/field/label.d.ts +1 -0
- package/build-types/form/primitives/field/label.d.ts.map +1 -1
- package/build-types/form/primitives/field/stories/index.story.d.ts +5 -0
- package/build-types/form/primitives/field/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/field/types.d.ts +7 -0
- package/build-types/form/primitives/field/types.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/legend.d.ts +1 -0
- package/build-types/form/primitives/fieldset/legend.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/stories/index.story.d.ts +5 -0
- package/build-types/form/primitives/fieldset/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/types.d.ts +7 -0
- package/build-types/form/primitives/fieldset/types.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/types.d.ts +1 -9
- package/build-types/form/primitives/input-layout/types.d.ts.map +1 -1
- package/build-types/index.d.ts +5 -0
- package/build-types/index.d.ts.map +1 -1
- package/build-types/link/index.d.ts +2 -0
- package/build-types/link/index.d.ts.map +1 -0
- package/build-types/link/link.d.ts +7 -0
- package/build-types/link/link.d.ts.map +1 -0
- package/build-types/link/stories/index.story.d.ts +18 -0
- package/build-types/link/stories/index.story.d.ts.map +1 -0
- package/build-types/link/test/index.test.d.ts +2 -0
- package/build-types/link/test/index.test.d.ts.map +1 -0
- package/build-types/link/types.d.ts +33 -0
- package/build-types/link/types.d.ts.map +1 -0
- package/build-types/notice/action-link.d.ts +0 -2
- package/build-types/notice/action-link.d.ts.map +1 -1
- package/build-types/notice/description.d.ts +1 -1
- package/build-types/notice/description.d.ts.map +1 -1
- package/build-types/notice/title.d.ts.map +1 -1
- package/build-types/notice/types.d.ts +3 -2
- package/build-types/notice/types.d.ts.map +1 -1
- package/build-types/text/index.d.ts +2 -0
- package/build-types/text/index.d.ts.map +1 -0
- package/build-types/text/stories/index.story.d.ts +9 -0
- package/build-types/text/stories/index.story.d.ts.map +1 -0
- package/build-types/text/test/index.test.d.ts +2 -0
- package/build-types/text/test/index.test.d.ts.map +1 -0
- package/build-types/text/text.d.ts +7 -0
- package/build-types/text/text.d.ts.map +1 -0
- package/build-types/text/types.d.ts +15 -0
- package/build-types/text/types.d.ts.map +1 -0
- package/package.json +14 -14
- package/src/badge/style.module.css +5 -2
- package/src/button/style.module.css +2 -0
- package/src/card/content.tsx +20 -0
- package/src/card/full-bleed.tsx +26 -0
- package/src/card/header.tsx +21 -0
- package/src/card/index.ts +7 -0
- package/src/card/root.tsx +42 -0
- package/src/card/stories/index.story.tsx +128 -0
- package/src/card/style.module.css +48 -0
- package/src/card/test/index.test.tsx +96 -0
- package/src/card/title.tsx +22 -0
- package/src/card/types.ts +38 -0
- package/src/collapsible/index.ts +5 -0
- package/src/collapsible/panel.tsx +16 -0
- package/src/collapsible/root.tsx +15 -0
- package/src/collapsible/stories/index.story.tsx +108 -0
- package/src/collapsible/test/index.test.tsx +228 -0
- package/src/collapsible/trigger.tsx +15 -0
- package/src/collapsible/types.ts +24 -0
- package/src/collapsible-card/content.tsx +33 -0
- package/src/collapsible-card/header.tsx +53 -0
- package/src/collapsible-card/index.ts +5 -0
- package/src/collapsible-card/root.tsx +37 -0
- package/src/collapsible-card/stories/index.story.tsx +207 -0
- package/src/collapsible-card/style.module.css +78 -0
- package/src/collapsible-card/test/index.test.tsx +181 -0
- package/src/collapsible-card/types.ts +54 -0
- package/src/dialog/style.module.css +5 -5
- package/src/dialog/types.ts +3 -3
- package/src/form/primitives/field/label.tsx +9 -1
- package/src/form/primitives/field/stories/index.story.tsx +17 -0
- package/src/form/primitives/field/test/index.test.tsx +13 -0
- package/src/form/primitives/field/types.ts +7 -0
- package/src/form/primitives/fieldset/legend.tsx +8 -1
- package/src/form/primitives/fieldset/stories/index.story.tsx +20 -0
- package/src/form/primitives/fieldset/test/index.test.tsx +14 -0
- package/src/form/primitives/fieldset/types.ts +7 -0
- package/src/form/primitives/input-layout/input-layout.tsx +17 -8
- package/src/form/primitives/input-layout/slot.tsx +3 -13
- package/src/form/primitives/input-layout/style.module.css +6 -2
- package/src/form/primitives/input-layout/test/index.test.tsx +34 -1
- package/src/form/primitives/input-layout/types.ts +1 -10
- package/src/index.ts +5 -0
- package/src/link/index.ts +1 -0
- package/src/link/link.tsx +73 -0
- package/src/link/stories/index.story.tsx +92 -0
- package/src/link/style.module.css +68 -0
- package/src/link/test/index.test.tsx +93 -0
- package/src/link/types.ts +36 -0
- package/src/notice/action-link.tsx +12 -18
- package/src/notice/description.tsx +12 -14
- package/src/notice/style.module.css +9 -22
- package/src/notice/test/index.test.tsx +2 -2
- package/src/notice/title.tsx +11 -10
- package/src/notice/types.ts +3 -2
- package/src/tabs/style.module.css +1 -1
- package/src/text/index.ts +1 -0
- package/src/text/stories/index.story.tsx +68 -0
- package/src/text/style.module.css +67 -0
- package/src/text/test/index.test.tsx +46 -0
- package/src/text/text.tsx +25 -0
- package/src/text/types.ts +25 -0
- package/src/tooltip/popup.tsx +1 -1
- package/src/utils/css/focus.module.css +4 -2
- package/src/utils/css/item-popup.module.css +1 -0
- package/src/utils/css/select-trigger.module.css +1 -0
- package/src/visually-hidden/style.module.css +1 -0
- package/AGENTS.md +0 -9
- package/CLAUDE.md +0 -1
- package/build/form/primitives/input-layout/context.cjs.map +0 -7
- package/build-module/form/primitives/input-layout/context.mjs +0 -22
- package/build-module/form/primitives/input-layout/context.mjs.map +0 -7
- package/build-types/form/primitives/input-layout/context.d.ts +0 -17
- package/build-types/form/primitives/input-layout/context.d.ts.map +0 -1
- package/src/form/primitives/input-layout/context.tsx +0 -36
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { userEvent } from '@testing-library/user-event';
|
|
3
|
+
import { createRef } from '@wordpress/element';
|
|
4
|
+
import * as Card from '../../card';
|
|
5
|
+
import * as CollapsibleCard from '../index';
|
|
6
|
+
|
|
7
|
+
describe( 'CollapsibleCard', () => {
|
|
8
|
+
describe( 'basic behaviour', () => {
|
|
9
|
+
it( 'forwards ref', () => {
|
|
10
|
+
const rootRef = createRef< HTMLDivElement >();
|
|
11
|
+
const headerRef = createRef< HTMLDivElement >();
|
|
12
|
+
const contentRef = createRef< HTMLDivElement >();
|
|
13
|
+
|
|
14
|
+
render(
|
|
15
|
+
<CollapsibleCard.Root ref={ rootRef } defaultOpen>
|
|
16
|
+
<CollapsibleCard.Header ref={ headerRef }>
|
|
17
|
+
<Card.Title>Title</Card.Title>
|
|
18
|
+
</CollapsibleCard.Header>
|
|
19
|
+
<CollapsibleCard.Content ref={ contentRef }>
|
|
20
|
+
<p>Content</p>
|
|
21
|
+
</CollapsibleCard.Content>
|
|
22
|
+
</CollapsibleCard.Root>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
expect( rootRef.current ).toBeInstanceOf( HTMLDivElement );
|
|
26
|
+
expect( headerRef.current ).toBeInstanceOf( HTMLDivElement );
|
|
27
|
+
expect( contentRef.current ).toBeInstanceOf( HTMLDivElement );
|
|
28
|
+
} );
|
|
29
|
+
|
|
30
|
+
it( 'renders header content', () => {
|
|
31
|
+
render(
|
|
32
|
+
<CollapsibleCard.Root>
|
|
33
|
+
<CollapsibleCard.Header>
|
|
34
|
+
<Card.Title>Card heading</Card.Title>
|
|
35
|
+
</CollapsibleCard.Header>
|
|
36
|
+
</CollapsibleCard.Root>
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
expect( screen.getByText( 'Card heading' ) ).toBeVisible();
|
|
40
|
+
} );
|
|
41
|
+
} );
|
|
42
|
+
|
|
43
|
+
describe( 'collapsing', () => {
|
|
44
|
+
it( 'hides content when collapsed (default)', () => {
|
|
45
|
+
render(
|
|
46
|
+
<CollapsibleCard.Root>
|
|
47
|
+
<CollapsibleCard.Header>
|
|
48
|
+
<Card.Title>Title</Card.Title>
|
|
49
|
+
</CollapsibleCard.Header>
|
|
50
|
+
<CollapsibleCard.Content>
|
|
51
|
+
<p>Hidden content</p>
|
|
52
|
+
</CollapsibleCard.Content>
|
|
53
|
+
</CollapsibleCard.Root>
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
expect( screen.getByText( 'Hidden content' ) ).not.toBeVisible();
|
|
57
|
+
} );
|
|
58
|
+
|
|
59
|
+
it( 'shows content when defaultOpen is true', () => {
|
|
60
|
+
render(
|
|
61
|
+
<CollapsibleCard.Root defaultOpen>
|
|
62
|
+
<CollapsibleCard.Header>
|
|
63
|
+
<Card.Title>Title</Card.Title>
|
|
64
|
+
</CollapsibleCard.Header>
|
|
65
|
+
<CollapsibleCard.Content>
|
|
66
|
+
<p>Visible content</p>
|
|
67
|
+
</CollapsibleCard.Content>
|
|
68
|
+
</CollapsibleCard.Root>
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
expect( screen.getByText( 'Visible content' ) ).toBeVisible();
|
|
72
|
+
} );
|
|
73
|
+
|
|
74
|
+
it( 'toggles content on trigger click', async () => {
|
|
75
|
+
const user = userEvent.setup();
|
|
76
|
+
|
|
77
|
+
render(
|
|
78
|
+
<CollapsibleCard.Root>
|
|
79
|
+
<CollapsibleCard.Header>
|
|
80
|
+
<Card.Title>Title</Card.Title>
|
|
81
|
+
</CollapsibleCard.Header>
|
|
82
|
+
<CollapsibleCard.Content>
|
|
83
|
+
<p>Toggle content</p>
|
|
84
|
+
</CollapsibleCard.Content>
|
|
85
|
+
</CollapsibleCard.Root>
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
expect( screen.getByText( 'Toggle content' ) ).not.toBeVisible();
|
|
89
|
+
|
|
90
|
+
await user.click(
|
|
91
|
+
screen.getByRole( 'button', {
|
|
92
|
+
name: 'Title',
|
|
93
|
+
expanded: false,
|
|
94
|
+
} )
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
expect( screen.getByText( 'Toggle content' ) ).toBeVisible();
|
|
98
|
+
|
|
99
|
+
await user.click(
|
|
100
|
+
screen.getByRole( 'button', {
|
|
101
|
+
name: 'Title',
|
|
102
|
+
expanded: true,
|
|
103
|
+
} )
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
expect( screen.getByText( 'Toggle content' ) ).not.toBeVisible();
|
|
107
|
+
} );
|
|
108
|
+
|
|
109
|
+
it( 'calls onOpenChange when toggled', async () => {
|
|
110
|
+
const onOpenChange = jest.fn();
|
|
111
|
+
const user = userEvent.setup();
|
|
112
|
+
|
|
113
|
+
render(
|
|
114
|
+
<CollapsibleCard.Root onOpenChange={ onOpenChange }>
|
|
115
|
+
<CollapsibleCard.Header>
|
|
116
|
+
<Card.Title>Title</Card.Title>
|
|
117
|
+
</CollapsibleCard.Header>
|
|
118
|
+
<CollapsibleCard.Content>
|
|
119
|
+
<p>Content</p>
|
|
120
|
+
</CollapsibleCard.Content>
|
|
121
|
+
</CollapsibleCard.Root>
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
await user.click(
|
|
125
|
+
screen.getByRole( 'button', {
|
|
126
|
+
name: 'Title',
|
|
127
|
+
expanded: false,
|
|
128
|
+
} )
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
expect( onOpenChange.mock.calls[ 0 ][ 0 ] ).toBe( true );
|
|
132
|
+
} );
|
|
133
|
+
} );
|
|
134
|
+
|
|
135
|
+
describe( 'disabled', () => {
|
|
136
|
+
it( 'does not toggle when disabled', async () => {
|
|
137
|
+
const user = userEvent.setup();
|
|
138
|
+
|
|
139
|
+
render(
|
|
140
|
+
<CollapsibleCard.Root defaultOpen disabled>
|
|
141
|
+
<CollapsibleCard.Header>
|
|
142
|
+
<Card.Title>Title</Card.Title>
|
|
143
|
+
</CollapsibleCard.Header>
|
|
144
|
+
<CollapsibleCard.Content>
|
|
145
|
+
<p>Should stay visible</p>
|
|
146
|
+
</CollapsibleCard.Content>
|
|
147
|
+
</CollapsibleCard.Root>
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
expect( screen.getByText( 'Should stay visible' ) ).toBeVisible();
|
|
151
|
+
|
|
152
|
+
await user.click(
|
|
153
|
+
screen.getByRole( 'button', {
|
|
154
|
+
name: 'Title',
|
|
155
|
+
expanded: true,
|
|
156
|
+
} )
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
expect( screen.getByText( 'Should stay visible' ) ).toBeVisible();
|
|
160
|
+
} );
|
|
161
|
+
} );
|
|
162
|
+
|
|
163
|
+
describe( 'trigger', () => {
|
|
164
|
+
it( 'renders the header as a toggle button', () => {
|
|
165
|
+
render(
|
|
166
|
+
<CollapsibleCard.Root>
|
|
167
|
+
<CollapsibleCard.Header>
|
|
168
|
+
<Card.Title>Title</Card.Title>
|
|
169
|
+
</CollapsibleCard.Header>
|
|
170
|
+
</CollapsibleCard.Root>
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
expect(
|
|
174
|
+
screen.getByRole( 'button', {
|
|
175
|
+
name: 'Title',
|
|
176
|
+
expanded: false,
|
|
177
|
+
} )
|
|
178
|
+
).toBeVisible();
|
|
179
|
+
} );
|
|
180
|
+
} );
|
|
181
|
+
} );
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { PanelProps } from '../collapsible/types';
|
|
3
|
+
import type { ComponentProps } from '../utils/types';
|
|
4
|
+
|
|
5
|
+
export interface RootProps extends ComponentProps< 'div' > {
|
|
6
|
+
/**
|
|
7
|
+
* The content to be rendered inside the collapsible card.
|
|
8
|
+
* Should include `CollapsibleCard.Header` and `CollapsibleCard.Content`.
|
|
9
|
+
*/
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* Whether the collapsible panel is currently open (controlled).
|
|
13
|
+
*
|
|
14
|
+
* To render an uncontrolled collapsible card, use `defaultOpen` instead.
|
|
15
|
+
*/
|
|
16
|
+
open?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether the collapsible panel is initially open (uncontrolled).
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
defaultOpen?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Event handler called when the panel is opened or closed.
|
|
24
|
+
*/
|
|
25
|
+
onOpenChange?: ( open: boolean ) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Whether the component should ignore user interaction.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
disabled?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface HeaderProps extends ComponentProps< 'div' > {
|
|
34
|
+
/**
|
|
35
|
+
* The content to be rendered inside the header.
|
|
36
|
+
*/
|
|
37
|
+
children?: ReactNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ContentProps extends ComponentProps< 'div' > {
|
|
41
|
+
/**
|
|
42
|
+
* The content to be rendered inside the collapsible content area.
|
|
43
|
+
*/
|
|
44
|
+
children?: ReactNode;
|
|
45
|
+
/**
|
|
46
|
+
* Allows the browser’s built-in page search to find and expand the panel contents.
|
|
47
|
+
*
|
|
48
|
+
* Overrides the `keepMounted` prop and uses `hidden="until-found"`
|
|
49
|
+
* to hide the element without removing it from the DOM.
|
|
50
|
+
*
|
|
51
|
+
* @default true
|
|
52
|
+
*/
|
|
53
|
+
hiddenUntilFound?: PanelProps[ 'hiddenUntilFound' ];
|
|
54
|
+
}
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
z-index: var(--wp-ui-dialog-z-index, initial);
|
|
30
30
|
transform: translate(-50%, -50%);
|
|
31
31
|
box-sizing: border-box;
|
|
32
|
-
min-width:
|
|
32
|
+
min-width: var(--wpds-dimension-surface-width-sm);
|
|
33
33
|
width: calc(100vw - 2 * var(--wpds-dimension-padding-2xl));
|
|
34
34
|
max-height: calc(100vh - 2 * var(--wpds-dimension-padding-2xl));
|
|
35
35
|
padding: var(--wpds-dimension-padding-2xl);
|
|
@@ -61,19 +61,19 @@
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
@media (min-width: 480px) {
|
|
64
|
-
min-width:
|
|
64
|
+
min-width: var(--wpds-dimension-surface-width-md);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
&.is-small {
|
|
68
|
-
max-width:
|
|
68
|
+
max-width: var(--wpds-dimension-surface-width-md);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
&.is-medium {
|
|
72
|
-
max-width:
|
|
72
|
+
max-width: var(--wpds-dimension-surface-width-lg);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
&.is-large {
|
|
76
|
-
max-width:
|
|
76
|
+
max-width: var(--wpds-dimension-surface-width-2xl);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
&.is-stretch {
|
package/src/dialog/types.ts
CHANGED
|
@@ -32,9 +32,9 @@ export interface PopupProps extends ComponentProps< 'div' > {
|
|
|
32
32
|
* Renders the dialog at a preset width (excluding additional padding from
|
|
33
33
|
* the viewport edges).
|
|
34
34
|
*
|
|
35
|
-
* - `'small'` — max-width
|
|
36
|
-
* - `'medium'` — max-width
|
|
37
|
-
* - `'large'` — max-width
|
|
35
|
+
* - `'small'` — narrow max-width.
|
|
36
|
+
* - `'medium'` — moderate max-width.
|
|
37
|
+
* - `'large'` — wide max-width.
|
|
38
38
|
* - `'stretch'` — no max-width, stretches to fill available space.
|
|
39
39
|
* - `'full'` — stretches to fill available width and height.
|
|
40
40
|
*
|
|
@@ -2,10 +2,14 @@ import clsx from 'clsx';
|
|
|
2
2
|
import { Field as _Field } from '@base-ui/react/field';
|
|
3
3
|
import { forwardRef } from '@wordpress/element';
|
|
4
4
|
import fieldStyles from '../../../utils/css/field.module.css';
|
|
5
|
+
import { VisuallyHidden } from '../../../visually-hidden';
|
|
5
6
|
import type { FieldLabelProps } from './types';
|
|
6
7
|
|
|
7
8
|
export const Label = forwardRef< HTMLLabelElement, FieldLabelProps >(
|
|
8
|
-
function Label(
|
|
9
|
+
function Label(
|
|
10
|
+
{ className, hideFromVision, variant, ...restProps },
|
|
11
|
+
ref
|
|
12
|
+
) {
|
|
9
13
|
return (
|
|
10
14
|
<_Field.Label
|
|
11
15
|
ref={ ref }
|
|
@@ -14,6 +18,10 @@ export const Label = forwardRef< HTMLLabelElement, FieldLabelProps >(
|
|
|
14
18
|
variant && fieldStyles[ `is-${ variant }` ],
|
|
15
19
|
className
|
|
16
20
|
) }
|
|
21
|
+
{ ...( hideFromVision && {
|
|
22
|
+
render: <VisuallyHidden />,
|
|
23
|
+
nativeLabel: false,
|
|
24
|
+
} ) }
|
|
17
25
|
{ ...restProps }
|
|
18
26
|
/>
|
|
19
27
|
);
|
|
@@ -100,6 +100,23 @@ export const UsingAriaLabelledby: StoryObj< typeof Field.Root > = {
|
|
|
100
100
|
},
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
+
/**
|
|
104
|
+
* When `hideFromVision` is set on `Field.Label`, the label is visually
|
|
105
|
+
* hidden but remains accessible to screen readers.
|
|
106
|
+
*/
|
|
107
|
+
export const HiddenLabel: StoryObj< typeof Field.Root > = {
|
|
108
|
+
args: {
|
|
109
|
+
children: (
|
|
110
|
+
<>
|
|
111
|
+
<Field.Label hideFromVision>Label</Field.Label>
|
|
112
|
+
<Field.Control
|
|
113
|
+
render={ <input type="text" placeholder="Placeholder" /> }
|
|
114
|
+
/>
|
|
115
|
+
</>
|
|
116
|
+
),
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
|
|
103
120
|
/**
|
|
104
121
|
* To add rich content (such as links) to the description, use `Field.Details`.
|
|
105
122
|
*
|
|
@@ -34,6 +34,19 @@ describe( 'Field', () => {
|
|
|
34
34
|
expect( detailsRef.current ).toBeInstanceOf( HTMLDivElement );
|
|
35
35
|
} );
|
|
36
36
|
|
|
37
|
+
it( 'keeps the accessible name when the label is visually hidden', () => {
|
|
38
|
+
render(
|
|
39
|
+
<Field.Root>
|
|
40
|
+
<Field.Label hideFromVision>Field Label</Field.Label>
|
|
41
|
+
<Field.Control render={ <input /> } />
|
|
42
|
+
</Field.Root>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
expect(
|
|
46
|
+
screen.getByRole( 'textbox', { name: 'Field Label' } )
|
|
47
|
+
).toBeVisible();
|
|
48
|
+
} );
|
|
49
|
+
|
|
37
50
|
it( 'renders details with a semantically associated description for the control', () => {
|
|
38
51
|
render(
|
|
39
52
|
<Field.Root>
|
|
@@ -33,6 +33,13 @@ export type FieldLabelProps = ComponentProps< typeof Field.Label > & {
|
|
|
33
33
|
* elements such as links or buttons.
|
|
34
34
|
*/
|
|
35
35
|
children?: Field.Label.Props[ 'children' ];
|
|
36
|
+
/**
|
|
37
|
+
* Whether to visually hide the label while keeping it accessible
|
|
38
|
+
* to screen readers.
|
|
39
|
+
*
|
|
40
|
+
* @default false
|
|
41
|
+
*/
|
|
42
|
+
hideFromVision?: boolean;
|
|
36
43
|
/**
|
|
37
44
|
* The visual variant of the label.
|
|
38
45
|
*
|
|
@@ -2,14 +2,21 @@ import clsx from 'clsx';
|
|
|
2
2
|
import { Fieldset as _Fieldset } from '@base-ui/react/fieldset';
|
|
3
3
|
import { forwardRef } from '@wordpress/element';
|
|
4
4
|
import fieldStyles from '../../../utils/css/field.module.css';
|
|
5
|
+
import { VisuallyHidden } from '../../../visually-hidden';
|
|
5
6
|
import type { FieldsetLegendProps } from './types';
|
|
6
7
|
|
|
7
8
|
export const FieldsetLegend = forwardRef< HTMLDivElement, FieldsetLegendProps >(
|
|
8
|
-
function FieldsetLegend(
|
|
9
|
+
function FieldsetLegend(
|
|
10
|
+
{ className, hideFromVision, ...restProps },
|
|
11
|
+
ref
|
|
12
|
+
) {
|
|
9
13
|
return (
|
|
10
14
|
<_Fieldset.Legend
|
|
11
15
|
ref={ ref }
|
|
12
16
|
className={ clsx( fieldStyles.label, className ) }
|
|
17
|
+
{ ...( hideFromVision && {
|
|
18
|
+
render: <VisuallyHidden />,
|
|
19
|
+
} ) }
|
|
13
20
|
{ ...restProps }
|
|
14
21
|
/>
|
|
15
22
|
);
|
|
@@ -33,6 +33,26 @@ export const Default: Story = {
|
|
|
33
33
|
},
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* When `hideFromVision` is set on `Fieldset.Legend`, the legend is visually
|
|
38
|
+
* hidden but remains accessible to screen readers.
|
|
39
|
+
*/
|
|
40
|
+
export const HiddenLegend: Story = {
|
|
41
|
+
args: {
|
|
42
|
+
children: (
|
|
43
|
+
<>
|
|
44
|
+
<Fieldset.Legend hideFromVision>Legend</Fieldset.Legend>
|
|
45
|
+
{ [ 'Apples', 'Bananas' ].map( ( fruit ) => (
|
|
46
|
+
// eslint-disable-next-line jsx-a11y/label-has-associated-control
|
|
47
|
+
<label key={ fruit }>
|
|
48
|
+
<input type="checkbox" /> { fruit }
|
|
49
|
+
</label>
|
|
50
|
+
) ) }
|
|
51
|
+
</>
|
|
52
|
+
),
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
36
56
|
/**
|
|
37
57
|
* To add rich content (such as links) to the description, use `Fieldset.Details`.
|
|
38
58
|
*
|
|
@@ -29,6 +29,20 @@ describe( 'Fieldset', () => {
|
|
|
29
29
|
expect( detailsRef.current ).toBeInstanceOf( HTMLDivElement );
|
|
30
30
|
} );
|
|
31
31
|
|
|
32
|
+
it( 'keeps the accessible name when the legend is visually hidden', () => {
|
|
33
|
+
render(
|
|
34
|
+
<Fieldset.Root>
|
|
35
|
+
<Fieldset.Legend hideFromVision>
|
|
36
|
+
Choose your options
|
|
37
|
+
</Fieldset.Legend>
|
|
38
|
+
</Fieldset.Root>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
expect(
|
|
42
|
+
screen.getByRole( 'group', { name: 'Choose your options' } )
|
|
43
|
+
).toBeVisible();
|
|
44
|
+
} );
|
|
45
|
+
|
|
32
46
|
it( 'accessibly associates description when Fieldset.Description is present', () => {
|
|
33
47
|
render(
|
|
34
48
|
<Fieldset.Root>
|
|
@@ -7,6 +7,13 @@ export type FieldsetRootProps = ComponentProps< typeof _Fieldset.Root > & {
|
|
|
7
7
|
|
|
8
8
|
export type FieldsetLegendProps = ComponentProps< typeof _Fieldset.Legend > & {
|
|
9
9
|
children?: React.ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* Whether to visually hide the legend while keeping it accessible
|
|
12
|
+
* to screen readers.
|
|
13
|
+
*
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
hideFromVision?: boolean;
|
|
10
17
|
};
|
|
11
18
|
|
|
12
19
|
export type FieldsetDescriptionProps = ComponentProps< 'p' > & {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
|
-
import { forwardRef } from '@wordpress/element';
|
|
2
|
+
import { Children, forwardRef } from '@wordpress/element';
|
|
3
3
|
import resetStyles from '../../../utils/css/resets.module.css';
|
|
4
4
|
import styles from './style.module.css';
|
|
5
5
|
import type { InputLayoutProps } from './types';
|
|
6
|
-
import { SlotContextProvider } from './context';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* A low-level component that handles the visual layout of an input-like field,
|
|
@@ -36,13 +35,23 @@ export const InputLayout = forwardRef< HTMLDivElement, InputLayoutProps >(
|
|
|
36
35
|
) }
|
|
37
36
|
{ ...restProps }
|
|
38
37
|
>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
{ Children.count( prefix ) > 0 && (
|
|
39
|
+
<div
|
|
40
|
+
className={ styles[ 'slot-wrapper' ] }
|
|
41
|
+
data-slot-type="prefix"
|
|
42
|
+
>
|
|
43
|
+
{ prefix }
|
|
44
|
+
</div>
|
|
45
|
+
) }
|
|
42
46
|
{ children }
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
{ Children.count( suffix ) > 0 && (
|
|
48
|
+
<div
|
|
49
|
+
className={ styles[ 'slot-wrapper' ] }
|
|
50
|
+
data-slot-type="suffix"
|
|
51
|
+
>
|
|
52
|
+
{ suffix }
|
|
53
|
+
</div>
|
|
54
|
+
) }
|
|
46
55
|
</div>
|
|
47
56
|
);
|
|
48
57
|
}
|
|
@@ -2,7 +2,6 @@ import clsx from 'clsx';
|
|
|
2
2
|
import { forwardRef } from '@wordpress/element';
|
|
3
3
|
import styles from './style.module.css';
|
|
4
4
|
import type { InputLayoutSlotProps } from './types';
|
|
5
|
-
import { useInputLayoutSlotContext } from './context';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* A layout helper to add paddings in a prefix or suffix.
|
|
@@ -11,25 +10,16 @@ export const InputLayoutSlot = forwardRef<
|
|
|
11
10
|
HTMLDivElement,
|
|
12
11
|
InputLayoutSlotProps
|
|
13
12
|
>( function InputLayoutSlot(
|
|
14
|
-
{
|
|
13
|
+
{ padding = 'default', className, ...restProps },
|
|
15
14
|
ref
|
|
16
15
|
) {
|
|
17
|
-
const typeContext = useInputLayoutSlotContext();
|
|
18
|
-
const type = typeProp ?? typeContext;
|
|
19
|
-
|
|
20
|
-
if ( ! type ) {
|
|
21
|
-
throw new Error(
|
|
22
|
-
'InputLayoutSlot requires a `type` prop or must be used within an InputLayout prefix/suffix slot.'
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
16
|
return (
|
|
27
17
|
<div
|
|
28
18
|
ref={ ref }
|
|
29
19
|
className={ clsx(
|
|
30
20
|
styles[ 'input-layout-slot' ],
|
|
31
|
-
styles[ `is-${
|
|
32
|
-
|
|
21
|
+
styles[ `is-padding-${ padding }` ],
|
|
22
|
+
className
|
|
33
23
|
) }
|
|
34
24
|
{ ...restProps }
|
|
35
25
|
/>
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
.slot-wrapper {
|
|
60
|
+
display: contents;
|
|
61
|
+
}
|
|
62
|
+
|
|
59
63
|
.input-layout-slot {
|
|
60
64
|
display: flex;
|
|
61
65
|
align-items: center;
|
|
@@ -69,11 +73,11 @@
|
|
|
69
73
|
var(--wpds-dimension-padding-xs));
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
|
|
76
|
+
[data-slot-type="prefix"] & {
|
|
73
77
|
padding-inline-start: var(--wp-ui-input-layout-prefix-padding-start, var(--wp-ui-input-layout-padding-inline));
|
|
74
78
|
}
|
|
75
79
|
|
|
76
|
-
|
|
80
|
+
[data-slot-type="suffix"] & {
|
|
77
81
|
padding-inline-end: var(--wp-ui-input-layout-suffix-padding-end, var(--wp-ui-input-layout-padding-inline));
|
|
78
82
|
}
|
|
79
83
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { render } from '@testing-library/react';
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
2
|
import { createRef } from '@wordpress/element';
|
|
3
3
|
import { InputLayout } from '../index';
|
|
4
4
|
import { InputLayoutSlot } from '../slot';
|
|
@@ -20,4 +20,37 @@ describe( 'InputLayout', () => {
|
|
|
20
20
|
expect( layoutRef.current ).toBeInstanceOf( HTMLDivElement );
|
|
21
21
|
expect( slotRef.current ).toBeInstanceOf( HTMLDivElement );
|
|
22
22
|
} );
|
|
23
|
+
|
|
24
|
+
// Testing the DOM contract that CSS selectors depend on.
|
|
25
|
+
it( 'wraps prefix and suffix with data-slot-type attributes', () => {
|
|
26
|
+
render(
|
|
27
|
+
<InputLayout
|
|
28
|
+
prefix={ <InputLayout.Slot>Prefix</InputLayout.Slot> }
|
|
29
|
+
suffix={ <InputLayout.Slot>Suffix</InputLayout.Slot> }
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
/* eslint-disable testing-library/no-node-access */
|
|
34
|
+
const prefix = screen
|
|
35
|
+
.getByText( 'Prefix' )
|
|
36
|
+
.closest( '[data-slot-type]' );
|
|
37
|
+
expect( prefix ).toHaveAttribute( 'data-slot-type', 'prefix' );
|
|
38
|
+
|
|
39
|
+
const suffix = screen
|
|
40
|
+
.getByText( 'Suffix' )
|
|
41
|
+
.closest( '[data-slot-type]' );
|
|
42
|
+
expect( suffix ).toHaveAttribute( 'data-slot-type', 'suffix' );
|
|
43
|
+
/* eslint-enable testing-library/no-node-access */
|
|
44
|
+
} );
|
|
45
|
+
|
|
46
|
+
it( 'does not render slot wrappers when prefix/suffix are empty', () => {
|
|
47
|
+
render( <InputLayout data-testid="layout" /> );
|
|
48
|
+
|
|
49
|
+
const layout = screen.getByTestId( 'layout' );
|
|
50
|
+
/* eslint-disable testing-library/no-node-access */
|
|
51
|
+
expect(
|
|
52
|
+
layout.querySelector( '[data-slot-type]' )
|
|
53
|
+
).not.toBeInTheDocument();
|
|
54
|
+
/* eslint-enable testing-library/no-node-access */
|
|
55
|
+
} );
|
|
23
56
|
} );
|
|
@@ -24,17 +24,8 @@ export interface InputLayoutProps
|
|
|
24
24
|
suffix?: React.ReactNode;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export type InputLayoutSlotType = 'prefix' | 'suffix';
|
|
28
|
-
|
|
29
27
|
export interface InputLayoutSlotProps
|
|
30
|
-
extends
|
|
31
|
-
/**
|
|
32
|
-
* The type of the slot.
|
|
33
|
-
*
|
|
34
|
-
* When not provided, the type will be automatically inferred from the
|
|
35
|
-
* `InputLayout` context if the slot is used within a `prefix` or `suffix`.
|
|
36
|
-
*/
|
|
37
|
-
type?: InputLayoutSlotType;
|
|
28
|
+
extends React.HTMLAttributes< HTMLDivElement > {
|
|
38
29
|
/**
|
|
39
30
|
* The padding of the slot.
|
|
40
31
|
*
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
export * from './badge';
|
|
2
2
|
export * from './button';
|
|
3
|
+
export * as Card from './card';
|
|
4
|
+
export * as Collapsible from './collapsible';
|
|
5
|
+
export * as CollapsibleCard from './collapsible-card';
|
|
3
6
|
export * as Dialog from './dialog';
|
|
4
7
|
export * from './form/primitives';
|
|
5
8
|
export * from './icon';
|
|
6
9
|
export * from './icon-button';
|
|
10
|
+
export * from './link';
|
|
7
11
|
export * as Notice from './notice';
|
|
8
12
|
export * from './stack';
|
|
9
13
|
export * as Tabs from './tabs';
|
|
14
|
+
export * from './text';
|
|
10
15
|
export * as Tooltip from './tooltip';
|
|
11
16
|
export * from './visually-hidden';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Link } from './link';
|