@wordpress/ui 0.13.1-next.v.202605131006.0 → 0.14.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 +40 -1
- package/CONTRIBUTING.md +34 -0
- package/README.md +15 -0
- package/build/alert-dialog/portal.cjs.map +2 -2
- package/build/alert-dialog/types.cjs.map +1 -1
- package/build/button/button.cjs +1 -1
- package/build/button/button.cjs.map +2 -2
- package/build/card/content.cjs +1 -1
- package/build/card/content.cjs.map +2 -2
- package/build/card/full-bleed.cjs +1 -1
- package/build/card/full-bleed.cjs.map +2 -2
- package/build/card/header.cjs +1 -1
- package/build/card/header.cjs.map +2 -2
- package/build/card/root.cjs +1 -1
- package/build/card/root.cjs.map +2 -2
- package/build/collapsible-card/header.cjs.map +2 -2
- package/build/dialog/portal.cjs.map +2 -2
- package/build/dialog/types.cjs.map +1 -1
- package/build/drawer/portal.cjs.map +2 -2
- package/build/drawer/types.cjs.map +1 -1
- package/build/form/primitives/autocomplete/clear.cjs +4 -1
- package/build/form/primitives/autocomplete/clear.cjs.map +2 -2
- package/build/form/primitives/autocomplete/empty.cjs +1 -1
- package/build/form/primitives/autocomplete/empty.cjs.map +2 -2
- package/build/form/primitives/autocomplete/index.cjs +4 -1
- package/build/form/primitives/autocomplete/index.cjs.map +2 -2
- package/build/form/primitives/autocomplete/item.cjs +1 -1
- package/build/form/primitives/autocomplete/item.cjs.map +2 -2
- package/build/form/primitives/autocomplete/list-body.cjs +1 -1
- package/build/form/primitives/autocomplete/list-body.cjs.map +2 -2
- package/build/form/primitives/autocomplete/list.cjs +1 -1
- package/build/form/primitives/autocomplete/list.cjs.map +2 -2
- package/build/form/primitives/autocomplete/popup.cjs +14 -31
- package/build/form/primitives/autocomplete/popup.cjs.map +3 -3
- package/build/form/primitives/autocomplete/portal.cjs +10 -2
- package/build/form/primitives/autocomplete/portal.cjs.map +2 -2
- package/build/form/primitives/autocomplete/positioner.cjs +158 -0
- package/build/form/primitives/autocomplete/positioner.cjs.map +7 -0
- package/build/form/primitives/autocomplete/types.cjs.map +1 -1
- package/build/form/primitives/constants.cjs.map +2 -2
- package/build/form/primitives/select/index.cjs +4 -1
- package/build/form/primitives/select/index.cjs.map +2 -2
- package/build/form/primitives/select/item.cjs +1 -1
- package/build/form/primitives/select/item.cjs.map +2 -2
- package/build/form/primitives/select/popup.cjs +18 -36
- package/build/form/primitives/select/popup.cjs.map +3 -3
- package/build/form/primitives/select/portal.cjs +11 -5
- package/build/form/primitives/select/portal.cjs.map +2 -2
- package/build/form/primitives/select/positioner.cjs +159 -0
- package/build/form/primitives/select/positioner.cjs.map +7 -0
- package/build/form/primitives/select/types.cjs.map +1 -1
- package/build/icon-button/icon-button.cjs +1 -1
- package/build/icon-button/icon-button.cjs.map +2 -2
- package/build/index.cjs +7 -1
- package/build/index.cjs.map +2 -2
- package/build/popover/index.cjs +3 -0
- package/build/popover/index.cjs.map +2 -2
- package/build/popover/popup.cjs +23 -51
- package/build/popover/popup.cjs.map +3 -3
- package/build/popover/portal.cjs.map +2 -2
- package/build/popover/positioner.cjs +168 -0
- package/build/popover/positioner.cjs.map +7 -0
- package/build/popover/root.cjs.map +2 -2
- package/build/popover/types.cjs.map +1 -1
- package/build/tooltip/portal.cjs +10 -2
- package/build/tooltip/portal.cjs.map +2 -2
- package/build/tooltip/positioner.cjs.map +2 -2
- package/build/tooltip/types.cjs.map +1 -1
- package/build/utils/create-overlay-title-validation.cjs.map +2 -2
- package/build/utils/render-slot-with-children.cjs +4 -1
- package/build/utils/render-slot-with-children.cjs.map +2 -2
- package/build/utils/use-enable-wp-compat-overlay-slot.cjs +39 -0
- package/build/utils/use-enable-wp-compat-overlay-slot.cjs.map +7 -0
- package/build/utils/wp-compat-overlay-slot.cjs +177 -0
- package/build/utils/wp-compat-overlay-slot.cjs.map +7 -0
- package/build-module/alert-dialog/portal.mjs.map +2 -2
- package/build-module/button/button.mjs +1 -1
- package/build-module/button/button.mjs.map +2 -2
- package/build-module/card/content.mjs +1 -1
- package/build-module/card/content.mjs.map +2 -2
- package/build-module/card/full-bleed.mjs +1 -1
- package/build-module/card/full-bleed.mjs.map +2 -2
- package/build-module/card/header.mjs +1 -1
- package/build-module/card/header.mjs.map +2 -2
- package/build-module/card/root.mjs +1 -1
- package/build-module/card/root.mjs.map +2 -2
- package/build-module/collapsible-card/header.mjs.map +2 -2
- package/build-module/dialog/portal.mjs.map +2 -2
- package/build-module/drawer/portal.mjs.map +2 -2
- package/build-module/form/primitives/autocomplete/clear.mjs +4 -1
- package/build-module/form/primitives/autocomplete/clear.mjs.map +2 -2
- package/build-module/form/primitives/autocomplete/empty.mjs +1 -1
- package/build-module/form/primitives/autocomplete/empty.mjs.map +2 -2
- package/build-module/form/primitives/autocomplete/index.mjs +3 -1
- package/build-module/form/primitives/autocomplete/index.mjs.map +2 -2
- package/build-module/form/primitives/autocomplete/item.mjs +1 -1
- package/build-module/form/primitives/autocomplete/item.mjs.map +2 -2
- package/build-module/form/primitives/autocomplete/list-body.mjs +1 -1
- package/build-module/form/primitives/autocomplete/list-body.mjs.map +2 -2
- package/build-module/form/primitives/autocomplete/list.mjs +1 -1
- package/build-module/form/primitives/autocomplete/list.mjs.map +2 -2
- package/build-module/form/primitives/autocomplete/popup.mjs +14 -31
- package/build-module/form/primitives/autocomplete/popup.mjs.map +3 -3
- package/build-module/form/primitives/autocomplete/portal.mjs +10 -2
- package/build-module/form/primitives/autocomplete/portal.mjs.map +2 -2
- package/build-module/form/primitives/autocomplete/positioner.mjs +123 -0
- package/build-module/form/primitives/autocomplete/positioner.mjs.map +7 -0
- package/build-module/form/primitives/constants.mjs.map +2 -2
- package/build-module/form/primitives/select/index.mjs +3 -1
- package/build-module/form/primitives/select/index.mjs.map +2 -2
- package/build-module/form/primitives/select/item.mjs +1 -1
- package/build-module/form/primitives/select/item.mjs.map +2 -2
- package/build-module/form/primitives/select/popup.mjs +18 -36
- package/build-module/form/primitives/select/popup.mjs.map +3 -3
- package/build-module/form/primitives/select/portal.mjs +11 -5
- package/build-module/form/primitives/select/portal.mjs.map +2 -2
- package/build-module/form/primitives/select/positioner.mjs +124 -0
- package/build-module/form/primitives/select/positioner.mjs.map +7 -0
- package/build-module/icon-button/icon-button.mjs +1 -1
- package/build-module/icon-button/icon-button.mjs.map +2 -2
- package/build-module/index.mjs +5 -1
- package/build-module/index.mjs.map +2 -2
- package/build-module/popover/index.mjs +2 -0
- package/build-module/popover/index.mjs.map +2 -2
- package/build-module/popover/popup.mjs +23 -51
- package/build-module/popover/popup.mjs.map +3 -3
- package/build-module/popover/portal.mjs.map +2 -2
- package/build-module/popover/positioner.mjs +133 -0
- package/build-module/popover/positioner.mjs.map +7 -0
- package/build-module/popover/root.mjs.map +2 -2
- package/build-module/tooltip/portal.mjs +10 -2
- package/build-module/tooltip/portal.mjs.map +2 -2
- package/build-module/tooltip/positioner.mjs.map +2 -2
- package/build-module/utils/create-overlay-title-validation.mjs.map +2 -2
- package/build-module/utils/render-slot-with-children.mjs +4 -1
- package/build-module/utils/render-slot-with-children.mjs.map +2 -2
- package/build-module/utils/use-enable-wp-compat-overlay-slot.mjs +14 -0
- package/build-module/utils/use-enable-wp-compat-overlay-slot.mjs.map +7 -0
- package/build-module/utils/wp-compat-overlay-slot.mjs +148 -0
- package/build-module/utils/wp-compat-overlay-slot.mjs.map +7 -0
- package/build-types/alert-dialog/portal.d.ts +8 -5
- package/build-types/alert-dialog/portal.d.ts.map +1 -1
- package/build-types/alert-dialog/types.d.ts +2 -2
- package/build-types/alert-dialog/types.d.ts.map +1 -1
- package/build-types/badge/stories/e2e/index.story.d.ts +7 -0
- package/build-types/badge/stories/e2e/index.story.d.ts.map +1 -0
- package/build-types/button/stories/e2e/index.story.d.ts +8 -0
- package/build-types/button/stories/e2e/index.story.d.ts.map +1 -0
- package/build-types/card/full-bleed.d.ts +18 -0
- package/build-types/card/full-bleed.d.ts.map +1 -1
- package/build-types/card/stories/index.story.d.ts +23 -0
- package/build-types/card/stories/index.story.d.ts.map +1 -1
- package/build-types/collapsible-card/header.d.ts +2 -0
- package/build-types/collapsible-card/header.d.ts.map +1 -1
- package/build-types/collapsible-card/stories/index.story.d.ts +14 -0
- package/build-types/collapsible-card/stories/index.story.d.ts.map +1 -1
- package/build-types/dialog/portal.d.ts +8 -6
- package/build-types/dialog/portal.d.ts.map +1 -1
- package/build-types/dialog/types.d.ts +2 -2
- package/build-types/dialog/types.d.ts.map +1 -1
- package/build-types/drawer/portal.d.ts +8 -6
- package/build-types/drawer/portal.d.ts.map +1 -1
- package/build-types/drawer/types.d.ts +2 -2
- package/build-types/drawer/types.d.ts.map +1 -1
- package/build-types/form/primitives/autocomplete/clear.d.ts.map +1 -1
- package/build-types/form/primitives/autocomplete/index.d.ts +2 -1
- package/build-types/form/primitives/autocomplete/index.d.ts.map +1 -1
- package/build-types/form/primitives/autocomplete/popup.d.ts +1 -0
- package/build-types/form/primitives/autocomplete/popup.d.ts.map +1 -1
- package/build-types/form/primitives/autocomplete/portal.d.ts +9 -4
- package/build-types/form/primitives/autocomplete/portal.d.ts.map +1 -1
- package/build-types/form/primitives/autocomplete/positioner.d.ts +12 -0
- package/build-types/form/primitives/autocomplete/positioner.d.ts.map +1 -0
- package/build-types/form/primitives/autocomplete/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/autocomplete/types.d.ts +11 -9
- package/build-types/form/primitives/autocomplete/types.d.ts.map +1 -1
- package/build-types/form/primitives/constants.d.ts +9 -4
- package/build-types/form/primitives/constants.d.ts.map +1 -1
- package/build-types/form/primitives/select/index.d.ts +2 -1
- package/build-types/form/primitives/select/index.d.ts.map +1 -1
- package/build-types/form/primitives/select/popup.d.ts +1 -0
- package/build-types/form/primitives/select/popup.d.ts.map +1 -1
- package/build-types/form/primitives/select/portal.d.ts +9 -4
- package/build-types/form/primitives/select/portal.d.ts.map +1 -1
- package/build-types/form/primitives/select/positioner.d.ts +12 -0
- package/build-types/form/primitives/select/positioner.d.ts.map +1 -0
- package/build-types/form/primitives/select/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/select/types.d.ts +11 -2
- package/build-types/form/primitives/select/types.d.ts.map +1 -1
- package/build-types/icon/stories/index.story.d.ts.map +1 -1
- package/build-types/index.d.ts +2 -0
- package/build-types/index.d.ts.map +1 -1
- package/build-types/popover/index.d.ts +2 -1
- package/build-types/popover/index.d.ts.map +1 -1
- package/build-types/popover/popup.d.ts +2 -1
- package/build-types/popover/popup.d.ts.map +1 -1
- package/build-types/popover/portal.d.ts +8 -5
- package/build-types/popover/portal.d.ts.map +1 -1
- package/build-types/popover/positioner.d.ts +12 -0
- package/build-types/popover/positioner.d.ts.map +1 -0
- package/build-types/popover/root.d.ts +5 -2
- package/build-types/popover/root.d.ts.map +1 -1
- package/build-types/popover/stories/index.story.d.ts +10 -21
- package/build-types/popover/stories/index.story.d.ts.map +1 -1
- package/build-types/popover/types.d.ts +12 -3
- package/build-types/popover/types.d.ts.map +1 -1
- package/build-types/tooltip/portal.d.ts +9 -4
- package/build-types/tooltip/portal.d.ts.map +1 -1
- package/build-types/tooltip/positioner.d.ts +8 -5
- package/build-types/tooltip/positioner.d.ts.map +1 -1
- package/build-types/tooltip/types.d.ts +3 -3
- package/build-types/tooltip/types.d.ts.map +1 -1
- package/build-types/utils/render-slot-with-children.d.ts.map +1 -1
- package/build-types/utils/test/use-enable-wp-compat-overlay-slot.test.d.ts +2 -0
- package/build-types/utils/test/use-enable-wp-compat-overlay-slot.test.d.ts.map +1 -0
- package/build-types/utils/test/wp-compat-overlay-slot.test.d.ts +2 -0
- package/build-types/utils/test/wp-compat-overlay-slot.test.d.ts.map +1 -0
- package/build-types/utils/use-deprioritized-initial-focus.d.ts +1 -1
- package/build-types/utils/use-enable-wp-compat-overlay-slot.d.ts +17 -0
- package/build-types/utils/use-enable-wp-compat-overlay-slot.d.ts.map +1 -0
- package/build-types/utils/wp-compat-overlay-slot.d.ts +30 -0
- package/build-types/utils/wp-compat-overlay-slot.d.ts.map +1 -0
- package/package.json +14 -14
- package/src/alert-dialog/portal.tsx +1 -4
- package/src/alert-dialog/types.ts +2 -4
- package/src/badge/stories/e2e/index.story.tsx +20 -0
- package/src/button/stories/e2e/index.story.tsx +130 -0
- package/src/button/stories/index.story.tsx +1 -1
- package/src/button/style.module.css +17 -12
- package/src/card/full-bleed.tsx +18 -0
- package/src/card/stories/index.story.tsx +115 -1
- package/src/card/style.module.css +16 -0
- package/src/card/test/index.test.tsx +18 -1
- package/src/collapsible-card/header.tsx +2 -0
- package/src/collapsible-card/stories/index.story.tsx +66 -0
- package/src/dialog/portal.tsx +1 -5
- package/src/dialog/types.ts +2 -2
- package/src/drawer/portal.tsx +1 -5
- package/src/drawer/types.ts +2 -2
- package/src/form/primitives/autocomplete/clear.tsx +10 -4
- package/src/form/primitives/autocomplete/index.ts +2 -1
- package/src/form/primitives/autocomplete/popup.tsx +17 -21
- package/src/form/primitives/autocomplete/portal.tsx +11 -5
- package/src/form/primitives/autocomplete/positioner.tsx +29 -0
- package/src/form/primitives/autocomplete/stories/index.story.tsx +1 -0
- package/src/form/primitives/autocomplete/test/index.test.tsx +219 -0
- package/src/form/primitives/autocomplete/types.ts +15 -15
- package/src/form/primitives/constants.ts +7 -4
- package/src/form/primitives/select/index.ts +2 -1
- package/src/form/primitives/select/popup.tsx +30 -34
- package/src/form/primitives/select/portal.tsx +15 -8
- package/src/form/primitives/select/positioner.tsx +33 -0
- package/src/form/primitives/select/stories/index.story.tsx +1 -0
- package/src/form/primitives/select/test/index.test.tsx +134 -0
- package/src/form/primitives/select/types.ts +12 -2
- package/src/form/select-control/test/index.test.tsx +64 -0
- package/src/icon/stories/index.story.tsx +3 -2
- package/src/icon-button/icon-button.tsx +1 -1
- package/src/icon-button/test/index.test.tsx +10 -10
- package/src/index.ts +2 -0
- package/src/popover/index.ts +12 -1
- package/src/popover/popup.tsx +28 -45
- package/src/popover/portal.tsx +1 -4
- package/src/popover/positioner.tsx +42 -0
- package/src/popover/root.tsx +5 -2
- package/src/popover/stories/index.story.tsx +85 -138
- package/src/popover/test/index.test.tsx +36 -1
- package/src/popover/types.ts +13 -15
- package/src/tabs/stories/index.story.tsx +2 -2
- package/src/tooltip/portal.tsx +11 -5
- package/src/tooltip/positioner.tsx +1 -4
- package/src/tooltip/style.module.css +1 -1
- package/src/tooltip/test/index.test.tsx +110 -0
- package/src/tooltip/types.ts +3 -5
- package/src/utils/create-overlay-title-validation.tsx +1 -1
- package/src/utils/css/item-popup.module.css +7 -4
- package/src/utils/css/wp-compat-overlay-slot.module.css +35 -0
- package/src/utils/render-slot-with-children.ts +4 -1
- package/src/utils/test/use-enable-wp-compat-overlay-slot.test.tsx +74 -0
- package/src/utils/test/wp-compat-overlay-slot.test.ts +300 -0
- package/src/utils/use-enable-wp-compat-overlay-slot.ts +32 -0
- package/src/utils/wp-compat-overlay-slot.ts +129 -0
package/src/card/full-bleed.tsx
CHANGED
|
@@ -7,6 +7,24 @@ import type { FullBleedProps } from './types';
|
|
|
7
7
|
* A container that breaks out of the card's padding to span edge-to-edge.
|
|
8
8
|
* Useful for full-width images, dividers, or embedded content.
|
|
9
9
|
*
|
|
10
|
+
* Additional edge-bumping behavior based on placement:
|
|
11
|
+
*
|
|
12
|
+
* - As the **first child** of `Card.Header`, it extends flush to the card's
|
|
13
|
+
* top edge — ideal for hero images.
|
|
14
|
+
* - As the **only child** of `Card.Content`, it extends flush to the card's
|
|
15
|
+
* top edge when `Content` is the first card section, and to the bottom edge
|
|
16
|
+
* when it is the last.
|
|
17
|
+
*
|
|
18
|
+
* Inter-sibling spacing inside `Card.Header` / `Card.Content` is consumer-
|
|
19
|
+
* managed. To add space between a hero `FullBleed` and the following
|
|
20
|
+
* siblings, compose the parent with `Stack` via the `render` prop:
|
|
21
|
+
* `<Card.Header render={ <Stack direction="column" gap="lg" /> }>`. This
|
|
22
|
+
* keeps `FullBleed` a direct child of `Card.Header` so the edge-bump still
|
|
23
|
+
* fires, while `Stack` provides the gap.
|
|
24
|
+
*
|
|
25
|
+
* Inside `CollapsibleCard`, place full-bleed media in `CollapsibleCard.Content`
|
|
26
|
+
* (not the header). The trigger/panel gap is preserved by design.
|
|
27
|
+
*
|
|
10
28
|
* Must be used as a direct child of `Card.Content` or `Card.Header`.
|
|
11
29
|
*/
|
|
12
30
|
export const FullBleed = forwardRef< HTMLDivElement, FullBleedProps >(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Stack } from '@wordpress/ui';
|
|
2
3
|
import * as Card from '../index';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -71,6 +72,56 @@ export const Default: Story = {
|
|
|
71
72
|
},
|
|
72
73
|
};
|
|
73
74
|
|
|
75
|
+
/**
|
|
76
|
+
* `Card.FullBleed` as the sole child of `Card.Content` spans edge-to-edge
|
|
77
|
+
* with no padding around it.
|
|
78
|
+
*/
|
|
79
|
+
export const FullBleedCoverOnly: Story = {
|
|
80
|
+
args: {
|
|
81
|
+
children: (
|
|
82
|
+
<Card.Content>
|
|
83
|
+
<Card.FullBleed>
|
|
84
|
+
<div
|
|
85
|
+
style={ {
|
|
86
|
+
height: 180,
|
|
87
|
+
background:
|
|
88
|
+
'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
|
|
89
|
+
} }
|
|
90
|
+
/>
|
|
91
|
+
</Card.FullBleed>
|
|
92
|
+
</Card.Content>
|
|
93
|
+
),
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* When `Card.FullBleed` is the sole child of `Card.Content` and a
|
|
99
|
+
* `Card.Header` sits above it, the image bumps against the card's side and
|
|
100
|
+
* bottom edges while the header retains its normal padding.
|
|
101
|
+
*/
|
|
102
|
+
export const FullBleedCoverWithHeader: Story = {
|
|
103
|
+
args: {
|
|
104
|
+
children: (
|
|
105
|
+
<>
|
|
106
|
+
<Card.Header>
|
|
107
|
+
<Card.Title>Card title</Card.Title>
|
|
108
|
+
</Card.Header>
|
|
109
|
+
<Card.Content>
|
|
110
|
+
<Card.FullBleed>
|
|
111
|
+
<div
|
|
112
|
+
style={ {
|
|
113
|
+
height: 180,
|
|
114
|
+
background:
|
|
115
|
+
'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
|
|
116
|
+
} }
|
|
117
|
+
/>
|
|
118
|
+
</Card.FullBleed>
|
|
119
|
+
</Card.Content>
|
|
120
|
+
</>
|
|
121
|
+
),
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
|
|
74
125
|
/**
|
|
75
126
|
* `Card.FullBleed` breaks out of the card's padding to span
|
|
76
127
|
* edge-to-edge. Useful for images, dividers, or embedded content.
|
|
@@ -82,7 +133,7 @@ export const WithFullBleed: Story = {
|
|
|
82
133
|
<Card.Header>
|
|
83
134
|
<Card.Title>Featured image</Card.Title>
|
|
84
135
|
</Card.Header>
|
|
85
|
-
<Card.Content>
|
|
136
|
+
<Card.Content render={ <Stack direction="column" gap="lg" /> }>
|
|
86
137
|
<Card.FullBleed>
|
|
87
138
|
<div
|
|
88
139
|
style={ {
|
|
@@ -112,6 +163,69 @@ export const HeaderOnly: Story = {
|
|
|
112
163
|
},
|
|
113
164
|
};
|
|
114
165
|
|
|
166
|
+
/**
|
|
167
|
+
* When `Card.FullBleed` is the **first child** of `Card.Header`, it extends
|
|
168
|
+
* flush to the card's top and side edges — ideal for hero images. Content
|
|
169
|
+
* that follows inside the header is padded normally.
|
|
170
|
+
*/
|
|
171
|
+
export const FullBleedHeroWithTitle: Story = {
|
|
172
|
+
args: {
|
|
173
|
+
children: (
|
|
174
|
+
<>
|
|
175
|
+
<Card.Header render={ <Stack direction="column" gap="lg" /> }>
|
|
176
|
+
<Card.FullBleed>
|
|
177
|
+
<div
|
|
178
|
+
style={ {
|
|
179
|
+
height: 180,
|
|
180
|
+
background:
|
|
181
|
+
'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
|
|
182
|
+
} }
|
|
183
|
+
/>
|
|
184
|
+
</Card.FullBleed>
|
|
185
|
+
<Card.Title>Hero image card</Card.Title>
|
|
186
|
+
</Card.Header>
|
|
187
|
+
<Card.Content>
|
|
188
|
+
<Text>
|
|
189
|
+
The image above bleeds to the card's top and side
|
|
190
|
+
edges.
|
|
191
|
+
</Text>
|
|
192
|
+
</Card.Content>
|
|
193
|
+
</>
|
|
194
|
+
),
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* When `Card.FullBleed` is the **only child** of `Card.Header`, it fills the
|
|
200
|
+
* header entirely — top and sides flush to the card edges, no extra padding
|
|
201
|
+
* below.
|
|
202
|
+
*/
|
|
203
|
+
export const FullBleedHeroOnly: Story = {
|
|
204
|
+
args: {
|
|
205
|
+
children: (
|
|
206
|
+
<>
|
|
207
|
+
<Card.Header>
|
|
208
|
+
<Card.FullBleed>
|
|
209
|
+
<div
|
|
210
|
+
style={ {
|
|
211
|
+
height: 180,
|
|
212
|
+
background:
|
|
213
|
+
'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
|
|
214
|
+
} }
|
|
215
|
+
/>
|
|
216
|
+
</Card.FullBleed>
|
|
217
|
+
</Card.Header>
|
|
218
|
+
<Card.Content>
|
|
219
|
+
<Text>
|
|
220
|
+
The image above bleeds to the card's top and side
|
|
221
|
+
edges.
|
|
222
|
+
</Text>
|
|
223
|
+
</Card.Content>
|
|
224
|
+
</>
|
|
225
|
+
),
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
|
|
115
229
|
/**
|
|
116
230
|
* Use the `render` prop to change the underlying HTML elements for
|
|
117
231
|
* better semantics. Here, `Card.Root` renders as a `<section>` and
|
|
@@ -38,4 +38,20 @@
|
|
|
38
38
|
margin-inline: calc(-1 * var(--wp-ui-card-padding));
|
|
39
39
|
width: calc(100% + 2 * var(--wp-ui-card-padding));
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
* When FullBleed sits at the start of the first *root* card section, extend
|
|
44
|
+
* it flush to the card's top edge. Must use `.root >` so `Card.Content`
|
|
45
|
+
* nested inside `CollapsibleCard`'s panel is not treated as `:first-child`
|
|
46
|
+
* (which would pull FullBleed up into the header gap).
|
|
47
|
+
*/
|
|
48
|
+
.root > :is(.header, .content):first-child > .fullbleed:first-child {
|
|
49
|
+
margin-block-start: calc(-1 * var(--wp-ui-card-padding));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* When FullBleed sits at the end of the last card section, extend it flush to the card's bottom edge. */
|
|
53
|
+
:is(.header, .content):last-child > .fullbleed:last-child {
|
|
54
|
+
margin-block-end: calc(-1 * var(--wp-ui-card-padding));
|
|
55
|
+
}
|
|
56
|
+
|
|
41
57
|
}
|
|
@@ -49,7 +49,7 @@ describe( 'Card', () => {
|
|
|
49
49
|
} );
|
|
50
50
|
|
|
51
51
|
describe( 'fullbleed', () => {
|
|
52
|
-
it( 'renders children', () => {
|
|
52
|
+
it( 'renders children inside Content', () => {
|
|
53
53
|
render(
|
|
54
54
|
<Card.Root>
|
|
55
55
|
<Card.Content>
|
|
@@ -65,6 +65,23 @@ describe( 'Card', () => {
|
|
|
65
65
|
|
|
66
66
|
expect( screen.getByRole( 'img', { name: 'test' } ) ).toBeVisible();
|
|
67
67
|
} );
|
|
68
|
+
|
|
69
|
+
it( 'renders children inside Header', () => {
|
|
70
|
+
render(
|
|
71
|
+
<Card.Root>
|
|
72
|
+
<Card.Header>
|
|
73
|
+
<Card.FullBleed>
|
|
74
|
+
<img
|
|
75
|
+
src="https://example.com/hero.jpg"
|
|
76
|
+
alt="hero"
|
|
77
|
+
/>
|
|
78
|
+
</Card.FullBleed>
|
|
79
|
+
</Card.Header>
|
|
80
|
+
</Card.Root>
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
expect( screen.getByRole( 'img', { name: 'hero' } ) ).toBeVisible();
|
|
84
|
+
} );
|
|
68
85
|
} );
|
|
69
86
|
|
|
70
87
|
describe( 'render prop', () => {
|
|
@@ -25,6 +25,8 @@ import type { HeaderProps } from './types';
|
|
|
25
25
|
* Avoid placing interactive elements (buttons, links, inputs) inside the
|
|
26
26
|
* header, since the entire area is clickable and their events will bubble
|
|
27
27
|
* to trigger the collapse toggle.
|
|
28
|
+
*
|
|
29
|
+
* Place full-bleed media in `CollapsibleCard.Content`, not the header.
|
|
28
30
|
*/
|
|
29
31
|
export const Header = forwardRef< HTMLDivElement, HeaderProps >(
|
|
30
32
|
function CollapsibleCardHeader(
|
|
@@ -33,6 +33,7 @@ const meta: Meta< typeof CollapsibleCard.Root > = {
|
|
|
33
33
|
'CollapsibleCard.Header': CollapsibleCard.Header,
|
|
34
34
|
'CollapsibleCard.HeaderDescription': CollapsibleCard.HeaderDescription,
|
|
35
35
|
'CollapsibleCard.Content': CollapsibleCard.Content,
|
|
36
|
+
'Card.FullBleed': Card.FullBleed,
|
|
36
37
|
},
|
|
37
38
|
parameters: {
|
|
38
39
|
componentStatus: {
|
|
@@ -314,3 +315,68 @@ export const ComparedToCard: Story = {
|
|
|
314
315
|
</div>
|
|
315
316
|
),
|
|
316
317
|
};
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* When `Card.FullBleed` is the sole child of `CollapsibleCard.Content` and a
|
|
321
|
+
* header sits above it, the media bumps against the card's side and
|
|
322
|
+
* bottom edges while the header retains its normal padding. (Unlike a plain
|
|
323
|
+
* `Card`, a header is always required here for the collapse trigger — see
|
|
324
|
+
* `Card` stories for a body-only `FullBleedCoverOnly` example.)
|
|
325
|
+
*/
|
|
326
|
+
export const FullBleedCoverWithHeader: Story = {
|
|
327
|
+
argTypes: { open: { control: false } },
|
|
328
|
+
args: {
|
|
329
|
+
defaultOpen: true,
|
|
330
|
+
children: (
|
|
331
|
+
<>
|
|
332
|
+
<CollapsibleCard.Header>
|
|
333
|
+
<Card.Title>Card title</Card.Title>
|
|
334
|
+
</CollapsibleCard.Header>
|
|
335
|
+
<CollapsibleCard.Content>
|
|
336
|
+
<Card.FullBleed>
|
|
337
|
+
<div
|
|
338
|
+
style={ {
|
|
339
|
+
height: 180,
|
|
340
|
+
background:
|
|
341
|
+
'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
|
|
342
|
+
} }
|
|
343
|
+
/>
|
|
344
|
+
</Card.FullBleed>
|
|
345
|
+
</CollapsibleCard.Content>
|
|
346
|
+
</>
|
|
347
|
+
),
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* `Card.FullBleed` breaks out of the content padding to span edge-to-edge.
|
|
353
|
+
* Useful for images, dividers, or embedded content inside the collapsible
|
|
354
|
+
* region.
|
|
355
|
+
*/
|
|
356
|
+
export const WithFullBleed: Story = {
|
|
357
|
+
argTypes: { open: { control: false } },
|
|
358
|
+
args: {
|
|
359
|
+
defaultOpen: true,
|
|
360
|
+
children: (
|
|
361
|
+
<>
|
|
362
|
+
<CollapsibleCard.Header>
|
|
363
|
+
<Card.Title>Featured image</Card.Title>
|
|
364
|
+
</CollapsibleCard.Header>
|
|
365
|
+
<CollapsibleCard.Content
|
|
366
|
+
render={ <Stack direction="column" gap="lg" /> }
|
|
367
|
+
>
|
|
368
|
+
<Card.FullBleed>
|
|
369
|
+
<div
|
|
370
|
+
style={ {
|
|
371
|
+
height: 160,
|
|
372
|
+
background:
|
|
373
|
+
'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
|
374
|
+
} }
|
|
375
|
+
/>
|
|
376
|
+
</Card.FullBleed>
|
|
377
|
+
<Text>Content below the full-bleed area.</Text>
|
|
378
|
+
</CollapsibleCard.Content>
|
|
379
|
+
</>
|
|
380
|
+
),
|
|
381
|
+
},
|
|
382
|
+
};
|
package/src/dialog/portal.tsx
CHANGED
|
@@ -3,11 +3,7 @@ import { forwardRef } from '@wordpress/element';
|
|
|
3
3
|
import type { PortalProps } from './types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* `Popup`, etc.) outside the DOM hierarchy. Pass to `Dialog.Popup`'s
|
|
8
|
-
* `portal` prop to customize `container`, `className`, `style`, and other
|
|
9
|
-
* Base UI portal options. When `portal` is omitted, `Dialog.Popup` uses this
|
|
10
|
-
* component with default props.
|
|
6
|
+
* Used to apply custom portal behavior to `Dialog`'s overlay content.
|
|
11
7
|
*/
|
|
12
8
|
const Portal = forwardRef< HTMLDivElement, PortalProps >(
|
|
13
9
|
function DialogPortal( props, ref ) {
|
package/src/dialog/types.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Dialog as _Dialog } from '@base-ui/react/dialog';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
import type { Button } from '../button';
|
|
5
5
|
import type { IconButton } from '../icon-button';
|
|
6
6
|
import type { ComponentProps } from '../utils/types';
|
|
7
7
|
|
|
8
|
-
export type PortalProps =
|
|
8
|
+
export type PortalProps = ComponentProps< typeof _Dialog.Portal >;
|
|
9
9
|
|
|
10
10
|
export interface RootProps
|
|
11
11
|
extends Pick<
|
package/src/drawer/portal.tsx
CHANGED
|
@@ -3,11 +3,7 @@ import { forwardRef } from '@wordpress/element';
|
|
|
3
3
|
import type { PortalProps } from './types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* with the inner `Popup`, etc.) outside the DOM hierarchy. Pass to
|
|
8
|
-
* `Drawer.Popup`'s `portal` prop to customize `container`, `className`,
|
|
9
|
-
* `style`, and other Base UI portal options. When `portal` is omitted,
|
|
10
|
-
* `Drawer.Popup` uses this component with default props.
|
|
6
|
+
* Used to apply custom portal behavior to `Drawer`'s overlay content.
|
|
11
7
|
*/
|
|
12
8
|
const Portal = forwardRef< HTMLDivElement, PortalProps >(
|
|
13
9
|
function DrawerPortal( props, ref ) {
|
package/src/drawer/types.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { Drawer as _Drawer } from '@base-ui/react/drawer';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
3
3
|
import type { Button } from '../button';
|
|
4
4
|
import type { IconButton } from '../icon-button';
|
|
5
5
|
import type { ComponentProps } from '../utils/types';
|
|
6
6
|
|
|
7
|
-
export type PortalProps =
|
|
7
|
+
export type PortalProps = ComponentProps< typeof _Drawer.Portal >;
|
|
8
8
|
|
|
9
9
|
export interface RootProps
|
|
10
10
|
extends Pick<
|
|
@@ -5,12 +5,18 @@ import { __ } from '@wordpress/i18n';
|
|
|
5
5
|
import { IconButton } from '../../../icon-button';
|
|
6
6
|
import type { AutocompleteClearProps } from './types';
|
|
7
7
|
|
|
8
|
-
const DEFAULT_RENDER = (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const DEFAULT_RENDER = (
|
|
9
|
+
{
|
|
10
|
+
'aria-label': ariaLabel = __( 'Clear' ),
|
|
11
|
+
...props
|
|
12
|
+
}: AutocompleteClearProps,
|
|
13
|
+
{ disabled }: _Autocomplete.Clear.State
|
|
14
|
+
) => (
|
|
12
15
|
<IconButton
|
|
13
16
|
icon={ closeSmall }
|
|
17
|
+
focusableWhenDisabled={ false }
|
|
18
|
+
disabled={ disabled }
|
|
19
|
+
aria-hidden={ disabled || undefined }
|
|
14
20
|
size="small"
|
|
15
21
|
variant="minimal"
|
|
16
22
|
tone="neutral"
|
|
@@ -6,7 +6,8 @@ export { Input } from './input';
|
|
|
6
6
|
export { Item } from './item';
|
|
7
7
|
export { List } from './list';
|
|
8
8
|
export { ListBody } from './list-body';
|
|
9
|
-
export { Portal } from './portal';
|
|
10
9
|
export { Popup } from './popup';
|
|
10
|
+
export { Portal } from './portal';
|
|
11
|
+
export { Positioner } from './positioner';
|
|
11
12
|
export { Root } from './root';
|
|
12
13
|
export { Value } from './value';
|
|
@@ -8,35 +8,31 @@ import {
|
|
|
8
8
|
import { unlock } from '../../../lock-unlock';
|
|
9
9
|
import { renderSlotWithChildren } from '../../../utils/render-slot-with-children';
|
|
10
10
|
import itemPopupStyles from '../../../utils/css/item-popup.module.css';
|
|
11
|
-
import resetStyles from '../../../utils/css/resets.module.css';
|
|
12
|
-
import styles from './style.module.css';
|
|
13
11
|
import { Portal } from './portal';
|
|
12
|
+
import { Positioner } from './positioner';
|
|
14
13
|
import type { AutocompletePopupProps } from './types';
|
|
15
|
-
import { ITEM_POPUP_POSITIONER_PROPS } from '../constants';
|
|
16
14
|
|
|
17
15
|
const ThemeProvider: typeof ThemeProviderType =
|
|
18
16
|
unlock( themePrivateApis ).ThemeProvider;
|
|
19
17
|
|
|
20
18
|
export const Popup = forwardRef< HTMLDivElement, AutocompletePopupProps >(
|
|
21
|
-
function Popup( { className, portal, ...restProps }, ref ) {
|
|
22
|
-
const
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
>
|
|
30
|
-
<ThemeProvider>
|
|
31
|
-
<_Autocomplete.Popup
|
|
32
|
-
ref={ ref }
|
|
33
|
-
className={ clsx( itemPopupStyles.popup, className ) }
|
|
34
|
-
{ ...restProps }
|
|
35
|
-
/>
|
|
36
|
-
</ThemeProvider>
|
|
37
|
-
</_Autocomplete.Positioner>
|
|
19
|
+
function Popup( { className, portal, positioner, ...restProps }, ref ) {
|
|
20
|
+
const popupContent = (
|
|
21
|
+
<ThemeProvider>
|
|
22
|
+
<_Autocomplete.Popup
|
|
23
|
+
ref={ ref }
|
|
24
|
+
className={ clsx( itemPopupStyles.popup, className ) }
|
|
25
|
+
{ ...restProps }
|
|
26
|
+
/>
|
|
27
|
+
</ThemeProvider>
|
|
38
28
|
);
|
|
39
29
|
|
|
40
|
-
|
|
30
|
+
const positionedPopup = renderSlotWithChildren(
|
|
31
|
+
positioner,
|
|
32
|
+
<Positioner />,
|
|
33
|
+
popupContent
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return renderSlotWithChildren( portal, <Portal />, positionedPopup );
|
|
41
37
|
}
|
|
42
38
|
);
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { Autocomplete as _Autocomplete } from '@base-ui/react/autocomplete';
|
|
2
2
|
import { forwardRef } from '@wordpress/element';
|
|
3
3
|
import type { PortalProps } from './types';
|
|
4
|
+
import { getWpCompatOverlaySlot } from '../../../utils/wp-compat-overlay-slot';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
* `Autocomplete.Popup` uses this component with default props.
|
|
7
|
+
* Used to apply custom portal behavior to `Autocomplete`'s popup content.
|
|
8
|
+
* `container` defaults to the `@wordpress/ui` compat overlay slot.
|
|
9
9
|
*/
|
|
10
10
|
const Portal = forwardRef< HTMLDivElement, PortalProps >(
|
|
11
|
-
function AutocompletePortal(
|
|
12
|
-
return
|
|
11
|
+
function AutocompletePortal( { container, ...restProps }, ref ) {
|
|
12
|
+
return (
|
|
13
|
+
<_Autocomplete.Portal
|
|
14
|
+
container={ container ?? getWpCompatOverlaySlot() }
|
|
15
|
+
{ ...restProps }
|
|
16
|
+
ref={ ref }
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
13
19
|
}
|
|
14
20
|
);
|
|
15
21
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import { Autocomplete as _Autocomplete } from '@base-ui/react/autocomplete';
|
|
3
|
+
import { forwardRef } from '@wordpress/element';
|
|
4
|
+
import type { PositionerProps } from './types';
|
|
5
|
+
import resetStyles from '../../../utils/css/resets.module.css';
|
|
6
|
+
import styles from './style.module.css';
|
|
7
|
+
import { ITEM_POPUP_POSITIONER_PROPS } from '../constants';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Used to apply custom positioning to `Autocomplete`'s popup content.
|
|
11
|
+
*/
|
|
12
|
+
const Positioner = forwardRef< HTMLDivElement, PositionerProps >(
|
|
13
|
+
function AutocompletePositioner( { className, ...props }, ref ) {
|
|
14
|
+
return (
|
|
15
|
+
<_Autocomplete.Positioner
|
|
16
|
+
{ ...ITEM_POPUP_POSITIONER_PROPS }
|
|
17
|
+
{ ...props }
|
|
18
|
+
ref={ ref }
|
|
19
|
+
className={ clsx(
|
|
20
|
+
resetStyles[ 'box-sizing' ],
|
|
21
|
+
styles.positioner,
|
|
22
|
+
className
|
|
23
|
+
) }
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export { Positioner };
|
|
@@ -13,6 +13,7 @@ const meta: Meta< typeof Autocomplete.Root > = {
|
|
|
13
13
|
component: Autocomplete.Root,
|
|
14
14
|
subcomponents: {
|
|
15
15
|
'Autocomplete.Portal': Autocomplete.Portal,
|
|
16
|
+
'Autocomplete.Positioner': Autocomplete.Positioner,
|
|
16
17
|
'Autocomplete.Popup': Autocomplete.Popup,
|
|
17
18
|
'Autocomplete.Input': Autocomplete.Input,
|
|
18
19
|
'Autocomplete.InputGroup': Autocomplete.InputGroup,
|