@wordpress/components 25.15.0 → 25.16.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 +26 -0
- package/build/border-box-control/border-box-control/component.js.map +1 -1
- package/build/border-box-control/border-box-control/hook.js +3 -1
- package/build/border-box-control/border-box-control/hook.js.map +1 -1
- package/build/border-box-control/types.js.map +1 -1
- package/build/border-control/border-control/component.js +5 -1
- package/build/border-control/border-control/component.js.map +1 -1
- package/build/border-control/border-control/hook.js +18 -15
- package/build/border-control/border-control/hook.js.map +1 -1
- package/build/border-control/border-control-dropdown/component.js +2 -1
- package/build/border-control/border-control-dropdown/component.js.map +1 -1
- package/build/border-control/border-control-style-picker/component.js +21 -49
- package/build/border-control/border-control-style-picker/component.js.map +1 -1
- package/build/border-control/styles.js +15 -27
- package/build/border-control/styles.js.map +1 -1
- package/build/border-control/types.js.map +1 -1
- package/build/box-control/all-input-control.js +35 -29
- package/build/box-control/all-input-control.js.map +1 -1
- package/build/box-control/axial-input-controls.js +40 -54
- package/build/box-control/axial-input-controls.js.map +1 -1
- package/build/box-control/index.js +21 -24
- package/build/box-control/index.js.map +1 -1
- package/build/box-control/input-controls.js +45 -37
- package/build/box-control/input-controls.js.map +1 -1
- package/build/box-control/styles/box-control-styles.js +50 -112
- package/build/box-control/styles/box-control-styles.js.map +1 -1
- package/build/box-control/types.js.map +1 -1
- package/build/box-control/utils.js +123 -8
- package/build/box-control/utils.js.map +1 -1
- package/build/button/index.js +14 -16
- package/build/button/index.js.map +1 -1
- package/build/button/types.js.map +1 -1
- package/build/color-palette/index.native.js +11 -7
- package/build/color-palette/index.native.js.map +1 -1
- package/build/color-picker/hsl-input.js +55 -33
- package/build/color-picker/hsl-input.js.map +1 -1
- package/build/custom-select-control-v2/index.js +3 -2
- package/build/custom-select-control-v2/index.js.map +1 -1
- package/build/mobile/color-settings/palette.screen.native.js +8 -4
- package/build/mobile/color-settings/palette.screen.native.js.map +1 -1
- package/build/slot-fill/bubbles-virtually/use-slot-fills.js +1 -1
- package/build/slot-fill/bubbles-virtually/use-slot-fills.js.map +1 -1
- package/build/theme/styles.js +11 -6
- package/build/theme/styles.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control/utils.js +7 -1
- package/build/toggle-group-control/toggle-group-control/utils.js.map +1 -1
- package/build/tooltip/index.js +35 -8
- package/build/tooltip/index.js.map +1 -1
- package/build/tooltip/types.js.map +1 -1
- package/build-module/border-box-control/border-box-control/component.js.map +1 -1
- package/build-module/border-box-control/border-box-control/hook.js +3 -1
- package/build-module/border-box-control/border-box-control/hook.js.map +1 -1
- package/build-module/border-box-control/types.js.map +1 -1
- package/build-module/border-control/border-control/component.js +5 -1
- package/build-module/border-control/border-control/component.js.map +1 -1
- package/build-module/border-control/border-control/hook.js +18 -15
- package/build-module/border-control/border-control/hook.js.map +1 -1
- package/build-module/border-control/border-control-dropdown/component.js +2 -1
- package/build-module/border-control/border-control-dropdown/component.js.map +1 -1
- package/build-module/border-control/border-control-style-picker/component.js +21 -48
- package/build-module/border-control/border-control-style-picker/component.js.map +1 -1
- package/build-module/border-control/styles.js +14 -24
- package/build-module/border-control/styles.js.map +1 -1
- package/build-module/border-control/types.js.map +1 -1
- package/build-module/box-control/all-input-control.js +38 -28
- package/build-module/box-control/all-input-control.js.map +1 -1
- package/build-module/box-control/axial-input-controls.js +42 -57
- package/build-module/box-control/axial-input-controls.js.map +1 -1
- package/build-module/box-control/index.js +22 -25
- package/build-module/box-control/index.js.map +1 -1
- package/build-module/box-control/input-controls.js +47 -40
- package/build-module/box-control/input-controls.js.map +1 -1
- package/build-module/box-control/styles/box-control-styles.js +45 -105
- package/build-module/box-control/styles/box-control-styles.js.map +1 -1
- package/build-module/box-control/types.js.map +1 -1
- package/build-module/box-control/utils.js +121 -7
- package/build-module/box-control/utils.js.map +1 -1
- package/build-module/button/index.js +14 -16
- package/build-module/button/index.js.map +1 -1
- package/build-module/button/types.js.map +1 -1
- package/build-module/color-palette/index.native.js +11 -7
- package/build-module/color-palette/index.native.js.map +1 -1
- package/build-module/color-picker/hsl-input.js +55 -33
- package/build-module/color-picker/hsl-input.js.map +1 -1
- package/build-module/custom-select-control-v2/index.js +3 -2
- package/build-module/custom-select-control-v2/index.js.map +1 -1
- package/build-module/mobile/color-settings/palette.screen.native.js +8 -4
- package/build-module/mobile/color-settings/palette.screen.native.js.map +1 -1
- package/build-module/slot-fill/bubbles-virtually/use-slot-fills.js +1 -1
- package/build-module/slot-fill/bubbles-virtually/use-slot-fills.js.map +1 -1
- package/build-module/theme/styles.js +11 -2
- package/build-module/theme/styles.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control/utils.js +7 -1
- package/build-module/toggle-group-control/toggle-group-control/utils.js.map +1 -1
- package/build-module/tooltip/index.js +34 -9
- package/build-module/tooltip/index.js.map +1 -1
- package/build-module/tooltip/types.js.map +1 -1
- package/build-style/style-rtl.css +6 -4
- package/build-style/style.css +6 -4
- package/build-types/border-box-control/border-box-control/component.d.ts +1 -0
- package/build-types/border-box-control/border-box-control/component.d.ts.map +1 -1
- package/build-types/border-box-control/border-box-control/hook.d.ts.map +1 -1
- package/build-types/border-box-control/border-box-control-linked-button/hook.d.ts +3 -3
- package/build-types/border-box-control/stories/index.story.d.ts +2 -1
- package/build-types/border-box-control/stories/index.story.d.ts.map +1 -1
- package/build-types/border-box-control/types.d.ts +6 -0
- package/build-types/border-box-control/types.d.ts.map +1 -1
- package/build-types/border-control/border-control/component.d.ts +1 -0
- package/build-types/border-control/border-control/component.d.ts.map +1 -1
- package/build-types/border-control/border-control/hook.d.ts +2 -0
- package/build-types/border-control/border-control/hook.d.ts.map +1 -1
- package/build-types/border-control/border-control-dropdown/component.d.ts +1 -0
- package/build-types/border-control/border-control-dropdown/component.d.ts.map +1 -1
- package/build-types/border-control/border-control-dropdown/hook.d.ts +1 -0
- package/build-types/border-control/border-control-dropdown/hook.d.ts.map +1 -1
- package/build-types/border-control/border-control-style-picker/component.d.ts +3 -4
- package/build-types/border-control/border-control-style-picker/component.d.ts.map +1 -1
- package/build-types/border-control/stories/index.story.d.ts +12 -6
- package/build-types/border-control/stories/index.story.d.ts.map +1 -1
- package/build-types/border-control/styles.d.ts +0 -2
- package/build-types/border-control/styles.d.ts.map +1 -1
- package/build-types/border-control/types.d.ts +12 -1
- package/build-types/border-control/types.d.ts.map +1 -1
- package/build-types/box-control/all-input-control.d.ts +1 -1
- package/build-types/box-control/all-input-control.d.ts.map +1 -1
- package/build-types/box-control/axial-input-controls.d.ts +1 -1
- package/build-types/box-control/axial-input-controls.d.ts.map +1 -1
- package/build-types/box-control/index.d.ts +1 -1
- package/build-types/box-control/index.d.ts.map +1 -1
- package/build-types/box-control/input-controls.d.ts +1 -1
- package/build-types/box-control/input-controls.d.ts.map +1 -1
- package/build-types/box-control/stories/index.story.d.ts +24 -18
- package/build-types/box-control/stories/index.story.d.ts.map +1 -1
- package/build-types/box-control/styles/box-control-styles.d.ts +49 -23
- package/build-types/box-control/styles/box-control-styles.d.ts.map +1 -1
- package/build-types/box-control/types.d.ts +12 -12
- package/build-types/box-control/types.d.ts.map +1 -1
- package/build-types/box-control/utils.d.ts +2 -1
- package/build-types/box-control/utils.d.ts.map +1 -1
- package/build-types/button/deprecated.d.ts +1 -1
- package/build-types/button/index.d.ts.map +1 -1
- package/build-types/button/types.d.ts +7 -3
- package/build-types/button/types.d.ts.map +1 -1
- package/build-types/color-picker/hsl-input.d.ts.map +1 -1
- package/build-types/color-picker/styles.d.ts +1 -1
- package/build-types/custom-select-control-v2/index.d.ts.map +1 -1
- package/build-types/date-time/time/styles.d.ts +4 -4
- package/build-types/focal-point-picker/stories/index.story.d.ts +4 -4
- package/build-types/focal-point-picker/styles/focal-point-picker-style.d.ts +1 -1
- package/build-types/navigation/styles/navigation-styles.d.ts +1 -1
- package/build-types/navigator/navigator-back-button/hook.d.ts +2 -2
- package/build-types/navigator/navigator-button/hook.d.ts +2 -2
- package/build-types/number-control/index.d.ts +1 -1
- package/build-types/number-control/stories/index.story.d.ts +1 -1
- package/build-types/range-control/styles/range-control-styles.d.ts +1 -1
- package/build-types/search-control/index.d.ts +1 -1
- package/build-types/search-control/stories/index.story.d.ts +2 -2
- package/build-types/text-control/index.d.ts +1 -1
- package/build-types/textarea-control/index.d.ts +1 -1
- package/build-types/theme/styles.d.ts.map +1 -1
- package/build-types/toggle-group-control/toggle-group-control/as-button-group.d.ts +1 -1
- package/build-types/toggle-group-control/toggle-group-control/as-radio-group.d.ts +1 -1
- package/build-types/toggle-group-control/toggle-group-control/utils.d.ts.map +1 -1
- package/build-types/toggle-group-control/toggle-group-control-option/component.d.ts +1 -1
- package/build-types/toggle-group-control/toggle-group-control-option-icon/component.d.ts +1 -1
- package/build-types/toolbar/toolbar-button/index.d.ts +1 -1
- package/build-types/tooltip/index.d.ts +1 -1
- package/build-types/tooltip/index.d.ts.map +1 -1
- package/build-types/tooltip/stories/index.story.d.ts +10 -1
- package/build-types/tooltip/stories/index.story.d.ts.map +1 -1
- package/build-types/tooltip/types.d.ts +3 -0
- package/build-types/tooltip/types.d.ts.map +1 -1
- package/build-types/unit-control/index.d.ts +1 -1
- package/build-types/unit-control/styles/unit-control-styles.d.ts +1 -1
- package/package.json +19 -19
- package/src/border-box-control/border-box-control/component.tsx +0 -1
- package/src/border-box-control/border-box-control/hook.ts +5 -1
- package/src/border-box-control/types.ts +6 -0
- package/src/border-control/border-control/component.tsx +4 -0
- package/src/border-control/border-control/hook.ts +22 -16
- package/src/border-control/border-control-dropdown/component.tsx +2 -1
- package/src/border-control/border-control-style-picker/component.tsx +31 -66
- package/src/border-control/styles.ts +0 -15
- package/src/border-control/types.ts +15 -1
- package/src/box-control/all-input-control.tsx +57 -34
- package/src/box-control/axial-input-controls.tsx +79 -69
- package/src/box-control/index.tsx +47 -54
- package/src/box-control/input-controls.tsx +114 -83
- package/src/box-control/styles/box-control-styles.ts +21 -61
- package/src/box-control/test/index.tsx +126 -18
- package/src/box-control/types.ts +10 -21
- package/src/box-control/utils.ts +43 -8
- package/src/button/README.md +1 -1
- package/src/button/index.tsx +21 -33
- package/src/button/test/index.tsx +122 -0
- package/src/button/types.ts +7 -3
- package/src/circular-option-picker/test/index.tsx +10 -16
- package/src/color-palette/index.native.js +18 -7
- package/src/color-picker/hsl-input.tsx +56 -30
- package/src/color-picker/test/index.tsx +190 -16
- package/src/custom-select-control-v2/index.tsx +5 -2
- package/src/mobile/color-settings/palette.screen.native.js +7 -5
- package/src/palette-edit/test/index.tsx +326 -10
- package/src/slot-fill/bubbles-virtually/use-slot-fills.ts +1 -1
- package/src/tabs/test/index.tsx +3 -1
- package/src/theme/styles.ts +3 -1
- package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +6 -6
- package/src/toggle-group-control/test/index.tsx +73 -36
- package/src/toggle-group-control/toggle-group-control/utils.ts +8 -3
- package/src/tooltip/README.md +4 -0
- package/src/tooltip/index.tsx +46 -8
- package/src/tooltip/stories/index.story.tsx +18 -1
- package/src/tooltip/test/index.tsx +77 -12
- package/src/tooltip/types.ts +4 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/build/border-control/border-control-style-picker/hook.js +0 -41
- package/build/border-control/border-control-style-picker/hook.js.map +0 -1
- package/build/box-control/styles/box-control-visualizer-styles.js +0 -93
- package/build/box-control/styles/box-control-visualizer-styles.js.map +0 -1
- package/build/box-control/unit-control.js +0 -76
- package/build/box-control/unit-control.js.map +0 -1
- package/build-module/border-control/border-control-style-picker/hook.js +0 -32
- package/build-module/border-control/border-control-style-picker/hook.js.map +0 -1
- package/build-module/box-control/styles/box-control-visualizer-styles.js +0 -86
- package/build-module/box-control/styles/box-control-visualizer-styles.js.map +0 -1
- package/build-module/box-control/unit-control.js +0 -68
- package/build-module/box-control/unit-control.js.map +0 -1
- package/build-types/border-control/border-control-style-picker/hook.d.ts +0 -267
- package/build-types/border-control/border-control-style-picker/hook.d.ts.map +0 -1
- package/build-types/box-control/styles/box-control-visualizer-styles.d.ts +0 -46
- package/build-types/box-control/styles/box-control-visualizer-styles.d.ts.map +0 -1
- package/build-types/box-control/unit-control.d.ts +0 -4
- package/build-types/box-control/unit-control.d.ts.map +0 -1
- package/src/border-control/border-control-style-picker/hook.ts +0 -35
- package/src/box-control/styles/box-control-visualizer-styles.ts +0 -75
- package/src/box-control/unit-control.tsx +0 -74
|
@@ -240,7 +240,7 @@ exports[`ToggleGroupControl controlled should render correctly with icons 1`] =
|
|
|
240
240
|
class="components-toggle-group-control emotion-8 emotion-9"
|
|
241
241
|
data-wp-c16t="true"
|
|
242
242
|
data-wp-component="ToggleGroupControl"
|
|
243
|
-
id="toggle-group-control-as-radio-group-
|
|
243
|
+
id="toggle-group-control-as-radio-group-10"
|
|
244
244
|
role="radiogroup"
|
|
245
245
|
>
|
|
246
246
|
<div
|
|
@@ -254,7 +254,7 @@ exports[`ToggleGroupControl controlled should render correctly with icons 1`] =
|
|
|
254
254
|
data-value="uppercase"
|
|
255
255
|
data-wp-c16t="true"
|
|
256
256
|
data-wp-component="ToggleGroupControlOptionBase"
|
|
257
|
-
id="toggle-group-control-as-radio-group-
|
|
257
|
+
id="toggle-group-control-as-radio-group-10-24"
|
|
258
258
|
role="radio"
|
|
259
259
|
type="button"
|
|
260
260
|
value="uppercase"
|
|
@@ -292,7 +292,7 @@ exports[`ToggleGroupControl controlled should render correctly with icons 1`] =
|
|
|
292
292
|
data-value="lowercase"
|
|
293
293
|
data-wp-c16t="true"
|
|
294
294
|
data-wp-component="ToggleGroupControlOptionBase"
|
|
295
|
-
id="toggle-group-control-as-radio-group-
|
|
295
|
+
id="toggle-group-control-as-radio-group-10-25"
|
|
296
296
|
role="radio"
|
|
297
297
|
type="button"
|
|
298
298
|
value="lowercase"
|
|
@@ -488,7 +488,7 @@ exports[`ToggleGroupControl controlled should render correctly with text options
|
|
|
488
488
|
class="components-toggle-group-control emotion-8 emotion-9"
|
|
489
489
|
data-wp-c16t="true"
|
|
490
490
|
data-wp-component="ToggleGroupControl"
|
|
491
|
-
id="toggle-group-control-as-radio-group-
|
|
491
|
+
id="toggle-group-control-as-radio-group-9"
|
|
492
492
|
role="radiogroup"
|
|
493
493
|
>
|
|
494
494
|
<div
|
|
@@ -501,7 +501,7 @@ exports[`ToggleGroupControl controlled should render correctly with text options
|
|
|
501
501
|
data-value="rigas"
|
|
502
502
|
data-wp-c16t="true"
|
|
503
503
|
data-wp-component="ToggleGroupControlOptionBase"
|
|
504
|
-
id="toggle-group-control-as-radio-group-
|
|
504
|
+
id="toggle-group-control-as-radio-group-9-22"
|
|
505
505
|
role="radio"
|
|
506
506
|
type="button"
|
|
507
507
|
value="rigas"
|
|
@@ -523,7 +523,7 @@ exports[`ToggleGroupControl controlled should render correctly with text options
|
|
|
523
523
|
data-value="jack"
|
|
524
524
|
data-wp-c16t="true"
|
|
525
525
|
data-wp-component="ToggleGroupControlOptionBase"
|
|
526
|
-
id="toggle-group-control-as-radio-group-
|
|
526
|
+
id="toggle-group-control-as-radio-group-9-23"
|
|
527
527
|
role="radio"
|
|
528
528
|
type="button"
|
|
529
529
|
value="jack"
|
|
@@ -117,6 +117,22 @@ describe.each( [
|
|
|
117
117
|
expect( container ).toMatchSnapshot();
|
|
118
118
|
} );
|
|
119
119
|
} );
|
|
120
|
+
it( 'should render with the correct option initially selected when `value` is defined', () => {
|
|
121
|
+
render(
|
|
122
|
+
<Component value="jack" label="Test Toggle Group Control">
|
|
123
|
+
{ options }
|
|
124
|
+
</Component>
|
|
125
|
+
);
|
|
126
|
+
expect( screen.getByRole( 'radio', { name: 'R' } ) ).not.toBeChecked();
|
|
127
|
+
expect( screen.getByRole( 'radio', { name: 'J' } ) ).toBeChecked();
|
|
128
|
+
} );
|
|
129
|
+
it( 'should render without a selected option when `value` is `undefined`', () => {
|
|
130
|
+
render(
|
|
131
|
+
<Component label="Test Toggle Group Control">{ options }</Component>
|
|
132
|
+
);
|
|
133
|
+
expect( screen.getByRole( 'radio', { name: 'R' } ) ).not.toBeChecked();
|
|
134
|
+
expect( screen.getByRole( 'radio', { name: 'J' } ) ).not.toBeChecked();
|
|
135
|
+
} );
|
|
120
136
|
it( 'should call onChange with proper value', async () => {
|
|
121
137
|
const mockOnChange = jest.fn();
|
|
122
138
|
|
|
@@ -193,7 +209,7 @@ describe.each( [
|
|
|
193
209
|
} );
|
|
194
210
|
|
|
195
211
|
if ( mode === 'controlled' ) {
|
|
196
|
-
it( 'should reset values correctly', async () => {
|
|
212
|
+
it( 'should reset values correctly when default value is undefined', async () => {
|
|
197
213
|
render(
|
|
198
214
|
<Component label="Test Toggle Group Control">
|
|
199
215
|
{ options }
|
|
@@ -208,56 +224,77 @@ describe.each( [
|
|
|
208
224
|
expect( jackOption ).not.toBeChecked();
|
|
209
225
|
expect( rigasOption ).toBeChecked();
|
|
210
226
|
|
|
211
|
-
await press.ArrowRight();
|
|
212
|
-
|
|
213
|
-
expect( rigasOption ).not.toBeChecked();
|
|
214
|
-
expect( jackOption ).toBeChecked();
|
|
215
|
-
|
|
216
227
|
await click( screen.getByRole( 'button', { name: 'Reset' } ) );
|
|
217
228
|
|
|
218
229
|
expect( rigasOption ).not.toBeChecked();
|
|
219
230
|
expect( jackOption ).not.toBeChecked();
|
|
220
231
|
} );
|
|
221
232
|
|
|
222
|
-
it( 'should
|
|
233
|
+
it( 'should reset values correctly when default value is defined', async () => {
|
|
223
234
|
render(
|
|
224
|
-
<Component
|
|
225
|
-
value="rigas"
|
|
226
|
-
label="Test Toggle Group Control"
|
|
227
|
-
extraButtonOptions={ [
|
|
228
|
-
{ name: 'Rigas', value: 'rigas' },
|
|
229
|
-
{ name: 'Jack', value: 'jack' },
|
|
230
|
-
] }
|
|
231
|
-
>
|
|
235
|
+
<Component label="Test Toggle Group Control" value="rigas">
|
|
232
236
|
{ options }
|
|
233
237
|
</Component>
|
|
234
238
|
);
|
|
235
239
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
expect( screen.getByRole( 'radio', { name: 'J' } ) ).toBeChecked();
|
|
243
|
-
expect(
|
|
244
|
-
screen.getByRole( 'radio', { name: 'R' } )
|
|
245
|
-
).not.toBeChecked();
|
|
240
|
+
const rigasOption = screen.getByRole( 'radio', {
|
|
241
|
+
name: 'R',
|
|
242
|
+
} );
|
|
243
|
+
const jackOption = screen.getByRole( 'radio', {
|
|
244
|
+
name: 'J',
|
|
245
|
+
} );
|
|
246
246
|
|
|
247
|
-
|
|
248
|
-
expect(
|
|
249
|
-
expect(
|
|
250
|
-
screen.getByRole( 'radio', { name: 'J' } )
|
|
251
|
-
).not.toBeChecked();
|
|
247
|
+
expect( rigasOption ).toBeChecked();
|
|
248
|
+
expect( jackOption ).not.toBeChecked();
|
|
252
249
|
|
|
253
250
|
await click( screen.getByRole( 'button', { name: 'Reset' } ) );
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
).not.toBeChecked();
|
|
257
|
-
expect(
|
|
258
|
-
screen.getByRole( 'radio', { name: 'J' } )
|
|
259
|
-
).not.toBeChecked();
|
|
251
|
+
|
|
252
|
+
expect( rigasOption ).not.toBeChecked();
|
|
253
|
+
expect( jackOption ).not.toBeChecked();
|
|
260
254
|
} );
|
|
255
|
+
|
|
256
|
+
describe.each( [
|
|
257
|
+
[ 'undefined', undefined ],
|
|
258
|
+
[ 'defined', 'rigas' ],
|
|
259
|
+
] )(
|
|
260
|
+
'should update correctly when triggered by external updates',
|
|
261
|
+
( defaultValueType, defaultValue ) => {
|
|
262
|
+
it( `when default value is ${ defaultValueType }`, async () => {
|
|
263
|
+
render(
|
|
264
|
+
<Component
|
|
265
|
+
value={ defaultValue }
|
|
266
|
+
label="Test Toggle Group Control"
|
|
267
|
+
extraButtonOptions={ [
|
|
268
|
+
{ name: 'Rigas', value: 'rigas' },
|
|
269
|
+
{ name: 'Jack', value: 'jack' },
|
|
270
|
+
] }
|
|
271
|
+
>
|
|
272
|
+
{ options }
|
|
273
|
+
</Component>
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
await click(
|
|
277
|
+
screen.getByRole( 'button', { name: 'Jack' } )
|
|
278
|
+
);
|
|
279
|
+
expect(
|
|
280
|
+
screen.getByRole( 'radio', { name: 'J' } )
|
|
281
|
+
).toBeChecked();
|
|
282
|
+
expect(
|
|
283
|
+
screen.getByRole( 'radio', { name: 'R' } )
|
|
284
|
+
).not.toBeChecked();
|
|
285
|
+
|
|
286
|
+
await click(
|
|
287
|
+
screen.getByRole( 'button', { name: 'Rigas' } )
|
|
288
|
+
);
|
|
289
|
+
expect(
|
|
290
|
+
screen.getByRole( 'radio', { name: 'R' } )
|
|
291
|
+
).toBeChecked();
|
|
292
|
+
expect(
|
|
293
|
+
screen.getByRole( 'radio', { name: 'J' } )
|
|
294
|
+
).not.toBeChecked();
|
|
295
|
+
} );
|
|
296
|
+
}
|
|
297
|
+
);
|
|
261
298
|
}
|
|
262
299
|
|
|
263
300
|
describe( 'isDeselectable', () => {
|
|
@@ -21,16 +21,21 @@ type ValueProp = ToggleGroupControlProps[ 'value' ];
|
|
|
21
21
|
export function useComputeControlledOrUncontrolledValue(
|
|
22
22
|
valueProp: ValueProp
|
|
23
23
|
): { value: ValueProp; defaultValue: ValueProp } {
|
|
24
|
+
const isInitialRender = useRef( true );
|
|
24
25
|
const prevValueProp = usePrevious( valueProp );
|
|
25
26
|
const prevIsControlled = useRef( false );
|
|
26
27
|
|
|
28
|
+
useEffect( () => {
|
|
29
|
+
if ( isInitialRender.current ) {
|
|
30
|
+
isInitialRender.current = false;
|
|
31
|
+
}
|
|
32
|
+
}, [] );
|
|
33
|
+
|
|
27
34
|
// Assume the component is being used in controlled mode on the first re-render
|
|
28
35
|
// that has a different `valueProp` from the previous render.
|
|
29
36
|
const isControlled =
|
|
30
37
|
prevIsControlled.current ||
|
|
31
|
-
( prevValueProp !==
|
|
32
|
-
valueProp !== undefined &&
|
|
33
|
-
prevValueProp !== valueProp );
|
|
38
|
+
( ! isInitialRender.current && prevValueProp !== valueProp );
|
|
34
39
|
useEffect( () => {
|
|
35
40
|
prevIsControlled.current = isControlled;
|
|
36
41
|
}, [ isControlled ] );
|
package/src/tooltip/README.md
CHANGED
|
@@ -16,6 +16,10 @@ const MyTooltip = () => (
|
|
|
16
16
|
);
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
### Nested tooltips
|
|
20
|
+
|
|
21
|
+
In case one or more `Tooltip` components are rendered inside another `Tooltip` component, only the tooltip associated to the outermost `Tooltip` component will be rendered in the browser and shown to the user appropriately. The rest of the nested `Tooltip` components will simply no-op and pass-through their anchor.
|
|
22
|
+
|
|
19
23
|
## Props
|
|
20
24
|
|
|
21
25
|
The component accepts the following props:
|
package/src/tooltip/index.tsx
CHANGED
|
@@ -8,22 +8,41 @@ import * as Ariakit from '@ariakit/react';
|
|
|
8
8
|
* WordPress dependencies
|
|
9
9
|
*/
|
|
10
10
|
import { useInstanceId } from '@wordpress/compose';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
Children,
|
|
13
|
+
useContext,
|
|
14
|
+
createContext,
|
|
15
|
+
forwardRef,
|
|
16
|
+
} from '@wordpress/element';
|
|
12
17
|
import deprecated from '@wordpress/deprecated';
|
|
13
18
|
|
|
14
19
|
/**
|
|
15
20
|
* Internal dependencies
|
|
16
21
|
*/
|
|
17
|
-
import type {
|
|
22
|
+
import type {
|
|
23
|
+
TooltipProps,
|
|
24
|
+
TooltipInternalContext as TooltipInternalContextType,
|
|
25
|
+
} from './types';
|
|
18
26
|
import Shortcut from '../shortcut';
|
|
19
27
|
import { positionToPlacement } from '../popover/utils';
|
|
20
28
|
|
|
29
|
+
const TooltipInternalContext = createContext< TooltipInternalContextType >( {
|
|
30
|
+
isNestedInTooltip: false,
|
|
31
|
+
} );
|
|
32
|
+
|
|
21
33
|
/**
|
|
22
34
|
* Time over anchor to wait before showing tooltip
|
|
23
35
|
*/
|
|
24
36
|
export const TOOLTIP_DELAY = 700;
|
|
25
37
|
|
|
26
|
-
|
|
38
|
+
const CONTEXT_VALUE = {
|
|
39
|
+
isNestedInTooltip: true,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function UnforwardedTooltip(
|
|
43
|
+
props: TooltipProps,
|
|
44
|
+
ref: React.ForwardedRef< any >
|
|
45
|
+
) {
|
|
27
46
|
const {
|
|
28
47
|
children,
|
|
29
48
|
delay = TOOLTIP_DELAY,
|
|
@@ -32,8 +51,12 @@ function Tooltip( props: TooltipProps ) {
|
|
|
32
51
|
position,
|
|
33
52
|
shortcut,
|
|
34
53
|
text,
|
|
54
|
+
|
|
55
|
+
...restProps
|
|
35
56
|
} = props;
|
|
36
57
|
|
|
58
|
+
const { isNestedInTooltip } = useContext( TooltipInternalContext );
|
|
59
|
+
|
|
37
60
|
const baseId = useInstanceId( Tooltip, 'tooltip' );
|
|
38
61
|
const describedById = text || shortcut ? baseId : undefined;
|
|
39
62
|
|
|
@@ -43,7 +66,7 @@ function Tooltip( props: TooltipProps ) {
|
|
|
43
66
|
if ( 'development' === process.env.NODE_ENV ) {
|
|
44
67
|
// eslint-disable-next-line no-console
|
|
45
68
|
console.error(
|
|
46
|
-
'Tooltip should be called with only a single child element.'
|
|
69
|
+
'wp-components.Tooltip should be called with only a single child element.'
|
|
47
70
|
);
|
|
48
71
|
}
|
|
49
72
|
}
|
|
@@ -64,24 +87,37 @@ function Tooltip( props: TooltipProps ) {
|
|
|
64
87
|
}
|
|
65
88
|
computedPlacement = computedPlacement || 'bottom';
|
|
66
89
|
|
|
67
|
-
|
|
90
|
+
// Removing the `Ariakit` namespace from the hook name allows ESLint to
|
|
91
|
+
// properly identify the hook, and apply the correct linting rules.
|
|
92
|
+
const useAriakitTooltipStore = Ariakit.useTooltipStore;
|
|
93
|
+
const tooltipStore = useAriakitTooltipStore( {
|
|
68
94
|
placement: computedPlacement,
|
|
69
95
|
showTimeout: delay,
|
|
70
96
|
} );
|
|
71
97
|
|
|
98
|
+
if ( isNestedInTooltip ) {
|
|
99
|
+
return isOnlyChild ? (
|
|
100
|
+
<Ariakit.Role { ...restProps } render={ children } />
|
|
101
|
+
) : (
|
|
102
|
+
children
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
72
106
|
return (
|
|
73
|
-
|
|
107
|
+
<TooltipInternalContext.Provider value={ CONTEXT_VALUE }>
|
|
74
108
|
<Ariakit.TooltipAnchor
|
|
75
109
|
onClick={ hideOnClick ? tooltipStore.hide : undefined }
|
|
76
110
|
store={ tooltipStore }
|
|
77
111
|
render={ isOnlyChild ? children : undefined }
|
|
112
|
+
ref={ ref }
|
|
78
113
|
>
|
|
79
114
|
{ isOnlyChild ? undefined : children }
|
|
80
115
|
</Ariakit.TooltipAnchor>
|
|
81
116
|
{ isOnlyChild && ( text || shortcut ) && (
|
|
82
117
|
<Ariakit.Tooltip
|
|
83
|
-
|
|
118
|
+
{ ...restProps }
|
|
84
119
|
className="components-tooltip"
|
|
120
|
+
unmountOnHide
|
|
85
121
|
gutter={ 4 }
|
|
86
122
|
id={ describedById }
|
|
87
123
|
overflowPadding={ 0.5 }
|
|
@@ -98,8 +134,10 @@ function Tooltip( props: TooltipProps ) {
|
|
|
98
134
|
) }
|
|
99
135
|
</Ariakit.Tooltip>
|
|
100
136
|
) }
|
|
101
|
-
|
|
137
|
+
</TooltipInternalContext.Provider>
|
|
102
138
|
);
|
|
103
139
|
}
|
|
104
140
|
|
|
141
|
+
export const Tooltip = forwardRef( UnforwardedTooltip );
|
|
142
|
+
|
|
105
143
|
export default Tooltip;
|
|
@@ -30,7 +30,7 @@ const meta: Meta< typeof Tooltip > = {
|
|
|
30
30
|
'bottom right',
|
|
31
31
|
],
|
|
32
32
|
},
|
|
33
|
-
shortcut: { control: { type: '
|
|
33
|
+
shortcut: { control: { type: 'object' } },
|
|
34
34
|
},
|
|
35
35
|
parameters: {
|
|
36
36
|
controls: { expanded: true },
|
|
@@ -57,3 +57,20 @@ KeyboardShortcut.args = {
|
|
|
57
57
|
ariaLabel: shortcutAriaLabel.primaryShift( ',' ),
|
|
58
58
|
},
|
|
59
59
|
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* In case one or more `Tooltip` components are rendered inside another
|
|
63
|
+
* `Tooltip` component, only the tooltip associated to the outermost `Tooltip`
|
|
64
|
+
* component will be rendered in the browser and shown to the user
|
|
65
|
+
* appropriately. The rest of the nested `Tooltip` components will simply no-op
|
|
66
|
+
* and pass-through their anchor.
|
|
67
|
+
*/
|
|
68
|
+
export const Nested: StoryFn< typeof Tooltip > = Template.bind( {} );
|
|
69
|
+
Nested.args = {
|
|
70
|
+
children: (
|
|
71
|
+
<Tooltip text="Nested tooltip text (that will never show)">
|
|
72
|
+
<Button variant="primary">Tooltip Anchor</Button>
|
|
73
|
+
</Tooltip>
|
|
74
|
+
),
|
|
75
|
+
text: 'Outer tooltip text',
|
|
76
|
+
};
|
|
@@ -12,12 +12,11 @@ import { shortcutAriaLabel } from '@wordpress/keycodes';
|
|
|
12
12
|
/**
|
|
13
13
|
* Internal dependencies
|
|
14
14
|
*/
|
|
15
|
-
import Button from '../../button';
|
|
16
15
|
import Modal from '../../modal';
|
|
17
16
|
import Tooltip, { TOOLTIP_DELAY } from '..';
|
|
18
17
|
|
|
19
18
|
const props = {
|
|
20
|
-
children: <
|
|
19
|
+
children: <button>Tooltip anchor</button>,
|
|
21
20
|
text: 'tooltip text',
|
|
22
21
|
};
|
|
23
22
|
|
|
@@ -56,8 +55,8 @@ describe( 'Tooltip', () => {
|
|
|
56
55
|
render(
|
|
57
56
|
// @ts-expect-error Tooltip cannot have more than one child element
|
|
58
57
|
<Tooltip { ...props }>
|
|
59
|
-
<
|
|
60
|
-
<
|
|
58
|
+
<button>First button</button>
|
|
59
|
+
<button>Second button</button>
|
|
61
60
|
</Tooltip>
|
|
62
61
|
);
|
|
63
62
|
|
|
@@ -102,6 +101,17 @@ describe( 'Tooltip', () => {
|
|
|
102
101
|
screen.queryByRole( 'button', { description: 'tooltip text' } )
|
|
103
102
|
).not.toBeInTheDocument();
|
|
104
103
|
} );
|
|
104
|
+
|
|
105
|
+
it( 'should not leak Tooltip props to the tooltip anchor', () => {
|
|
106
|
+
render(
|
|
107
|
+
<Tooltip data-foo>
|
|
108
|
+
<button>Anchor</button>
|
|
109
|
+
</Tooltip>
|
|
110
|
+
);
|
|
111
|
+
expect(
|
|
112
|
+
screen.getByRole( 'button', { name: 'Anchor' } )
|
|
113
|
+
).not.toHaveAttribute( 'data-foo' );
|
|
114
|
+
} );
|
|
105
115
|
} );
|
|
106
116
|
|
|
107
117
|
describe( 'keyboard focus', () => {
|
|
@@ -142,9 +152,7 @@ describe( 'Tooltip', () => {
|
|
|
142
152
|
render(
|
|
143
153
|
<>
|
|
144
154
|
<Tooltip { ...props }>
|
|
145
|
-
<
|
|
146
|
-
Tooltip anchor
|
|
147
|
-
</Button>
|
|
155
|
+
<button aria-disabled="true">Tooltip anchor</button>
|
|
148
156
|
</Tooltip>
|
|
149
157
|
<button>Focus me</button>
|
|
150
158
|
</>
|
|
@@ -196,9 +204,7 @@ describe( 'Tooltip', () => {
|
|
|
196
204
|
render(
|
|
197
205
|
<>
|
|
198
206
|
<Tooltip { ...props }>
|
|
199
|
-
<
|
|
200
|
-
Tooltip anchor
|
|
201
|
-
</Button>
|
|
207
|
+
<button aria-disabled="true">Tooltip anchor</button>
|
|
202
208
|
</Tooltip>
|
|
203
209
|
<button>Focus me</button>
|
|
204
210
|
</>
|
|
@@ -310,12 +316,12 @@ describe( 'Tooltip', () => {
|
|
|
310
316
|
|
|
311
317
|
render(
|
|
312
318
|
<Tooltip { ...props }>
|
|
313
|
-
<
|
|
319
|
+
<button
|
|
314
320
|
onMouseEnter={ onMouseEnterMock }
|
|
315
321
|
onMouseLeave={ onMouseLeaveMock }
|
|
316
322
|
>
|
|
317
323
|
Tooltip anchor
|
|
318
|
-
</
|
|
324
|
+
</button>
|
|
319
325
|
</Tooltip>
|
|
320
326
|
);
|
|
321
327
|
|
|
@@ -436,4 +442,63 @@ describe( 'Tooltip', () => {
|
|
|
436
442
|
await waitExpectTooltipToHide();
|
|
437
443
|
} );
|
|
438
444
|
} );
|
|
445
|
+
|
|
446
|
+
describe( 'nested', () => {
|
|
447
|
+
it( 'should render the outer tooltip and ignore nested tooltips', async () => {
|
|
448
|
+
render(
|
|
449
|
+
<Tooltip text="Outer tooltip">
|
|
450
|
+
<Tooltip text="Middle tooltip">
|
|
451
|
+
<Tooltip text="Inner tooltip">
|
|
452
|
+
<button>Tooltip anchor</button>
|
|
453
|
+
</Tooltip>
|
|
454
|
+
</Tooltip>
|
|
455
|
+
</Tooltip>
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
// Hover the anchor. Only the outer tooltip should show.
|
|
459
|
+
await hover(
|
|
460
|
+
screen.getByRole( 'button', {
|
|
461
|
+
name: 'Tooltip anchor',
|
|
462
|
+
} )
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
await waitFor( () =>
|
|
466
|
+
expect(
|
|
467
|
+
screen.getByRole( 'tooltip', { name: 'Outer tooltip' } )
|
|
468
|
+
).toBeVisible()
|
|
469
|
+
);
|
|
470
|
+
expect(
|
|
471
|
+
screen.queryByRole( 'tooltip', { name: 'Middle tooltip' } )
|
|
472
|
+
).not.toBeInTheDocument();
|
|
473
|
+
expect(
|
|
474
|
+
screen.queryByRole( 'tooltip', { name: 'Inner tooltip' } )
|
|
475
|
+
).not.toBeInTheDocument();
|
|
476
|
+
expect(
|
|
477
|
+
screen.getByRole( 'button', {
|
|
478
|
+
description: 'Outer tooltip',
|
|
479
|
+
} )
|
|
480
|
+
).toBeVisible();
|
|
481
|
+
|
|
482
|
+
// Hover outside of the anchor, tooltip should hide
|
|
483
|
+
await hoverOutside();
|
|
484
|
+
await waitFor( () =>
|
|
485
|
+
expect(
|
|
486
|
+
screen.queryByRole( 'tooltip', { name: 'Outer tooltip' } )
|
|
487
|
+
).not.toBeInTheDocument()
|
|
488
|
+
);
|
|
489
|
+
} );
|
|
490
|
+
|
|
491
|
+
it( 'should not leak Tooltip component classname to the anchor element', () => {
|
|
492
|
+
render(
|
|
493
|
+
<Tooltip>
|
|
494
|
+
<Tooltip>
|
|
495
|
+
<button>Anchor</button>
|
|
496
|
+
</Tooltip>
|
|
497
|
+
</Tooltip>
|
|
498
|
+
);
|
|
499
|
+
expect(
|
|
500
|
+
screen.getByRole( 'button', { name: 'Anchor' } )
|
|
501
|
+
).not.toHaveClass( 'components-tooltip' );
|
|
502
|
+
} );
|
|
503
|
+
} );
|
|
439
504
|
} );
|