@wordpress/components 19.9.0 → 19.10.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 +30 -0
- package/CONTRIBUTING.md +80 -7
- package/build/angle-picker-control/angle-circle.js +5 -7
- package/build/angle-picker-control/angle-circle.js.map +1 -1
- package/build/box-control/index.js +0 -21
- package/build/box-control/index.js.map +1 -1
- package/build/box-control/utils.js +1 -8
- package/build/box-control/utils.js.map +1 -1
- package/build/button/index.js +3 -5
- package/build/button/index.js.map +1 -1
- package/build/circular-option-picker/index.js +1 -2
- package/build/circular-option-picker/index.js.map +1 -1
- package/build/disabled/index.js +4 -76
- package/build/disabled/index.js.map +1 -1
- package/build/input-control/index.js +3 -2
- package/build/input-control/index.js.map +1 -1
- package/build/input-control/styles/input-control-styles.js +42 -30
- package/build/input-control/styles/input-control-styles.js.map +1 -1
- package/build/mobile/bottom-sheet-select-control/index.native.js +1 -0
- package/build/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
- package/build/popover/index.js +6 -52
- package/build/popover/index.js.map +1 -1
- package/build/select-control/index.js +31 -4
- package/build/select-control/index.js.map +1 -1
- package/build/select-control/styles/select-control-styles.js +8 -8
- package/build/select-control/styles/select-control-styles.js.map +1 -1
- package/build/text-control/index.js +35 -28
- package/build/text-control/index.js.map +1 -1
- package/build/text-control/types.js +6 -0
- package/build/text-control/types.js.map +1 -0
- package/build/toggle-group-control/toggle-group-control-option-icon/component.js +6 -4
- package/build/toggle-group-control/toggle-group-control-option-icon/component.js.map +1 -1
- package/build/tools-panel/tools-panel-header/component.js +52 -36
- package/build/tools-panel/tools-panel-header/component.js.map +1 -1
- package/build/unit-control/index.js +3 -3
- package/build/unit-control/index.js.map +1 -1
- package/build/unit-control/styles/unit-control-styles.js +11 -20
- package/build/unit-control/styles/unit-control-styles.js.map +1 -1
- package/build/unit-control/utils.js.map +1 -1
- package/build-module/angle-picker-control/angle-circle.js +5 -7
- package/build-module/angle-picker-control/angle-circle.js.map +1 -1
- package/build-module/box-control/index.js +1 -20
- package/build-module/box-control/index.js.map +1 -1
- package/build-module/box-control/utils.js +0 -6
- package/build-module/box-control/utils.js.map +1 -1
- package/build-module/button/index.js +3 -4
- package/build-module/button/index.js.map +1 -1
- package/build-module/circular-option-picker/index.js +1 -2
- package/build-module/circular-option-picker/index.js.map +1 -1
- package/build-module/disabled/index.js +5 -76
- package/build-module/disabled/index.js.map +1 -1
- package/build-module/input-control/index.js +3 -2
- package/build-module/input-control/index.js.map +1 -1
- package/build-module/input-control/styles/input-control-styles.js +42 -30
- package/build-module/input-control/styles/input-control-styles.js.map +1 -1
- package/build-module/mobile/bottom-sheet-select-control/index.native.js +1 -0
- package/build-module/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
- package/build-module/popover/index.js +6 -52
- package/build-module/popover/index.js.map +1 -1
- package/build-module/select-control/index.js +29 -3
- package/build-module/select-control/index.js.map +1 -1
- package/build-module/select-control/styles/select-control-styles.js +8 -8
- package/build-module/select-control/styles/select-control-styles.js.map +1 -1
- package/build-module/text-control/index.js +35 -27
- package/build-module/text-control/index.js.map +1 -1
- package/build-module/text-control/types.js +2 -0
- package/build-module/text-control/types.js.map +1 -0
- package/build-module/toggle-group-control/toggle-group-control-option-icon/component.js +1 -5
- package/build-module/toggle-group-control/toggle-group-control-option-icon/component.js.map +1 -1
- package/build-module/tools-panel/tools-panel-header/component.js +51 -36
- package/build-module/tools-panel/tools-panel-header/component.js.map +1 -1
- package/build-module/unit-control/index.js +3 -3
- package/build-module/unit-control/index.js.map +1 -1
- package/build-module/unit-control/styles/unit-control-styles.js +11 -20
- package/build-module/unit-control/styles/unit-control-styles.js.map +1 -1
- package/build-module/unit-control/utils.js.map +1 -1
- package/build-style/style-rtl.css +7 -0
- package/build-style/style.css +7 -0
- package/build-types/button/index.d.ts.map +1 -1
- package/build-types/circular-option-picker/index.d.ts.map +1 -1
- package/build-types/color-picker/styles.d.ts +3 -3
- package/build-types/disabled/index.d.ts.map +1 -1
- package/build-types/input-control/index.d.ts +4 -3
- package/build-types/input-control/index.d.ts.map +1 -1
- package/build-types/input-control/stories/index.d.ts +5 -5
- package/build-types/input-control/stories/index.d.ts.map +1 -1
- package/build-types/input-control/styles/input-control-styles.d.ts +1 -0
- package/build-types/input-control/styles/input-control-styles.d.ts.map +1 -1
- package/build-types/input-control/types.d.ts +6 -0
- package/build-types/input-control/types.d.ts.map +1 -1
- package/build-types/number-control/styles/number-control-styles.d.ts +1 -1
- package/build-types/popover/index.d.ts +0 -1
- package/build-types/popover/index.d.ts.map +1 -1
- package/build-types/select-control/index.d.ts +30 -26
- package/build-types/select-control/index.d.ts.map +1 -1
- package/build-types/select-control/stories/index.d.ts +23 -0
- package/build-types/select-control/stories/index.d.ts.map +1 -0
- package/build-types/select-control/styles/select-control-styles.d.ts +3 -4
- package/build-types/select-control/styles/select-control-styles.d.ts.map +1 -1
- package/build-types/select-control/test/select-control.d.ts +2 -0
- package/build-types/select-control/test/select-control.d.ts.map +1 -0
- package/build-types/select-control/types.d.ts +52 -1
- package/build-types/select-control/types.d.ts.map +1 -1
- package/build-types/text-control/index.d.ts +32 -0
- package/build-types/text-control/index.d.ts.map +1 -0
- package/build-types/text-control/stories/index.d.ts +13 -0
- package/build-types/text-control/stories/index.d.ts.map +1 -0
- package/build-types/text-control/types.d.ts +25 -0
- package/build-types/text-control/types.d.ts.map +1 -0
- package/build-types/toggle-group-control/toggle-group-control-option-icon/component.d.ts.map +1 -1
- package/build-types/tools-panel/tools-panel-header/component.d.ts.map +1 -1
- package/build-types/tools-panel/types.d.ts +0 -1
- package/build-types/tools-panel/types.d.ts.map +1 -1
- package/build-types/unit-control/index.d.ts +2 -2
- package/build-types/unit-control/index.d.ts.map +1 -1
- package/build-types/unit-control/styles/unit-control-styles.d.ts.map +1 -1
- package/build-types/unit-control/test/index.d.ts +2 -0
- package/build-types/unit-control/test/index.d.ts.map +1 -0
- package/build-types/unit-control/test/utils.d.ts +2 -0
- package/build-types/unit-control/test/utils.d.ts.map +1 -0
- package/build-types/unit-control/types.d.ts +1 -1
- package/build-types/unit-control/types.d.ts.map +1 -1
- package/build-types/unit-control/utils.d.ts +3 -3
- package/build-types/unit-control/utils.d.ts.map +1 -1
- package/package.json +17 -17
- package/src/angle-picker-control/angle-circle.js +3 -3
- package/src/box-control/README.md +0 -74
- package/src/box-control/index.js +0 -15
- package/src/box-control/stories/index.js +0 -29
- package/src/box-control/utils.js +0 -7
- package/src/button/index.js +2 -4
- package/src/button/test/index.js +16 -1
- package/src/circular-option-picker/index.js +1 -2
- package/src/color-palette/README.md +0 -1
- package/src/color-palette/test/__snapshots__/index.js.snap +2 -3
- package/src/confirm-dialog/stories/index.js +87 -99
- package/src/date-time/stories/index.js +19 -0
- package/src/date-time/test/date.js +107 -78
- package/src/dimension-control/test/__snapshots__/index.test.js.snap +4 -4
- package/src/disabled/index.js +5 -90
- package/src/form-file-upload/test/index.js +15 -12
- package/src/input-control/README.md +1 -1
- package/src/input-control/index.tsx +3 -2
- package/src/input-control/stories/index.tsx +1 -1
- package/src/input-control/styles/input-control-styles.tsx +19 -5
- package/src/input-control/types.ts +6 -0
- package/src/menu-item/style.scss +10 -0
- package/src/mobile/bottom-sheet/bottom-sheet-navigation/test/navigation-container.native.js +8 -1
- package/src/mobile/bottom-sheet-select-control/index.native.js +1 -0
- package/src/mobile/html-text-input/style.android.scss +1 -0
- package/src/mobile/html-text-input/style.ios.scss +1 -0
- package/src/mobile/link-settings/test/link-settings-navigation.native.js +9 -1
- package/src/popover/index.js +5 -51
- package/src/select-control/README.md +2 -2
- package/src/select-control/index.tsx +30 -29
- package/src/select-control/stories/index.tsx +90 -0
- package/src/select-control/styles/select-control-styles.ts +9 -8
- package/src/select-control/test/{select-control.js → select-control.tsx} +2 -2
- package/src/select-control/types.ts +66 -1
- package/src/text-control/index.tsx +84 -0
- package/src/text-control/stories/index.tsx +66 -0
- package/src/text-control/types.ts +29 -0
- package/src/toggle-group-control/toggle-group-control-option-icon/component.tsx +1 -5
- package/src/tools-panel/test/__snapshots__/index.js.snap +1 -1
- package/src/tools-panel/test/index.js +71 -18
- package/src/tools-panel/tools-panel-header/component.tsx +75 -33
- package/src/tools-panel/types.ts +0 -1
- package/src/tooltip/test/index.js +6 -0
- package/src/unit-control/index.tsx +2 -5
- package/src/unit-control/styles/unit-control-styles.ts +3 -13
- package/src/unit-control/test/__snapshots__/index.tsx.snap +33 -0
- package/src/unit-control/test/{index.js → index.tsx} +214 -165
- package/src/unit-control/test/{utils.js → utils.ts} +38 -19
- package/src/unit-control/types.ts +4 -1
- package/src/unit-control/utils.ts +5 -3
- package/tsconfig.json +2 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/build/box-control/visualizer.js +0 -165
- package/build/box-control/visualizer.js.map +0 -1
- package/build-module/box-control/visualizer.js +0 -154
- package/build-module/box-control/visualizer.js.map +0 -1
- package/src/box-control/visualizer.js +0 -116
- package/src/select-control/stories/index.js +0 -104
- package/src/text-control/index.js +0 -72
- package/src/text-control/stories/index.js +0 -46
package/src/disabled/index.js
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { includes, debounce } from 'lodash';
|
|
5
4
|
import classnames from 'classnames';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* WordPress dependencies
|
|
9
8
|
*/
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
useCallback,
|
|
13
|
-
useLayoutEffect,
|
|
14
|
-
useRef,
|
|
15
|
-
} from '@wordpress/element';
|
|
16
|
-
import { focus } from '@wordpress/dom';
|
|
9
|
+
import { __experimentalUseDisabled as useDisabled } from '@wordpress/compose';
|
|
10
|
+
import { createContext } from '@wordpress/element';
|
|
17
11
|
|
|
18
12
|
/**
|
|
19
13
|
* Internal dependencies
|
|
@@ -23,25 +17,6 @@ import { StyledWrapper } from './styles/disabled-styles';
|
|
|
23
17
|
const Context = createContext( false );
|
|
24
18
|
const { Consumer, Provider } = Context;
|
|
25
19
|
|
|
26
|
-
/**
|
|
27
|
-
* Names of control nodes which qualify for disabled behavior.
|
|
28
|
-
*
|
|
29
|
-
* See WHATWG HTML Standard: 4.10.18.5: "Enabling and disabling form controls: the disabled attribute".
|
|
30
|
-
*
|
|
31
|
-
* @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute
|
|
32
|
-
*
|
|
33
|
-
* @type {string[]}
|
|
34
|
-
*/
|
|
35
|
-
const DISABLED_ELIGIBLE_NODE_NAMES = [
|
|
36
|
-
'BUTTON',
|
|
37
|
-
'FIELDSET',
|
|
38
|
-
'INPUT',
|
|
39
|
-
'OPTGROUP',
|
|
40
|
-
'OPTION',
|
|
41
|
-
'SELECT',
|
|
42
|
-
'TEXTAREA',
|
|
43
|
-
];
|
|
44
|
-
|
|
45
20
|
/**
|
|
46
21
|
* @typedef OwnProps
|
|
47
22
|
* @property {string} [className] Classname for the disabled element.
|
|
@@ -54,68 +29,8 @@ const DISABLED_ELIGIBLE_NODE_NAMES = [
|
|
|
54
29
|
* @return {JSX.Element} Element wrapping the children to disable them when isDisabled is true.
|
|
55
30
|
*/
|
|
56
31
|
function Disabled( { className, children, isDisabled = true, ...props } ) {
|
|
57
|
-
/** @type {import('react').
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
const disable = () => {
|
|
61
|
-
if ( ! node.current ) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
focus.focusable.find( node.current ).forEach( ( focusable ) => {
|
|
66
|
-
if (
|
|
67
|
-
includes( DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName )
|
|
68
|
-
) {
|
|
69
|
-
focusable.setAttribute( 'disabled', '' );
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if ( focusable.nodeName === 'A' ) {
|
|
73
|
-
focusable.setAttribute( 'tabindex', '-1' );
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const tabIndex = focusable.getAttribute( 'tabindex' );
|
|
77
|
-
if ( tabIndex !== null && tabIndex !== '-1' ) {
|
|
78
|
-
focusable.removeAttribute( 'tabindex' );
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if ( focusable.hasAttribute( 'contenteditable' ) ) {
|
|
82
|
-
focusable.setAttribute( 'contenteditable', 'false' );
|
|
83
|
-
}
|
|
84
|
-
} );
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// Debounce re-disable since disabling process itself will incur
|
|
88
|
-
// additional mutations which should be ignored.
|
|
89
|
-
const debouncedDisable = useCallback(
|
|
90
|
-
debounce( disable, undefined, { leading: true } ),
|
|
91
|
-
[]
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
useLayoutEffect( () => {
|
|
95
|
-
if ( ! isDisabled ) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
disable();
|
|
100
|
-
|
|
101
|
-
/** @type {MutationObserver | undefined} */
|
|
102
|
-
let observer;
|
|
103
|
-
if ( node.current ) {
|
|
104
|
-
observer = new window.MutationObserver( debouncedDisable );
|
|
105
|
-
observer.observe( node.current, {
|
|
106
|
-
childList: true,
|
|
107
|
-
attributes: true,
|
|
108
|
-
subtree: true,
|
|
109
|
-
} );
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return () => {
|
|
113
|
-
if ( observer ) {
|
|
114
|
-
observer.disconnect();
|
|
115
|
-
}
|
|
116
|
-
debouncedDisable.cancel();
|
|
117
|
-
};
|
|
118
|
-
}, [] );
|
|
32
|
+
/** @type {import('react').RefCallback<HTMLDivElement>} */
|
|
33
|
+
const ref = useDisabled();
|
|
119
34
|
|
|
120
35
|
if ( ! isDisabled ) {
|
|
121
36
|
return <Provider value={ false }>{ children }</Provider>;
|
|
@@ -124,7 +39,7 @@ function Disabled( { className, children, isDisabled = true, ...props } ) {
|
|
|
124
39
|
return (
|
|
125
40
|
<Provider value={ true }>
|
|
126
41
|
<StyledWrapper
|
|
127
|
-
ref={
|
|
42
|
+
ref={ ref }
|
|
128
43
|
className={ classnames( className, 'components-disabled' ) }
|
|
129
44
|
{ ...props }
|
|
130
45
|
>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { render
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
5
|
import userEvent from '@testing-library/user-event';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -14,15 +14,9 @@ import FormFileUpload from '../';
|
|
|
14
14
|
*/
|
|
15
15
|
const { File } = window;
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// Avoids timeout errors (https://github.com/testing-library/user-event/issues/565#issuecomment-1064579531).
|
|
21
|
-
delay: null,
|
|
22
|
-
} ),
|
|
23
|
-
...RTLrender( jsx ),
|
|
24
|
-
};
|
|
25
|
-
}
|
|
17
|
+
const user = userEvent.setup( {
|
|
18
|
+
advanceTimers: jest.advanceTimersByTime,
|
|
19
|
+
} );
|
|
26
20
|
|
|
27
21
|
// @testing-library/user-event considers changing <input type="file"> to a string as a change, but it do not occur on real browsers, so the comparisons will be against this result
|
|
28
22
|
const fakePath = expect.objectContaining( {
|
|
@@ -32,6 +26,15 @@ const fakePath = expect.objectContaining( {
|
|
|
32
26
|
} );
|
|
33
27
|
|
|
34
28
|
describe( 'FormFileUpload', () => {
|
|
29
|
+
beforeEach( () => {
|
|
30
|
+
jest.useFakeTimers();
|
|
31
|
+
} );
|
|
32
|
+
|
|
33
|
+
afterEach( () => {
|
|
34
|
+
jest.runOnlyPendingTimers();
|
|
35
|
+
jest.useRealTimers();
|
|
36
|
+
} );
|
|
37
|
+
|
|
35
38
|
it( 'should show an Icon Button and a hidden input', () => {
|
|
36
39
|
render( <FormFileUpload>My Upload Button</FormFileUpload> );
|
|
37
40
|
|
|
@@ -44,7 +47,7 @@ describe( 'FormFileUpload', () => {
|
|
|
44
47
|
it( 'should not fire a change event after selecting the same file', async () => {
|
|
45
48
|
const onChange = jest.fn();
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
render(
|
|
48
51
|
<FormFileUpload onChange={ onChange }>
|
|
49
52
|
My Upload Button
|
|
50
53
|
</FormFileUpload>
|
|
@@ -67,7 +70,7 @@ describe( 'FormFileUpload', () => {
|
|
|
67
70
|
it( 'should fire a change event after selecting the same file if the value was reset in between', async () => {
|
|
68
71
|
const onChange = jest.fn();
|
|
69
72
|
|
|
70
|
-
|
|
73
|
+
render(
|
|
71
74
|
<FormFileUpload
|
|
72
75
|
onClick={ jest.fn( ( e ) => ( e.target.value = '' ) ) }
|
|
73
76
|
onChange={ onChange }
|
|
@@ -92,7 +92,7 @@ export function UnforwardedInputControl(
|
|
|
92
92
|
* InputControl components let users enter and edit text. This is an experimental component
|
|
93
93
|
* intended to (in time) merge with or replace `TextControl`.
|
|
94
94
|
*
|
|
95
|
-
*
|
|
95
|
+
* ```jsx
|
|
96
96
|
* import { __experimentalInputControl as InputControl } from '@wordpress/components';
|
|
97
97
|
* import { useState } from '@wordpress/compose';
|
|
98
98
|
*
|
|
@@ -102,10 +102,11 @@ export function UnforwardedInputControl(
|
|
|
102
102
|
* return (
|
|
103
103
|
* <InputControl
|
|
104
104
|
* value={ value }
|
|
105
|
-
* onChange={ ( nextValue ) => setValue( nextValue ) }
|
|
105
|
+
* onChange={ ( nextValue ) => setValue( nextValue ?? '' ) }
|
|
106
106
|
* />
|
|
107
107
|
* );
|
|
108
108
|
* };
|
|
109
|
+
* ```
|
|
109
110
|
*/
|
|
110
111
|
export const InputControl = forwardRef( UnforwardedInputControl );
|
|
111
112
|
|
|
@@ -18,6 +18,7 @@ const meta: ComponentMeta< typeof InputControl > = {
|
|
|
18
18
|
prefix: { control: { type: null } },
|
|
19
19
|
suffix: { control: { type: null } },
|
|
20
20
|
type: { control: { type: 'text' } },
|
|
21
|
+
value: { control: { disable: true } },
|
|
21
22
|
},
|
|
22
23
|
parameters: {
|
|
23
24
|
controls: { expanded: true },
|
|
@@ -34,7 +35,6 @@ export const Default = Template.bind( {} );
|
|
|
34
35
|
Default.args = {
|
|
35
36
|
label: 'Value',
|
|
36
37
|
placeholder: 'Placeholder',
|
|
37
|
-
value: '',
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
export const WithPrefix = Template.bind( {} );
|
|
@@ -105,6 +105,7 @@ export const Container = styled.div< ContainerProps >`
|
|
|
105
105
|
`;
|
|
106
106
|
|
|
107
107
|
type InputProps = {
|
|
108
|
+
__next36pxDefaultSize?: boolean;
|
|
108
109
|
disabled?: boolean;
|
|
109
110
|
inputSize?: Size;
|
|
110
111
|
isDragging?: boolean;
|
|
@@ -140,14 +141,17 @@ const fontSizeStyles = ( { inputSize: size }: InputProps ) => {
|
|
|
140
141
|
`;
|
|
141
142
|
};
|
|
142
143
|
|
|
143
|
-
const sizeStyles = ( {
|
|
144
|
+
const sizeStyles = ( {
|
|
145
|
+
inputSize: size,
|
|
146
|
+
__next36pxDefaultSize,
|
|
147
|
+
}: InputProps ) => {
|
|
144
148
|
const sizes = {
|
|
145
149
|
default: {
|
|
146
|
-
height:
|
|
150
|
+
height: 36,
|
|
147
151
|
lineHeight: 1,
|
|
148
|
-
minHeight:
|
|
149
|
-
paddingLeft:
|
|
150
|
-
paddingRight:
|
|
152
|
+
minHeight: 36,
|
|
153
|
+
paddingLeft: 16,
|
|
154
|
+
paddingRight: 16,
|
|
151
155
|
},
|
|
152
156
|
small: {
|
|
153
157
|
height: 24,
|
|
@@ -165,6 +169,16 @@ const sizeStyles = ( { inputSize: size }: InputProps ) => {
|
|
|
165
169
|
},
|
|
166
170
|
};
|
|
167
171
|
|
|
172
|
+
if ( ! __next36pxDefaultSize ) {
|
|
173
|
+
sizes.default = {
|
|
174
|
+
height: 30,
|
|
175
|
+
lineHeight: 1,
|
|
176
|
+
minHeight: 30,
|
|
177
|
+
paddingLeft: 8,
|
|
178
|
+
paddingRight: 8,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
168
182
|
const style = sizes[ size as Size ] || sizes.default;
|
|
169
183
|
|
|
170
184
|
return css( style );
|
|
@@ -27,6 +27,12 @@ export type DragProps = Parameters< Parameters< typeof useDrag >[ 0 ] >[ 0 ];
|
|
|
27
27
|
export type Size = 'default' | 'small' | '__unstable-large';
|
|
28
28
|
|
|
29
29
|
interface BaseProps {
|
|
30
|
+
/**
|
|
31
|
+
* Start opting into the larger default height that will become the default size in a future version.
|
|
32
|
+
*
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
__next36pxDefaultSize?: boolean;
|
|
30
36
|
__unstableInputWidth?: CSSProperties[ 'width' ];
|
|
31
37
|
/**
|
|
32
38
|
* If true, the label will only be visible to screen readers.
|
package/src/menu-item/style.scss
CHANGED
|
@@ -38,6 +38,16 @@
|
|
|
38
38
|
margin-right: 0;
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
&:disabled,
|
|
43
|
+
&[aria-disabled="true"] {
|
|
44
|
+
// Override the button component's tertiary background and color.
|
|
45
|
+
&.is-tertiary {
|
|
46
|
+
background: none;
|
|
47
|
+
color: var(--wp-admin-theme-color-darker-10);
|
|
48
|
+
opacity: 0.3;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
41
51
|
}
|
|
42
52
|
|
|
43
53
|
.components-menu-item__info-wrapper {
|
|
@@ -27,7 +27,14 @@ const TestScreen = ( { fullScreen, name, navigateTo } ) => {
|
|
|
27
27
|
);
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
beforeAll( () => {
|
|
31
|
+
jest.useFakeTimers( 'legacy' );
|
|
32
|
+
} );
|
|
33
|
+
|
|
34
|
+
afterAll( () => {
|
|
35
|
+
jest.runOnlyPendingTimers();
|
|
36
|
+
jest.useRealTimers();
|
|
37
|
+
} );
|
|
31
38
|
|
|
32
39
|
it( 'animates height transitioning from non-full-screen to full-screen', async () => {
|
|
33
40
|
const screen = render(
|
|
@@ -9,7 +9,15 @@ import { render, fireEvent, waitFor } from 'test/helpers';
|
|
|
9
9
|
*/
|
|
10
10
|
import LinkSettingsNavigation from '../link-settings-navigation';
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
beforeAll( () => {
|
|
13
|
+
jest.useFakeTimers( 'legacy' );
|
|
14
|
+
} );
|
|
15
|
+
|
|
16
|
+
afterAll( () => {
|
|
17
|
+
jest.runOnlyPendingTimers();
|
|
18
|
+
jest.useRealTimers();
|
|
19
|
+
} );
|
|
20
|
+
|
|
13
21
|
jest.spyOn( Keyboard, 'dismiss' );
|
|
14
22
|
|
|
15
23
|
const subject = (
|
package/src/popover/index.js
CHANGED
|
@@ -47,7 +47,6 @@ function computeAnchorRect(
|
|
|
47
47
|
anchorRect,
|
|
48
48
|
getAnchorRect,
|
|
49
49
|
anchorRef = false,
|
|
50
|
-
shouldAnchorIncludePadding,
|
|
51
50
|
container
|
|
52
51
|
) {
|
|
53
52
|
if ( anchorRect ) {
|
|
@@ -98,17 +97,14 @@ function computeAnchorRect(
|
|
|
98
97
|
container
|
|
99
98
|
);
|
|
100
99
|
|
|
101
|
-
|
|
102
|
-
return rect;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return withoutPadding( rect, anchorRef );
|
|
100
|
+
return rect;
|
|
106
101
|
}
|
|
107
102
|
|
|
108
103
|
const { top, bottom } = anchorRef;
|
|
109
104
|
const topRect = top.getBoundingClientRect();
|
|
110
105
|
const bottomRect = bottom.getBoundingClientRect();
|
|
111
|
-
|
|
106
|
+
|
|
107
|
+
return offsetIframe(
|
|
112
108
|
new window.DOMRect(
|
|
113
109
|
topRect.left,
|
|
114
110
|
topRect.top,
|
|
@@ -118,12 +114,6 @@ function computeAnchorRect(
|
|
|
118
114
|
top.ownerDocument,
|
|
119
115
|
container
|
|
120
116
|
);
|
|
121
|
-
|
|
122
|
-
if ( shouldAnchorIncludePadding ) {
|
|
123
|
-
return rect;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return withoutPadding( rect, anchorRef );
|
|
127
117
|
}
|
|
128
118
|
|
|
129
119
|
if ( ! anchorRefFallback.current ) {
|
|
@@ -131,45 +121,12 @@ function computeAnchorRect(
|
|
|
131
121
|
}
|
|
132
122
|
|
|
133
123
|
const { parentNode } = anchorRefFallback.current;
|
|
134
|
-
|
|
124
|
+
|
|
125
|
+
return offsetIframe(
|
|
135
126
|
parentNode.getBoundingClientRect(),
|
|
136
127
|
parentNode.ownerDocument,
|
|
137
128
|
container
|
|
138
129
|
);
|
|
139
|
-
|
|
140
|
-
if ( shouldAnchorIncludePadding ) {
|
|
141
|
-
return rect;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return withoutPadding( rect, parentNode );
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function getComputedStyle( node ) {
|
|
148
|
-
return node.ownerDocument.defaultView.getComputedStyle( node );
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function withoutPadding( rect, element ) {
|
|
152
|
-
const {
|
|
153
|
-
paddingTop,
|
|
154
|
-
paddingBottom,
|
|
155
|
-
paddingLeft,
|
|
156
|
-
paddingRight,
|
|
157
|
-
} = getComputedStyle( element );
|
|
158
|
-
const top = paddingTop ? parseInt( paddingTop, 10 ) : 0;
|
|
159
|
-
const bottom = paddingBottom ? parseInt( paddingBottom, 10 ) : 0;
|
|
160
|
-
const left = paddingLeft ? parseInt( paddingLeft, 10 ) : 0;
|
|
161
|
-
const right = paddingRight ? parseInt( paddingRight, 10 ) : 0;
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
x: rect.left + left,
|
|
165
|
-
y: rect.top + top,
|
|
166
|
-
width: rect.width - left - right,
|
|
167
|
-
height: rect.height - top - bottom,
|
|
168
|
-
left: rect.left + left,
|
|
169
|
-
right: rect.right - right,
|
|
170
|
-
top: rect.top + top,
|
|
171
|
-
bottom: rect.bottom - bottom,
|
|
172
|
-
};
|
|
173
130
|
}
|
|
174
131
|
|
|
175
132
|
/**
|
|
@@ -252,7 +209,6 @@ const Popover = (
|
|
|
252
209
|
range,
|
|
253
210
|
focusOnMount = 'firstElement',
|
|
254
211
|
anchorRef,
|
|
255
|
-
shouldAnchorIncludePadding,
|
|
256
212
|
anchorRect,
|
|
257
213
|
getAnchorRect,
|
|
258
214
|
expandOnMobile,
|
|
@@ -304,7 +260,6 @@ const Popover = (
|
|
|
304
260
|
anchorRect,
|
|
305
261
|
getAnchorRect,
|
|
306
262
|
anchorRef,
|
|
307
|
-
shouldAnchorIncludePadding,
|
|
308
263
|
containerRef.current
|
|
309
264
|
);
|
|
310
265
|
|
|
@@ -480,7 +435,6 @@ const Popover = (
|
|
|
480
435
|
anchorRect,
|
|
481
436
|
getAnchorRect,
|
|
482
437
|
anchorRef,
|
|
483
|
-
shouldAnchorIncludePadding,
|
|
484
438
|
position,
|
|
485
439
|
contentSize,
|
|
486
440
|
__unstableStickyBoundaryElement,
|
|
@@ -114,7 +114,7 @@ Render a user interface to select multiple users from a list.
|
|
|
114
114
|
this.setState( { users } );
|
|
115
115
|
} }
|
|
116
116
|
options={ [
|
|
117
|
-
{ value:
|
|
117
|
+
{ value: '', label: 'Select a User', disabled: true },
|
|
118
118
|
{ value: 'a', label: 'User A' },
|
|
119
119
|
{ value: 'b', label: 'User B' },
|
|
120
120
|
{ value: 'c', label: 'User c' },
|
|
@@ -194,7 +194,7 @@ If this property is added, multiple values can be selected. The value passed sho
|
|
|
194
194
|
An array of objects containing the following properties:
|
|
195
195
|
|
|
196
196
|
- `label`: (string) The label to be shown to the user.
|
|
197
|
-
- `value`: (
|
|
197
|
+
- `value`: (string) The internal value used to choose the selected value. This is also the value passed to onChange when the option is selected.
|
|
198
198
|
- `disabled`: (boolean) Whether or not the option should have the disabled attribute.
|
|
199
199
|
- Type: `Array`
|
|
200
200
|
- Required: No
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { isEmpty, noop } from 'lodash';
|
|
5
5
|
import classNames from 'classnames';
|
|
6
|
-
import type { ChangeEvent, FocusEvent,
|
|
6
|
+
import type { ChangeEvent, FocusEvent, ForwardedRef } from 'react';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* WordPress dependencies
|
|
@@ -17,10 +17,9 @@ import { Icon, chevronDown } from '@wordpress/icons';
|
|
|
17
17
|
*/
|
|
18
18
|
import BaseControl from '../base-control';
|
|
19
19
|
import InputBase from '../input-control/input-base';
|
|
20
|
-
import type { InputBaseProps, LabelPosition } from '../input-control/types';
|
|
21
20
|
import { Select, DownArrowWrapper } from './styles/select-control-styles';
|
|
22
|
-
import type { Size } from './types';
|
|
23
21
|
import type { WordPressComponentProps } from '../ui/context';
|
|
22
|
+
import type { SelectControlProps } from './types';
|
|
24
23
|
|
|
25
24
|
function useUniqueId( idProp?: string ) {
|
|
26
25
|
const instanceId = useInstanceId( SelectControl );
|
|
@@ -29,30 +28,7 @@ function useUniqueId( idProp?: string ) {
|
|
|
29
28
|
return idProp || id;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
extends Omit< InputBaseProps, 'children' | 'isFocused' > {
|
|
34
|
-
help?: string;
|
|
35
|
-
hideLabelFromVision?: boolean;
|
|
36
|
-
multiple?: boolean;
|
|
37
|
-
onBlur?: ( event: FocusEvent< HTMLSelectElement > ) => void;
|
|
38
|
-
onFocus?: ( event: FocusEvent< HTMLSelectElement > ) => void;
|
|
39
|
-
onChange?: (
|
|
40
|
-
value: string | string[],
|
|
41
|
-
extra?: { event?: ChangeEvent< HTMLSelectElement > }
|
|
42
|
-
) => void;
|
|
43
|
-
options?: {
|
|
44
|
-
label: string;
|
|
45
|
-
value: string;
|
|
46
|
-
id?: string;
|
|
47
|
-
disabled?: boolean;
|
|
48
|
-
}[];
|
|
49
|
-
size?: Size;
|
|
50
|
-
value?: string | string[];
|
|
51
|
-
labelPosition?: LabelPosition;
|
|
52
|
-
children?: ReactNode;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function SelectControl(
|
|
31
|
+
function UnforwardedSelectControl(
|
|
56
32
|
{
|
|
57
33
|
className,
|
|
58
34
|
disabled = false,
|
|
@@ -165,6 +141,31 @@ function SelectControl(
|
|
|
165
141
|
/* eslint-enable jsx-a11y/no-onchange */
|
|
166
142
|
}
|
|
167
143
|
|
|
168
|
-
|
|
144
|
+
/**
|
|
145
|
+
* `SelectControl` allows users to select from a single or multiple option menu.
|
|
146
|
+
* It functions as a wrapper around the browser's native `<select>` element.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* import { SelectControl } from '@wordpress/components';
|
|
150
|
+
* import { useState } from '@wordpress/element';
|
|
151
|
+
*
|
|
152
|
+
* const MySelectControl = () => {
|
|
153
|
+
* const [ size, setSize ] = useState( '50%' );
|
|
154
|
+
*
|
|
155
|
+
* return (
|
|
156
|
+
* <SelectControl
|
|
157
|
+
* label="Size"
|
|
158
|
+
* value={ size }
|
|
159
|
+
* options={ [
|
|
160
|
+
* { label: 'Big', value: '100%' },
|
|
161
|
+
* { label: 'Medium', value: '50%' },
|
|
162
|
+
* { label: 'Small', value: '25%' },
|
|
163
|
+
* ] }
|
|
164
|
+
* onChange={ setSize }
|
|
165
|
+
* />
|
|
166
|
+
* );
|
|
167
|
+
* };
|
|
168
|
+
*/
|
|
169
|
+
export const SelectControl = forwardRef( UnforwardedSelectControl );
|
|
169
170
|
|
|
170
|
-
export default
|
|
171
|
+
export default SelectControl;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentMeta, ComponentStory } from '@storybook/react';
|
|
5
|
+
import type { ComponentProps } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* WordPress dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { useState } from '@wordpress/element';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
import SelectControl from '..';
|
|
16
|
+
|
|
17
|
+
const meta: ComponentMeta< typeof SelectControl > = {
|
|
18
|
+
title: 'Components/SelectControl',
|
|
19
|
+
component: SelectControl,
|
|
20
|
+
argTypes: {
|
|
21
|
+
help: { control: { type: 'text' } },
|
|
22
|
+
label: { control: { type: 'text' } },
|
|
23
|
+
prefix: { control: { type: 'text' } },
|
|
24
|
+
suffix: { control: { type: 'text' } },
|
|
25
|
+
value: { control: { type: null } },
|
|
26
|
+
},
|
|
27
|
+
parameters: {
|
|
28
|
+
controls: { expanded: true },
|
|
29
|
+
docs: { source: { state: 'open' } },
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
export default meta;
|
|
33
|
+
|
|
34
|
+
const SelectControlWithState: ComponentStory< typeof SelectControl > = (
|
|
35
|
+
args
|
|
36
|
+
) => {
|
|
37
|
+
const [ selection, setSelection ] = useState<
|
|
38
|
+
ComponentProps< typeof SelectControl >[ 'value' ]
|
|
39
|
+
>();
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<SelectControl
|
|
43
|
+
{ ...args }
|
|
44
|
+
value={ selection }
|
|
45
|
+
onChange={ setSelection }
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const Default = SelectControlWithState.bind( {} );
|
|
51
|
+
Default.args = {
|
|
52
|
+
options: [
|
|
53
|
+
{ value: '', label: 'Select an Option', disabled: true },
|
|
54
|
+
{ value: 'a', label: 'Option A' },
|
|
55
|
+
{ value: 'b', label: 'Option B' },
|
|
56
|
+
{ value: 'c', label: 'Option C' },
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const WithLabelAndHelpText = SelectControlWithState.bind( {} );
|
|
61
|
+
WithLabelAndHelpText.args = {
|
|
62
|
+
...Default.args,
|
|
63
|
+
help: 'Help text to explain the select control.',
|
|
64
|
+
label: 'Value',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* As an alternative to the `options` prop, `optgroup`s and `options` can be
|
|
69
|
+
* passed in as `children` for more customizability.
|
|
70
|
+
*/
|
|
71
|
+
export const WithCustomChildren: ComponentStory< typeof SelectControl > = (
|
|
72
|
+
args
|
|
73
|
+
) => {
|
|
74
|
+
return (
|
|
75
|
+
<SelectControlWithState { ...args }>
|
|
76
|
+
<option value="option-1">Option 1</option>
|
|
77
|
+
<option value="option-2" disabled>
|
|
78
|
+
Option 2 - Disabled
|
|
79
|
+
</option>
|
|
80
|
+
<optgroup label="Option Group 1">
|
|
81
|
+
<option value="option-group-1-option-1">
|
|
82
|
+
Option Group 1 - Option 1
|
|
83
|
+
</option>
|
|
84
|
+
<option value="option-group-1-option-2" disabled>
|
|
85
|
+
Option Group 1 - Option 2 - Disabled
|
|
86
|
+
</option>
|
|
87
|
+
</optgroup>
|
|
88
|
+
</SelectControlWithState>
|
|
89
|
+
);
|
|
90
|
+
};
|