@wordpress/components 29.6.0 → 29.8.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 +34 -0
- package/build/angle-picker-control/index.js +1 -1
- package/build/angle-picker-control/index.js.map +1 -1
- package/build/autocomplete/index.js +5 -30
- package/build/autocomplete/index.js.map +1 -1
- package/build/custom-select-control-v2/styles.js +9 -9
- package/build/custom-select-control-v2/styles.js.map +1 -1
- package/build/number-control/index.js +6 -4
- package/build/number-control/index.js.map +1 -1
- package/build/popover/index.js +29 -17
- package/build/popover/index.js.map +1 -1
- package/build/popover/types.js.map +1 -1
- package/build/range-control/index.js +6 -5
- package/build/range-control/index.js.map +1 -1
- package/build/toolbar/toolbar-dropdown-menu/index.js +4 -3
- package/build/toolbar/toolbar-dropdown-menu/index.js.map +1 -1
- package/build/toolbar/toolbar-item/index.js +4 -3
- package/build/toolbar/toolbar-item/index.js.map +1 -1
- package/build/utils/get-node-text.js +30 -0
- package/build/utils/get-node-text.js.map +1 -0
- package/build/utils/math.js +18 -15
- package/build/utils/math.js.map +1 -1
- package/build-module/angle-picker-control/index.js +1 -1
- package/build-module/angle-picker-control/index.js.map +1 -1
- package/build-module/autocomplete/index.js +3 -28
- package/build-module/autocomplete/index.js.map +1 -1
- package/build-module/custom-select-control-v2/styles.js +9 -9
- package/build-module/custom-select-control-v2/styles.js.map +1 -1
- package/build-module/number-control/index.js +7 -5
- package/build-module/number-control/index.js.map +1 -1
- package/build-module/popover/index.js +28 -16
- package/build-module/popover/index.js.map +1 -1
- package/build-module/popover/types.js.map +1 -1
- package/build-module/range-control/index.js +6 -5
- package/build-module/range-control/index.js.map +1 -1
- package/build-module/toolbar/toolbar-dropdown-menu/index.js +3 -2
- package/build-module/toolbar/toolbar-dropdown-menu/index.js.map +1 -1
- package/build-module/toolbar/toolbar-item/index.js +3 -2
- package/build-module/toolbar/toolbar-item/index.js.map +1 -1
- package/build-module/utils/get-node-text.js +24 -0
- package/build-module/utils/get-node-text.js.map +1 -0
- package/build-module/utils/math.js +17 -14
- package/build-module/utils/math.js.map +1 -1
- package/build-style/style-rtl.css +15 -13
- package/build-style/style.css +15 -13
- package/build-types/angle-picker-control/index.d.ts +1 -1
- package/build-types/autocomplete/index.d.ts +2 -2
- package/build-types/autocomplete/index.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/styles.d.ts.map +1 -1
- package/build-types/number-control/index.d.ts.map +1 -1
- package/build-types/popover/index.d.ts +18 -2
- package/build-types/popover/index.d.ts.map +1 -1
- package/build-types/popover/stories/e2e/index.story.d.ts +8 -1
- package/build-types/popover/stories/e2e/index.story.d.ts.map +1 -1
- package/build-types/popover/stories/index.story.d.ts +1 -0
- package/build-types/popover/stories/index.story.d.ts.map +1 -1
- package/build-types/popover/test/utils/index.d.ts.map +1 -1
- package/build-types/popover/types.d.ts +9 -0
- package/build-types/popover/types.d.ts.map +1 -1
- package/build-types/range-control/index.d.ts +6 -5
- package/build-types/range-control/index.d.ts.map +1 -1
- package/build-types/toolbar/toolbar-dropdown-menu/index.d.ts +2 -2
- package/build-types/toolbar/toolbar-dropdown-menu/index.d.ts.map +1 -1
- package/build-types/toolbar/toolbar-item/index.d.ts +2 -2
- package/build-types/toolbar/toolbar-item/index.d.ts.map +1 -1
- package/build-types/utils/get-node-text.d.ts +3 -0
- package/build-types/utils/get-node-text.d.ts.map +1 -0
- package/build-types/utils/math.d.ts +10 -11
- package/build-types/utils/math.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/angle-picker-control/README.md +1 -1
- package/src/angle-picker-control/index.tsx +1 -1
- package/src/autocomplete/index.tsx +3 -30
- package/src/button/style.scss +1 -1
- package/src/combobox-control/style.scss +4 -2
- package/src/custom-select-control-v2/styles.ts +1 -0
- package/src/form-token-field/style.scss +6 -6
- package/src/number-control/index.tsx +8 -7
- package/src/number-control/test/index.tsx +15 -2
- package/src/popover/index.tsx +34 -20
- package/src/popover/stories/index.story.tsx +83 -2
- package/src/popover/test/utils/index.tsx +0 -1
- package/src/popover/types.ts +10 -0
- package/src/range-control/index.tsx +6 -5
- package/src/toolbar/toolbar-dropdown-menu/index.tsx +3 -2
- package/src/toolbar/toolbar-item/index.tsx +3 -2
- package/src/utils/get-node-text.ts +24 -0
- package/src/utils/math.js +17 -22
- package/src/utils/test/get-node-text.js +37 -0
- package/src/utils/test/math.js +28 -32
- package/src/utils/theme-variables.scss +0 -4
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -25,22 +25,21 @@ export function subtract(...args: Array<number | string>): number;
|
|
|
25
25
|
/**
|
|
26
26
|
* Clamps a value based on a min/max range.
|
|
27
27
|
*
|
|
28
|
-
* @param {number} value The value.
|
|
29
|
-
* @param {number}
|
|
30
|
-
* @param {number}
|
|
28
|
+
* @param {number|string} value The value.
|
|
29
|
+
* @param {number} min The minimum range.
|
|
30
|
+
* @param {number} max The maximum range.
|
|
31
31
|
*
|
|
32
32
|
* @return {number} The clamped value.
|
|
33
33
|
*/
|
|
34
|
-
export function clamp(value: number, min: number, max: number): number;
|
|
34
|
+
export function clamp(value: number | string, min: number, max: number): number;
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* Rounds a value to the nearest step offset by a minimum.
|
|
37
37
|
*
|
|
38
|
-
* @param {number
|
|
39
|
-
* @param {number}
|
|
40
|
-
* @param {number}
|
|
41
|
-
* @param {number} step A multiplier for the value.
|
|
38
|
+
* @param {number|string} value The value.
|
|
39
|
+
* @param {number} min The minimum range.
|
|
40
|
+
* @param {number} step The increment for the value.
|
|
42
41
|
*
|
|
43
|
-
* @return {number} The
|
|
42
|
+
* @return {number} The value as a valid step.
|
|
44
43
|
*/
|
|
45
|
-
export function
|
|
44
|
+
export function ensureValidStep(value: number | string, min: number, step: number): number;
|
|
46
45
|
//# sourceMappingURL=math.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../src/utils/math.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,iCAJW,OAAO,GAEN,MAAM,CAMjB;AAED;;;;;;GAMG;AACH,6BAJW,KAAK,CAAC,MAAM,GAAC,MAAM,CAAC,GAEnB,MAAM,CAQjB;AAED;;;;;;GAMG;AACH,kCAJW,KAAK,CAAC,MAAM,GAAC,MAAM,CAAC,GAEnB,MAAM,CAWjB;AAcD;;;;;;;;GAQG;AACH,6BANW,MAAM,
|
|
1
|
+
{"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../src/utils/math.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,iCAJW,OAAO,GAEN,MAAM,CAMjB;AAED;;;;;;GAMG;AACH,6BAJW,KAAK,CAAC,MAAM,GAAC,MAAM,CAAC,GAEnB,MAAM,CAQjB;AAED;;;;;;GAMG;AACH,kCAJW,KAAK,CAAC,MAAM,GAAC,MAAM,CAAC,GAEnB,MAAM,CAWjB;AAcD;;;;;;;;GAQG;AACH,6BANW,MAAM,GAAC,MAAM,OACb,MAAM,OACN,MAAM,GAEL,MAAM,CAKjB;AAED;;;;;;;;GAQG;AACH,uCANW,MAAM,GAAC,MAAM,OACb,MAAM,QACN,MAAM,GAEL,MAAM,CAajB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/components",
|
|
3
|
-
"version": "29.
|
|
3
|
+
"version": "29.8.0",
|
|
4
4
|
"description": "UI components for WordPress.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -44,23 +44,23 @@
|
|
|
44
44
|
"@types/gradient-parser": "0.1.3",
|
|
45
45
|
"@types/highlight-words-core": "1.2.1",
|
|
46
46
|
"@use-gesture/react": "^10.3.1",
|
|
47
|
-
"@wordpress/a11y": "^4.
|
|
48
|
-
"@wordpress/compose": "^7.
|
|
49
|
-
"@wordpress/date": "^5.
|
|
50
|
-
"@wordpress/deprecated": "^4.
|
|
51
|
-
"@wordpress/dom": "^4.
|
|
52
|
-
"@wordpress/element": "^6.
|
|
53
|
-
"@wordpress/escape-html": "^3.
|
|
54
|
-
"@wordpress/hooks": "^4.
|
|
55
|
-
"@wordpress/html-entities": "^4.
|
|
56
|
-
"@wordpress/i18n": "^5.
|
|
57
|
-
"@wordpress/icons": "^10.
|
|
58
|
-
"@wordpress/is-shallow-equal": "^5.
|
|
59
|
-
"@wordpress/keycodes": "^4.
|
|
60
|
-
"@wordpress/primitives": "^4.
|
|
61
|
-
"@wordpress/private-apis": "^1.
|
|
62
|
-
"@wordpress/rich-text": "^7.
|
|
63
|
-
"@wordpress/warning": "^3.
|
|
47
|
+
"@wordpress/a11y": "^4.22.0",
|
|
48
|
+
"@wordpress/compose": "^7.22.0",
|
|
49
|
+
"@wordpress/date": "^5.22.0",
|
|
50
|
+
"@wordpress/deprecated": "^4.22.0",
|
|
51
|
+
"@wordpress/dom": "^4.22.0",
|
|
52
|
+
"@wordpress/element": "^6.22.0",
|
|
53
|
+
"@wordpress/escape-html": "^3.22.0",
|
|
54
|
+
"@wordpress/hooks": "^4.22.0",
|
|
55
|
+
"@wordpress/html-entities": "^4.22.0",
|
|
56
|
+
"@wordpress/i18n": "^5.22.0",
|
|
57
|
+
"@wordpress/icons": "^10.22.0",
|
|
58
|
+
"@wordpress/is-shallow-equal": "^5.22.0",
|
|
59
|
+
"@wordpress/keycodes": "^4.22.0",
|
|
60
|
+
"@wordpress/primitives": "^4.22.0",
|
|
61
|
+
"@wordpress/private-apis": "^1.22.0",
|
|
62
|
+
"@wordpress/rich-text": "^7.22.0",
|
|
63
|
+
"@wordpress/warning": "^3.22.0",
|
|
64
64
|
"change-case": "^4.1.2",
|
|
65
65
|
"clsx": "^2.1.1",
|
|
66
66
|
"colord": "^2.7.0",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"deepmerge": "^4.3.0",
|
|
69
69
|
"fast-deep-equal": "^3.1.3",
|
|
70
70
|
"framer-motion": "^11.1.9",
|
|
71
|
-
"gradient-parser": "
|
|
71
|
+
"gradient-parser": "1.0.2",
|
|
72
72
|
"highlight-words-core": "^1.2.2",
|
|
73
73
|
"is-plain-object": "^5.0.0",
|
|
74
74
|
"memize": "^2.1.0",
|
|
@@ -85,5 +85,5 @@
|
|
|
85
85
|
"publishConfig": {
|
|
86
86
|
"access": "public"
|
|
87
87
|
},
|
|
88
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "01a314d7e46a50101e328fdb11959c441e49372d"
|
|
89
89
|
}
|
|
@@ -40,35 +40,7 @@ import type {
|
|
|
40
40
|
UseAutocompleteProps,
|
|
41
41
|
WPCompleter,
|
|
42
42
|
} from './types';
|
|
43
|
-
|
|
44
|
-
const getNodeText = ( node: React.ReactNode ): string => {
|
|
45
|
-
if ( node === null ) {
|
|
46
|
-
return '';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
switch ( typeof node ) {
|
|
50
|
-
case 'string':
|
|
51
|
-
case 'number':
|
|
52
|
-
return node.toString();
|
|
53
|
-
break;
|
|
54
|
-
case 'boolean':
|
|
55
|
-
return '';
|
|
56
|
-
break;
|
|
57
|
-
case 'object': {
|
|
58
|
-
if ( node instanceof Array ) {
|
|
59
|
-
return node.map( getNodeText ).join( '' );
|
|
60
|
-
}
|
|
61
|
-
if ( 'props' in node ) {
|
|
62
|
-
return getNodeText( node.props.children );
|
|
63
|
-
}
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
default:
|
|
67
|
-
return '';
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return '';
|
|
71
|
-
};
|
|
43
|
+
import getNodeText from '../utils/get-node-text';
|
|
72
44
|
|
|
73
45
|
const EMPTY_FILTERED_OPTIONS: KeyedOption[] = [];
|
|
74
46
|
|
|
@@ -394,12 +366,13 @@ export function useAutocomplete( {
|
|
|
394
366
|
? `components-autocomplete-item-${ instanceId }-${ selectedKey }`
|
|
395
367
|
: null;
|
|
396
368
|
const hasSelection = record.start !== undefined;
|
|
369
|
+
const showPopover = !! textContent && hasSelection && !! AutocompleterUI;
|
|
397
370
|
|
|
398
371
|
return {
|
|
399
372
|
listBoxId,
|
|
400
373
|
activeId,
|
|
401
374
|
onKeyDown: withIgnoreIMEEvents( handleKeyDown ),
|
|
402
|
-
popover:
|
|
375
|
+
popover: showPopover && (
|
|
403
376
|
<AutocompleterUI
|
|
404
377
|
className={ className }
|
|
405
378
|
filterValue={ filterValue }
|
package/src/button/style.scss
CHANGED
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
color: $components-color-accent;
|
|
168
168
|
background: transparent;
|
|
169
169
|
|
|
170
|
-
&:hover:not(:disabled, [aria-disabled="true"]) {
|
|
170
|
+
&:hover:not(:disabled, [aria-disabled="true"], .is-pressed) {
|
|
171
171
|
background: color-mix(in srgb, $components-color-accent 4%, transparent);
|
|
172
172
|
color: $components-color-accent-darker-20;
|
|
173
173
|
}
|
|
@@ -12,6 +12,8 @@ input.components-combobox-control__input[type="text"] {
|
|
|
12
12
|
margin: 0;
|
|
13
13
|
line-height: inherit;
|
|
14
14
|
min-height: auto;
|
|
15
|
+
background: $components-color-background;
|
|
16
|
+
color: $components-color-foreground;
|
|
15
17
|
|
|
16
18
|
// Resolves Zooming on iOS devices
|
|
17
19
|
// https://github.com/WordPress/gutenberg/issues/27405
|
|
@@ -26,7 +28,7 @@ input.components-combobox-control__input[type="text"] {
|
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
.components-combobox-control__suggestions-container {
|
|
29
|
-
@include input-control;
|
|
31
|
+
@include input-control($components-color-accent);
|
|
30
32
|
display: flex;
|
|
31
33
|
flex-wrap: wrap;
|
|
32
34
|
align-items: flex-start;
|
|
@@ -34,7 +36,7 @@ input.components-combobox-control__input[type="text"] {
|
|
|
34
36
|
padding: 0;
|
|
35
37
|
|
|
36
38
|
&:focus-within {
|
|
37
|
-
@include input-style__focus();
|
|
39
|
+
@include input-style__focus($components-color-accent);
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
.components-spinner {
|
|
@@ -213,6 +213,7 @@ export const SelectedItemCheck = styled( Ariakit.SelectItemCheck )`
|
|
|
213
213
|
display: flex;
|
|
214
214
|
align-items: center;
|
|
215
215
|
margin-inline-start: ${ space( 2 ) };
|
|
216
|
+
fill: currentColor;
|
|
216
217
|
|
|
217
218
|
// Keep the checkmark vertically aligned at the top. Since the item text has a
|
|
218
219
|
// 28px line height and the checkmark is 24px tall, a (28-24)/2 = 2px margin
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
.components-form-token-field__input-container {
|
|
2
|
-
@include input-control();
|
|
2
|
+
@include input-control($components-color-accent);
|
|
3
3
|
width: 100%;
|
|
4
4
|
padding: 0;
|
|
5
5
|
cursor: text;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
&.is-active {
|
|
13
|
-
@include input-style__focus();
|
|
13
|
+
@include input-style__focus($components-color-accent);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
// Token input
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
min-width: 50px;
|
|
28
28
|
background: inherit;
|
|
29
29
|
border: 0;
|
|
30
|
-
color: $
|
|
30
|
+
color: $components-color-foreground;
|
|
31
31
|
box-shadow: none;
|
|
32
32
|
|
|
33
33
|
// Resolves Zooming on iOS devices
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
.components-form-token-field__suggestion {
|
|
171
|
-
color: $
|
|
171
|
+
color: $components-color-foreground;
|
|
172
172
|
display: block;
|
|
173
173
|
font-size: $default-font-size;
|
|
174
174
|
padding: $grid-unit-10 $grid-unit-15;
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
|
|
179
179
|
&.is-selected {
|
|
180
180
|
background: $components-color-accent;
|
|
181
|
-
color: $
|
|
181
|
+
color: $components-color-foreground-inverted;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
&[aria-disabled="true"] {
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
color: $gray-600;
|
|
187
187
|
|
|
188
188
|
&.is-selected {
|
|
189
|
-
background
|
|
189
|
+
background: color-mix(in srgb, $components-color-accent 4%, transparent);
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
|
|
@@ -18,7 +18,7 @@ import deprecated from '@wordpress/deprecated';
|
|
|
18
18
|
*/
|
|
19
19
|
import { Input, SpinButton, styles } from './styles/number-control-styles';
|
|
20
20
|
import * as inputControlActionTypes from '../input-control/reducer/actions';
|
|
21
|
-
import { add, subtract,
|
|
21
|
+
import { add, subtract, clamp, ensureValidStep } from '../utils/math';
|
|
22
22
|
import { ensureNumber, isValueEmpty } from '../utils/values';
|
|
23
23
|
import type { WordPressComponentProps } from '../context/wordpress-component';
|
|
24
24
|
import type { NumberControlProps } from './types';
|
|
@@ -78,17 +78,18 @@ function UnforwardedNumberControl(
|
|
|
78
78
|
const isStepAny = step === 'any';
|
|
79
79
|
const baseStep = isStepAny ? 1 : ensureNumber( step );
|
|
80
80
|
const baseSpin = ensureNumber( spinFactor ) * baseStep;
|
|
81
|
-
const baseValue = roundClamp( 0, min, max, baseStep );
|
|
82
81
|
const constrainValue = (
|
|
83
82
|
value: number | string,
|
|
84
83
|
stepOverride?: number
|
|
85
84
|
) => {
|
|
86
|
-
// When step is "any"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
// When step is not "any" the value must be a valid step.
|
|
86
|
+
if ( ! isStepAny ) {
|
|
87
|
+
value = ensureValidStep( value, min, stepOverride ?? baseStep );
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return `${ clamp( value, min, max ) }`;
|
|
91
91
|
};
|
|
92
|
+
const baseValue = constrainValue( 0 );
|
|
92
93
|
|
|
93
94
|
const autoComplete = typeProp === 'number' ? 'off' : undefined;
|
|
94
95
|
const classes = clsx( 'components-number-control', className );
|
|
@@ -40,8 +40,21 @@ describe( 'NumberControl', () => {
|
|
|
40
40
|
} );
|
|
41
41
|
|
|
42
42
|
it( 'should render custom className', () => {
|
|
43
|
-
render( <NumberControl
|
|
44
|
-
|
|
43
|
+
const { container: withoutClassName } = render( <NumberControl /> );
|
|
44
|
+
|
|
45
|
+
const { container: withClassName } = render(
|
|
46
|
+
<NumberControl className="hello" />
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
expect(
|
|
50
|
+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
|
51
|
+
withoutClassName.querySelector( '.components-number-control' )
|
|
52
|
+
).not.toHaveClass( 'hello' );
|
|
53
|
+
|
|
54
|
+
expect(
|
|
55
|
+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
|
56
|
+
withClassName.querySelector( '.components-number-control' )
|
|
57
|
+
).toHaveClass( 'hello' );
|
|
45
58
|
} );
|
|
46
59
|
} );
|
|
47
60
|
|
package/src/popover/index.tsx
CHANGED
|
@@ -59,6 +59,7 @@ import type {
|
|
|
59
59
|
PopoverProps,
|
|
60
60
|
PopoverAnchorRefReference,
|
|
61
61
|
PopoverAnchorRefTopBottom,
|
|
62
|
+
PopoverSlotProps,
|
|
62
63
|
} from './types';
|
|
63
64
|
import { overlayMiddlewares } from './overlay-middlewares';
|
|
64
65
|
import { StyleProvider } from '../style-provider';
|
|
@@ -478,6 +479,20 @@ const UnforwardedPopover = (
|
|
|
478
479
|
);
|
|
479
480
|
};
|
|
480
481
|
|
|
482
|
+
// Export the PopoverSlot individually to allow typescript to pick the types up.
|
|
483
|
+
export const PopoverSlot = forwardRef< HTMLDivElement, PopoverSlotProps >(
|
|
484
|
+
( { name = SLOT_NAME }, ref ) => {
|
|
485
|
+
return (
|
|
486
|
+
<Slot
|
|
487
|
+
bubblesVirtually
|
|
488
|
+
name={ name }
|
|
489
|
+
className="popover-slot"
|
|
490
|
+
ref={ ref }
|
|
491
|
+
/>
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
);
|
|
495
|
+
|
|
481
496
|
/**
|
|
482
497
|
* `Popover` renders its content in a floating modal. If no explicit anchor is passed via props, it anchors to its parent element by default.
|
|
483
498
|
*
|
|
@@ -501,25 +516,24 @@ const UnforwardedPopover = (
|
|
|
501
516
|
* ```
|
|
502
517
|
*
|
|
503
518
|
*/
|
|
504
|
-
export const Popover =
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
Popover.__unstableSlotNameProvider = slotNameContext.Provider;
|
|
519
|
+
export const Popover = Object.assign(
|
|
520
|
+
contextConnect( UnforwardedPopover, 'Popover' ),
|
|
521
|
+
{
|
|
522
|
+
/**
|
|
523
|
+
* Renders a slot that is used internally by Popover for rendering content.
|
|
524
|
+
*/
|
|
525
|
+
Slot: Object.assign( PopoverSlot, {
|
|
526
|
+
displayName: 'Popover.Slot',
|
|
527
|
+
} ),
|
|
528
|
+
/**
|
|
529
|
+
* Provides a context to manage popover slot names.
|
|
530
|
+
*
|
|
531
|
+
* This is marked as unstable and should not be used directly.
|
|
532
|
+
*/
|
|
533
|
+
__unstableSlotNameProvider: Object.assign( slotNameContext.Provider, {
|
|
534
|
+
displayName: 'Popover.__unstableSlotNameProvider',
|
|
535
|
+
} ),
|
|
536
|
+
}
|
|
537
|
+
);
|
|
524
538
|
|
|
525
539
|
export default Popover;
|
|
@@ -36,6 +36,10 @@ const meta: Meta< typeof Popover > = {
|
|
|
36
36
|
title: 'Components/Overlays/Popover',
|
|
37
37
|
id: 'components-popover',
|
|
38
38
|
component: Popover,
|
|
39
|
+
subcomponents: {
|
|
40
|
+
// @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170
|
|
41
|
+
'Popover.Slot': Popover.Slot,
|
|
42
|
+
},
|
|
39
43
|
argTypes: {
|
|
40
44
|
anchor: { control: false },
|
|
41
45
|
anchorRef: { control: false },
|
|
@@ -86,10 +90,13 @@ export const Default: StoryObj< typeof Popover > = {
|
|
|
86
90
|
decorators: [
|
|
87
91
|
( Story ) => {
|
|
88
92
|
const [ isVisible, setIsVisible ] = useState( false );
|
|
89
|
-
const
|
|
93
|
+
const buttonRef = useRef< HTMLButtonElement | undefined >();
|
|
94
|
+
const toggleVisible = ( event: React.MouseEvent ) => {
|
|
95
|
+
if ( buttonRef.current && event.target !== buttonRef.current ) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
90
98
|
setIsVisible( ( state ) => ! state );
|
|
91
99
|
};
|
|
92
|
-
const buttonRef = useRef< HTMLButtonElement | undefined >();
|
|
93
100
|
useEffect( () => {
|
|
94
101
|
buttonRef.current?.scrollIntoView?.( {
|
|
95
102
|
block: 'center',
|
|
@@ -255,3 +262,77 @@ export const WithSlotOutsideIframe: StoryObj< typeof Popover > = {
|
|
|
255
262
|
...Default.args,
|
|
256
263
|
},
|
|
257
264
|
};
|
|
265
|
+
|
|
266
|
+
export const WithCloseHandlers: StoryObj< typeof Popover > = {
|
|
267
|
+
render: function WithCloseHandlersStory( args ) {
|
|
268
|
+
const [ isVisible, setIsVisible ] = useState( false );
|
|
269
|
+
const buttonRef = useRef< HTMLButtonElement >( null );
|
|
270
|
+
|
|
271
|
+
const toggleVisible = ( event: React.MouseEvent ) => {
|
|
272
|
+
if ( buttonRef.current && event.target !== buttonRef.current ) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
setIsVisible( ( prev ) => ! prev );
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const handleClose = () => {
|
|
279
|
+
args.onClose?.();
|
|
280
|
+
setIsVisible( false );
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const handleFocusOutside = ( e: React.SyntheticEvent ) => {
|
|
284
|
+
args.onFocusOutside?.( e );
|
|
285
|
+
setIsVisible( false );
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
useEffect( () => {
|
|
289
|
+
buttonRef.current?.scrollIntoView( {
|
|
290
|
+
block: 'center',
|
|
291
|
+
inline: 'center',
|
|
292
|
+
} );
|
|
293
|
+
}, [] );
|
|
294
|
+
|
|
295
|
+
return (
|
|
296
|
+
<div
|
|
297
|
+
style={ {
|
|
298
|
+
width: '300vw',
|
|
299
|
+
height: '300vh',
|
|
300
|
+
display: 'flex',
|
|
301
|
+
alignItems: 'center',
|
|
302
|
+
justifyContent: 'center',
|
|
303
|
+
} }
|
|
304
|
+
>
|
|
305
|
+
<Button
|
|
306
|
+
variant="secondary"
|
|
307
|
+
onClick={ toggleVisible }
|
|
308
|
+
ref={ buttonRef }
|
|
309
|
+
>
|
|
310
|
+
Toggle Popover
|
|
311
|
+
{ isVisible && (
|
|
312
|
+
<Popover
|
|
313
|
+
{ ...args }
|
|
314
|
+
onClose={ handleClose }
|
|
315
|
+
onFocusOutside={ handleFocusOutside }
|
|
316
|
+
>
|
|
317
|
+
{ args.children }
|
|
318
|
+
</Popover>
|
|
319
|
+
) }
|
|
320
|
+
</Button>
|
|
321
|
+
</div>
|
|
322
|
+
);
|
|
323
|
+
},
|
|
324
|
+
args: {
|
|
325
|
+
...Default.args,
|
|
326
|
+
focusOnMount: true,
|
|
327
|
+
children: (
|
|
328
|
+
<div style={ { width: '280px', whiteSpace: 'normal' } }>
|
|
329
|
+
<p>
|
|
330
|
+
Clicking outside triggers the onFocusOutside callback prop.
|
|
331
|
+
</p>
|
|
332
|
+
<p>
|
|
333
|
+
Pressing the Escape key triggers the onClose callback prop.
|
|
334
|
+
</p>
|
|
335
|
+
</div>
|
|
336
|
+
),
|
|
337
|
+
},
|
|
338
|
+
};
|
package/src/popover/types.ts
CHANGED
|
@@ -206,3 +206,13 @@ export type PopoverProps = {
|
|
|
206
206
|
*/
|
|
207
207
|
isAlternate?: boolean;
|
|
208
208
|
};
|
|
209
|
+
|
|
210
|
+
export type PopoverSlotProps = {
|
|
211
|
+
/**
|
|
212
|
+
* The name of the Slot in which the popover should be rendered. It should
|
|
213
|
+
* be also passed to the corresponding `PopoverSlot` component.
|
|
214
|
+
*
|
|
215
|
+
* @default 'Popover'
|
|
216
|
+
*/
|
|
217
|
+
name?: string;
|
|
218
|
+
};
|
|
@@ -391,17 +391,18 @@ function UnforwardedRangeControl(
|
|
|
391
391
|
* import { useState } from '@wordpress/element';
|
|
392
392
|
*
|
|
393
393
|
* const MyRangeControl = () => {
|
|
394
|
-
* const [
|
|
394
|
+
* const [ value, setValue ] = useState();
|
|
395
395
|
* return (
|
|
396
396
|
* <RangeControl
|
|
397
397
|
* __nextHasNoMarginBottom
|
|
398
398
|
* __next40pxDefaultSize
|
|
399
399
|
* help="Please select how transparent you would like this."
|
|
400
|
-
* initialPosition={50}
|
|
400
|
+
* initialPosition={ 50 }
|
|
401
401
|
* label="Opacity"
|
|
402
|
-
* max={100}
|
|
403
|
-
* min={0}
|
|
404
|
-
*
|
|
402
|
+
* max={ 100 }
|
|
403
|
+
* min={ 0 }
|
|
404
|
+
* value={ value }
|
|
405
|
+
* onChange={ setValue }
|
|
405
406
|
* />
|
|
406
407
|
* );
|
|
407
408
|
* };
|
|
@@ -16,7 +16,7 @@ import ToolbarContext from '../toolbar-context';
|
|
|
16
16
|
import DropdownMenu from '../../dropdown-menu';
|
|
17
17
|
import type { DropdownMenuProps } from '../../dropdown-menu/types';
|
|
18
18
|
|
|
19
|
-
function
|
|
19
|
+
function UnforwardedToolbarDropdownMenu(
|
|
20
20
|
props: DropdownMenuProps,
|
|
21
21
|
ref: ForwardedRef< any >
|
|
22
22
|
) {
|
|
@@ -44,4 +44,5 @@ function ToolbarDropdownMenu(
|
|
|
44
44
|
);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
export
|
|
47
|
+
export const ToolbarDropdownMenu = forwardRef( UnforwardedToolbarDropdownMenu );
|
|
48
|
+
export default ToolbarDropdownMenu;
|
|
@@ -16,7 +16,7 @@ import warning from '@wordpress/warning';
|
|
|
16
16
|
import ToolbarContext from '../toolbar-context';
|
|
17
17
|
import type { ToolbarItemProps } from './types';
|
|
18
18
|
|
|
19
|
-
function
|
|
19
|
+
function UnforwardedToolbarItem(
|
|
20
20
|
{ children, as: Component, ...props }: ToolbarItemProps,
|
|
21
21
|
ref: ForwardedRef< any >
|
|
22
22
|
) {
|
|
@@ -57,4 +57,5 @@ function ToolbarItem(
|
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export
|
|
60
|
+
export const ToolbarItem = forwardRef( UnforwardedToolbarItem );
|
|
61
|
+
export default ToolbarItem;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const getNodeText = ( node: React.ReactNode ): string => {
|
|
2
|
+
if ( node === null ) {
|
|
3
|
+
return '';
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
switch ( typeof node ) {
|
|
7
|
+
case 'string':
|
|
8
|
+
case 'number':
|
|
9
|
+
return node.toString();
|
|
10
|
+
case 'object': {
|
|
11
|
+
if ( node instanceof Array ) {
|
|
12
|
+
return node.map( getNodeText ).join( '' );
|
|
13
|
+
}
|
|
14
|
+
if ( 'props' in node ) {
|
|
15
|
+
return getNodeText( node.props.children );
|
|
16
|
+
}
|
|
17
|
+
return '';
|
|
18
|
+
}
|
|
19
|
+
default:
|
|
20
|
+
return '';
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default getNodeText;
|