@wordpress/components 19.7.0-next.e230fbab09.0 → 19.7.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 +31 -1
- package/build/base-control/index.js +19 -14
- package/build/base-control/index.js.map +1 -1
- package/build/base-control/styles/base-control-styles.js +33 -12
- package/build/base-control/styles/base-control-styles.js.map +1 -1
- package/build/box-control/all-input-control.js +3 -7
- package/build/box-control/all-input-control.js.map +1 -1
- package/build/box-control/axial-input-controls.js +20 -15
- package/build/box-control/axial-input-controls.js.map +1 -1
- package/build/box-control/input-controls.js +21 -16
- package/build/box-control/input-controls.js.map +1 -1
- package/build/box-control/utils.js +25 -11
- package/build/box-control/utils.js.map +1 -1
- package/build/checkbox-control/index.js +21 -1
- package/build/checkbox-control/index.js.map +1 -1
- package/build/color-palette/index.js +53 -4
- package/build/color-palette/index.js.map +1 -1
- package/build/custom-select-control/index.js +8 -3
- package/build/custom-select-control/index.js.map +1 -1
- package/build/divider/styles.js +28 -16
- package/build/divider/styles.js.map +1 -1
- package/build/focal-point-picker/controls.js +2 -3
- package/build/focal-point-picker/controls.js.map +1 -1
- package/build/form-file-upload/index.js +4 -1
- package/build/form-file-upload/index.js.map +1 -1
- package/build/input-control/input-field.js +21 -14
- package/build/input-control/input-field.js.map +1 -1
- package/build/input-control/reducer/actions.js +1 -3
- package/build/input-control/reducer/actions.js.map +1 -1
- package/build/input-control/reducer/reducer.js +1 -43
- package/build/input-control/reducer/reducer.js.map +1 -1
- package/build/number-control/index.js +15 -10
- package/build/number-control/index.js.map +1 -1
- package/build/resizable-box/resize-tooltip/styles/resize-tooltip.styles.js +4 -4
- package/build/resizable-box/resize-tooltip/styles/resize-tooltip.styles.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control-option/component.js +1 -4
- package/build/toggle-group-control/toggle-group-control-option/component.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control-option/styles.js +12 -19
- package/build/toggle-group-control/toggle-group-control-option/styles.js.map +1 -1
- package/build/tree-grid/index.js +4 -1
- package/build/tree-grid/index.js.map +1 -1
- package/build/unit-control/index.js +49 -27
- package/build/unit-control/index.js.map +1 -1
- package/build/unit-control/unit-select-control.js +2 -4
- package/build/unit-control/unit-select-control.js.map +1 -1
- package/build-module/base-control/index.js +19 -14
- package/build-module/base-control/index.js.map +1 -1
- package/build-module/base-control/styles/base-control-styles.js +34 -6
- package/build-module/base-control/styles/base-control-styles.js.map +1 -1
- package/build-module/box-control/all-input-control.js +4 -8
- package/build-module/box-control/all-input-control.js.map +1 -1
- package/build-module/box-control/axial-input-controls.js +18 -14
- package/build-module/box-control/axial-input-controls.js.map +1 -1
- package/build-module/box-control/input-controls.js +18 -14
- package/build-module/box-control/input-controls.js.map +1 -1
- package/build-module/box-control/utils.js +25 -11
- package/build-module/box-control/utils.js.map +1 -1
- package/build-module/checkbox-control/index.js +24 -3
- package/build-module/checkbox-control/index.js.map +1 -1
- package/build-module/color-palette/index.js +52 -4
- package/build-module/color-palette/index.js.map +1 -1
- package/build-module/custom-select-control/index.js +8 -3
- package/build-module/custom-select-control/index.js.map +1 -1
- package/build-module/divider/styles.js +29 -10
- package/build-module/divider/styles.js.map +1 -1
- package/build-module/focal-point-picker/controls.js +2 -3
- package/build-module/focal-point-picker/controls.js.map +1 -1
- package/build-module/form-file-upload/index.js +4 -1
- package/build-module/form-file-upload/index.js.map +1 -1
- package/build-module/input-control/input-field.js +21 -13
- package/build-module/input-control/input-field.js.map +1 -1
- package/build-module/input-control/reducer/actions.js +0 -1
- package/build-module/input-control/reducer/actions.js.map +1 -1
- package/build-module/input-control/reducer/reducer.js +2 -39
- package/build-module/input-control/reducer/reducer.js.map +1 -1
- package/build-module/number-control/index.js +15 -9
- package/build-module/number-control/index.js.map +1 -1
- package/build-module/resizable-box/resize-tooltip/styles/resize-tooltip.styles.js +4 -4
- package/build-module/resizable-box/resize-tooltip/styles/resize-tooltip.styles.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control-option/component.js +1 -4
- package/build-module/toggle-group-control/toggle-group-control-option/component.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control-option/styles.js +11 -17
- package/build-module/toggle-group-control/toggle-group-control-option/styles.js.map +1 -1
- package/build-module/tree-grid/index.js +4 -1
- package/build-module/tree-grid/index.js.map +1 -1
- package/build-module/unit-control/index.js +47 -25
- package/build-module/unit-control/index.js.map +1 -1
- package/build-module/unit-control/unit-select-control.js +2 -3
- package/build-module/unit-control/unit-select-control.js.map +1 -1
- package/build-style/style-rtl.css +29 -181
- package/build-style/style.css +29 -181
- package/build-types/base-control/index.d.ts +23 -18
- package/build-types/base-control/index.d.ts.map +1 -1
- package/build-types/base-control/styles/base-control-styles.d.ts +4 -0
- package/build-types/base-control/styles/base-control-styles.d.ts.map +1 -1
- package/build-types/card/card-divider/hook.d.ts +1 -1
- package/build-types/color-palette/index.d.ts.map +1 -1
- package/build-types/color-picker/styles.d.ts +1 -1
- package/build-types/divider/stories/index.d.ts +1 -0
- package/build-types/divider/stories/index.d.ts.map +1 -1
- package/build-types/divider/styles.d.ts.map +1 -1
- package/build-types/divider/types.d.ts +8 -1
- package/build-types/divider/types.d.ts.map +1 -1
- package/build-types/input-control/input-field.d.ts.map +1 -1
- package/build-types/input-control/reducer/actions.d.ts +1 -3
- package/build-types/input-control/reducer/actions.d.ts.map +1 -1
- package/build-types/input-control/reducer/reducer.d.ts +3 -9
- package/build-types/input-control/reducer/reducer.d.ts.map +1 -1
- package/build-types/input-control/types.d.ts +2 -2
- package/build-types/input-control/types.d.ts.map +1 -1
- package/build-types/number-control/index.d.ts +3 -3
- package/build-types/number-control/index.d.ts.map +1 -1
- package/build-types/range-control/styles/range-control-styles.d.ts +1 -1
- package/build-types/resizable-box/resize-tooltip/styles/resize-tooltip.styles.d.ts.map +1 -1
- package/build-types/toggle-group-control/toggle-group-control-option/component.d.ts.map +1 -1
- package/build-types/toggle-group-control/toggle-group-control-option/styles.d.ts +0 -4
- package/build-types/toggle-group-control/toggle-group-control-option/styles.d.ts.map +1 -1
- package/build-types/unit-control/index.d.ts +7 -4
- package/build-types/unit-control/index.d.ts.map +1 -1
- package/build-types/unit-control/stories/index.d.ts +33 -0
- package/build-types/unit-control/stories/index.d.ts.map +1 -0
- package/build-types/unit-control/styles/unit-control-styles.d.ts +1 -1
- package/build-types/unit-control/types.d.ts +23 -6
- package/build-types/unit-control/types.d.ts.map +1 -1
- package/build-types/unit-control/unit-select-control.d.ts.map +1 -1
- package/package.json +17 -17
- package/src/base-control/README.md +9 -1
- package/src/base-control/index.js +20 -13
- package/src/base-control/stories/index.js +2 -2
- package/src/base-control/styles/base-control-styles.js +23 -1
- package/src/box-control/all-input-control.js +2 -10
- package/src/box-control/axial-input-controls.js +32 -21
- package/src/box-control/input-controls.js +30 -19
- package/src/box-control/utils.js +29 -12
- package/src/checkbox-control/index.js +34 -3
- package/src/checkbox-control/stories/index.js +44 -0
- package/src/checkbox-control/style.scss +4 -2
- package/src/color-palette/index.js +73 -8
- package/src/color-palette/stories/index.js +62 -26
- package/src/color-palette/style.scss +11 -3
- package/src/color-palette/test/__snapshots__/index.js.snap +662 -12
- package/src/color-palette/test/index.js +1 -1
- package/src/custom-select-control/index.js +8 -2
- package/src/custom-select-control/stories/index.js +77 -74
- package/src/custom-select-control/style.scss +18 -3
- package/src/divider/stories/index.tsx +26 -23
- package/src/divider/styles.ts +9 -0
- package/src/divider/types.ts +11 -1
- package/src/focal-point-picker/controls.js +2 -3
- package/src/font-size-picker/test/index.js +0 -2
- package/src/form-file-upload/README.md +18 -0
- package/src/form-file-upload/index.js +3 -0
- package/src/form-file-upload/test/index.js +73 -11
- package/src/input-control/input-field.tsx +23 -12
- package/src/input-control/reducer/actions.ts +1 -7
- package/src/input-control/reducer/reducer.ts +0 -29
- package/src/input-control/types.ts +2 -1
- package/src/number-control/README.md +14 -0
- package/src/number-control/index.js +13 -12
- package/src/number-control/stories/index.js +14 -7
- package/src/number-control/test/index.js +79 -1
- package/src/range-control/stories/index.js +91 -119
- package/src/resizable-box/resize-tooltip/styles/resize-tooltip.styles.js +1 -0
- package/src/toggle-group-control/test/__snapshots__/index.js.snap +0 -27
- package/src/toggle-group-control/toggle-group-control-option/component.tsx +1 -4
- package/src/toggle-group-control/toggle-group-control-option/styles.ts +0 -12
- package/src/toolbar-group/style.scss +0 -73
- package/src/tree-grid/README.md +1 -1
- package/src/tree-grid/index.js +4 -0
- package/src/tree-grid/test/index.js +61 -17
- package/src/unit-control/README.md +1 -3
- package/src/unit-control/index.tsx +59 -30
- package/src/unit-control/stories/index.tsx +170 -0
- package/src/unit-control/test/index.js +143 -100
- package/src/unit-control/types.ts +60 -41
- package/src/unit-control/unit-select-control.tsx +2 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/src/unit-control/stories/index.js +0 -127
|
@@ -61,24 +61,12 @@ export const buttonActive = css`
|
|
|
61
61
|
export const ButtonContentView = styled.div`
|
|
62
62
|
font-size: ${ CONFIG.fontSize };
|
|
63
63
|
line-height: 1;
|
|
64
|
-
position: absolute;
|
|
65
|
-
top: 50%;
|
|
66
|
-
left: 50%;
|
|
67
|
-
transform: translate( -50%, -50% );
|
|
68
64
|
`;
|
|
69
65
|
|
|
70
66
|
export const separatorActive = css`
|
|
71
67
|
background: transparent;
|
|
72
68
|
`;
|
|
73
69
|
|
|
74
|
-
export const LabelPlaceholderView = styled.div`
|
|
75
|
-
font-size: ${ CONFIG.fontSize };
|
|
76
|
-
font-weight: bold;
|
|
77
|
-
height: 0;
|
|
78
|
-
overflow: hidden;
|
|
79
|
-
visibility: hidden;
|
|
80
|
-
`;
|
|
81
|
-
|
|
82
70
|
export const medium = css`
|
|
83
71
|
min-height: ${ CONFIG.controlHeight };
|
|
84
72
|
`;
|
|
@@ -64,76 +64,3 @@ div.components-toolbar {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
|
|
68
|
-
// Size multiple sequential buttons to be optically balanced.
|
|
69
|
-
// Icons are 36px, as set by a 24px icon and 12px padding.
|
|
70
|
-
.block-editor-block-toolbar > .components-toolbar > .block-editor-block-toolbar__slot, // When a plugin adds to a slot, the segment has a `components-toolbar` class.
|
|
71
|
-
.block-editor-block-toolbar > .components-toolbar-group > .block-editor-block-toolbar__slot, // When no plugin adds to slots, the segment has a `components-toolbar-group` class.
|
|
72
|
-
.block-editor-block-toolbar > .block-editor-block-toolbar__slot > .components-toolbar, // The nesting order is sometimes reversed.
|
|
73
|
-
.block-editor-block-toolbar > .block-editor-block-toolbar__slot > .components-dropdown, // Targets unique markup for the "Replace" button.
|
|
74
|
-
.block-editor-block-toolbar .block-editor-block-toolbar__slot .components-toolbar-group { // Inline formatting tools use this class.
|
|
75
|
-
|
|
76
|
-
// Segments with just a single button.
|
|
77
|
-
> .components-button:first-child:last-child,
|
|
78
|
-
> .components-dropdown:first-child:last-child .components-button,
|
|
79
|
-
&.components-dropdown > .components-button.components-button, // Single segments where the dropdown is also the toolbar group (such as text align).
|
|
80
|
-
&.components-dropdown > * .components-button {
|
|
81
|
-
min-width: $block-toolbar-height;
|
|
82
|
-
padding-left: $grid-unit-15;
|
|
83
|
-
padding-right: $grid-unit-15;
|
|
84
|
-
|
|
85
|
-
&::before {
|
|
86
|
-
left: $grid-unit-10;
|
|
87
|
-
right: $grid-unit-10;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// First.
|
|
92
|
-
// @todo, this unnamed div only shows up when plugins add to slots. We should remove the fragment.
|
|
93
|
-
> .components-button:first-child,
|
|
94
|
-
> div:first-child > .components-button,
|
|
95
|
-
> .components-dropdown:first-child .components-button {
|
|
96
|
-
min-width: $block-toolbar-height - $grid-unit-15 * 0.5;
|
|
97
|
-
padding-left: $grid-unit-15 - $border-width;
|
|
98
|
-
padding-right: $grid-unit-15 * 0.5;
|
|
99
|
-
|
|
100
|
-
&::before {
|
|
101
|
-
left: $grid-unit-10;
|
|
102
|
-
right: 2px;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Middle.
|
|
107
|
-
// @todo, this unnamed div only shows up when plugins add to slots. We should remove the fragment.
|
|
108
|
-
> .components-button,
|
|
109
|
-
> div > .components-button,
|
|
110
|
-
> .components-dropdown .components-button {
|
|
111
|
-
min-width: $block-toolbar-height - $grid-unit-15;
|
|
112
|
-
padding-left: $grid-unit-15 * 0.5; // 6px.
|
|
113
|
-
padding-right: $grid-unit-15 * 0.5;
|
|
114
|
-
|
|
115
|
-
svg {
|
|
116
|
-
min-width: $button-size-small; // This is the optimal icon size, and we size the whole button after this.
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
&::before {
|
|
120
|
-
left: 2px;
|
|
121
|
-
right: 2px;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Last.
|
|
126
|
-
// @todo, this unnamed div only shows up when plugins add to slots. We should remove the fragment.
|
|
127
|
-
> .components-button:last-child,
|
|
128
|
-
> div:last-child > .components-button,
|
|
129
|
-
> .components-dropdown:last-child .components-button {
|
|
130
|
-
min-width: $block-toolbar-height - $grid-unit-15 * 0.5;
|
|
131
|
-
padding-left: $grid-unit-15 * 0.5;
|
|
132
|
-
padding-right: $grid-unit-15 - $border-width;
|
|
133
|
-
|
|
134
|
-
&::before {
|
|
135
|
-
left: 2px;
|
|
136
|
-
right: $grid-unit-10;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
package/src/tree-grid/README.md
CHANGED
|
@@ -114,7 +114,7 @@ Aside from the documented callback functions, any props specified will be passed
|
|
|
114
114
|
|
|
115
115
|
###### onFocusRow( event: Event, startRow: HTMLElement, destinationRow: HTMLElement )
|
|
116
116
|
|
|
117
|
-
Callback that fires when focus is shifted from one row to another via the
|
|
117
|
+
Callback that fires when focus is shifted from one row to another via the Up and Down keys. Callback is also fired on Home and End keys which move focus from the beginning row to the end row.
|
|
118
118
|
The callback is passed the event, the start row element that the focus was on originally, and
|
|
119
119
|
the destination row element after the focus has moved.
|
|
120
120
|
|
package/src/tree-grid/index.js
CHANGED
|
@@ -275,6 +275,10 @@ function TreeGrid(
|
|
|
275
275
|
);
|
|
276
276
|
focusablesInNextRow[ nextIndex ].focus();
|
|
277
277
|
|
|
278
|
+
// Let consumers know the row that was originally focused,
|
|
279
|
+
// and the row that is now in focus.
|
|
280
|
+
onFocusRow( event, activeRow, rows[ nextRowIndex ] );
|
|
281
|
+
|
|
278
282
|
// Prevent key use for anything else. This ensures Voiceover
|
|
279
283
|
// doesn't try to handle key navigation.
|
|
280
284
|
event.preventDefault();
|
|
@@ -6,7 +6,7 @@ import { fireEvent, render, screen } from '@testing-library/react';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
-
import { LEFT, RIGHT, UP, DOWN } from '@wordpress/keycodes';
|
|
9
|
+
import { LEFT, RIGHT, UP, DOWN, HOME, END } from '@wordpress/keycodes';
|
|
10
10
|
import { forwardRef } from '@wordpress/element';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -68,10 +68,10 @@ describe( 'TreeGrid', () => {
|
|
|
68
68
|
level={ 1 }
|
|
69
69
|
positionInSet={ 1 }
|
|
70
70
|
setSize={ 3 }
|
|
71
|
-
isExpanded={
|
|
71
|
+
isExpanded={ false }
|
|
72
72
|
>
|
|
73
73
|
<TreeGridCell withoutGridItem>
|
|
74
|
-
<TestButton>Row 1</TestButton>
|
|
74
|
+
<TestButton aria-expanded="false">Row 1</TestButton>
|
|
75
75
|
</TreeGridCell>
|
|
76
76
|
</TreeGridRow>
|
|
77
77
|
<TreeGridRow
|
|
@@ -88,7 +88,7 @@ describe( 'TreeGrid', () => {
|
|
|
88
88
|
level={ 1 }
|
|
89
89
|
positionInSet={ 3 }
|
|
90
90
|
setSize={ 3 }
|
|
91
|
-
isExpanded={
|
|
91
|
+
isExpanded={ false }
|
|
92
92
|
>
|
|
93
93
|
<TreeGridCell withoutGridItem>
|
|
94
94
|
<TestButton>Row 3</TestButton>
|
|
@@ -97,16 +97,16 @@ describe( 'TreeGrid', () => {
|
|
|
97
97
|
</TreeGrid>
|
|
98
98
|
);
|
|
99
99
|
|
|
100
|
-
screen.getByText( 'Row
|
|
101
|
-
const
|
|
100
|
+
screen.getByText( 'Row 1' ).focus();
|
|
101
|
+
const row1Element = screen.getByText( 'Row 1' ).closest( 'tr' );
|
|
102
102
|
|
|
103
|
-
fireEvent.keyDown( screen.getByText( 'Row
|
|
103
|
+
fireEvent.keyDown( screen.getByText( 'Row 1' ), {
|
|
104
104
|
key: 'ArrowRight',
|
|
105
105
|
keyCode: RIGHT,
|
|
106
|
-
currentTarget:
|
|
106
|
+
currentTarget: row1Element,
|
|
107
107
|
} );
|
|
108
108
|
|
|
109
|
-
expect( onExpandRow ).toHaveBeenCalledWith(
|
|
109
|
+
expect( onExpandRow ).toHaveBeenCalledWith( row1Element );
|
|
110
110
|
} );
|
|
111
111
|
} );
|
|
112
112
|
|
|
@@ -120,17 +120,17 @@ describe( 'TreeGrid', () => {
|
|
|
120
120
|
level={ 1 }
|
|
121
121
|
positionInSet={ 1 }
|
|
122
122
|
setSize={ 3 }
|
|
123
|
-
isExpanded={
|
|
123
|
+
isExpanded={ true }
|
|
124
124
|
>
|
|
125
125
|
<TreeGridCell withoutGridItem>
|
|
126
|
-
<TestButton>Row 1</TestButton>
|
|
126
|
+
<TestButton aria-expanded="true">Row 1</TestButton>
|
|
127
127
|
</TreeGridCell>
|
|
128
128
|
</TreeGridRow>
|
|
129
129
|
<TreeGridRow
|
|
130
130
|
level={ 1 }
|
|
131
131
|
positionInSet={ 2 }
|
|
132
132
|
setSize={ 3 }
|
|
133
|
-
isExpanded={
|
|
133
|
+
isExpanded={ false }
|
|
134
134
|
>
|
|
135
135
|
<TreeGridCell withoutGridItem>
|
|
136
136
|
<TestButton>Row 2</TestButton>
|
|
@@ -149,16 +149,16 @@ describe( 'TreeGrid', () => {
|
|
|
149
149
|
</TreeGrid>
|
|
150
150
|
);
|
|
151
151
|
|
|
152
|
-
screen.getByText( 'Row
|
|
153
|
-
const
|
|
152
|
+
screen.getByText( 'Row 1' ).focus();
|
|
153
|
+
const row1Element = screen.getByText( 'Row 1' ).closest( 'tr' );
|
|
154
154
|
|
|
155
|
-
fireEvent.keyDown( screen.getByText( 'Row
|
|
155
|
+
fireEvent.keyDown( screen.getByText( 'Row 1' ), {
|
|
156
156
|
key: 'ArrowLeft',
|
|
157
157
|
keyCode: LEFT,
|
|
158
|
-
currentTarget:
|
|
158
|
+
currentTarget: row1Element,
|
|
159
159
|
} );
|
|
160
160
|
|
|
161
|
-
expect( onCollapseRow ).toHaveBeenCalledWith(
|
|
161
|
+
expect( onCollapseRow ).toHaveBeenCalledWith( row1Element );
|
|
162
162
|
} );
|
|
163
163
|
} );
|
|
164
164
|
|
|
@@ -205,6 +205,28 @@ describe( 'TreeGrid', () => {
|
|
|
205
205
|
);
|
|
206
206
|
} );
|
|
207
207
|
|
|
208
|
+
it( 'should call onFocusRow with event, start and end nodes when pressing End', () => {
|
|
209
|
+
const onFocusRow = jest.fn();
|
|
210
|
+
render( <TestTree onFocusRow={ onFocusRow } /> );
|
|
211
|
+
|
|
212
|
+
screen.getByText( 'Row 1' ).focus();
|
|
213
|
+
|
|
214
|
+
const row1Element = screen.getByText( 'Row 1' ).closest( 'tr' );
|
|
215
|
+
const row3Element = screen.getByText( 'Row 3' ).closest( 'tr' );
|
|
216
|
+
|
|
217
|
+
fireEvent.keyDown( screen.getByText( 'Row 1' ), {
|
|
218
|
+
key: 'End',
|
|
219
|
+
keyCode: END,
|
|
220
|
+
currentTarget: row1Element,
|
|
221
|
+
} );
|
|
222
|
+
|
|
223
|
+
expect( onFocusRow ).toHaveBeenCalledWith(
|
|
224
|
+
expect.objectContaining( { key: 'End', keyCode: END } ),
|
|
225
|
+
row1Element,
|
|
226
|
+
row3Element
|
|
227
|
+
);
|
|
228
|
+
} );
|
|
229
|
+
|
|
208
230
|
it( 'should call onFocusRow with event, start and end nodes when pressing Up Arrow', () => {
|
|
209
231
|
const onFocusRow = jest.fn();
|
|
210
232
|
render( <TestTree onFocusRow={ onFocusRow } /> );
|
|
@@ -227,6 +249,28 @@ describe( 'TreeGrid', () => {
|
|
|
227
249
|
);
|
|
228
250
|
} );
|
|
229
251
|
|
|
252
|
+
it( 'should call onFocusRow with event, start and end nodes when pressing Home', () => {
|
|
253
|
+
const onFocusRow = jest.fn();
|
|
254
|
+
render( <TestTree onFocusRow={ onFocusRow } /> );
|
|
255
|
+
|
|
256
|
+
screen.getByText( 'Row 3' ).focus();
|
|
257
|
+
|
|
258
|
+
const row3Element = screen.getByText( 'Row 3' ).closest( 'tr' );
|
|
259
|
+
const row1Element = screen.getByText( 'Row 1' ).closest( 'tr' );
|
|
260
|
+
|
|
261
|
+
fireEvent.keyDown( screen.getByText( 'Row 3' ), {
|
|
262
|
+
key: 'Home',
|
|
263
|
+
keyCode: HOME,
|
|
264
|
+
currentTarget: row3Element,
|
|
265
|
+
} );
|
|
266
|
+
|
|
267
|
+
expect( onFocusRow ).toHaveBeenCalledWith(
|
|
268
|
+
expect.objectContaining( { key: 'Home', keyCode: HOME } ),
|
|
269
|
+
row3Element,
|
|
270
|
+
row1Element
|
|
271
|
+
);
|
|
272
|
+
} );
|
|
273
|
+
|
|
230
274
|
it( 'should call onFocusRow when shift key is held', () => {
|
|
231
275
|
const onFocusRow = jest.fn();
|
|
232
276
|
render( <TestTree onFocusRow={ onFocusRow } /> );
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
This feature is still experimental. “Experimental” means this is an early implementation subject to drastic and breaking changes.
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
|
-
UnitControl allows the user to set a
|
|
7
|
+
`UnitControl` allows the user to set a numeric quantity as well as a unit (e.g. `px`).
|
|
8
8
|
|
|
9
9
|
## Usage
|
|
10
10
|
|
|
@@ -66,14 +66,12 @@ The position of the label (`top`, `side`, `bottom`, or `edge`).
|
|
|
66
66
|
Callback when the `value` changes.
|
|
67
67
|
|
|
68
68
|
- Required: No
|
|
69
|
-
- Default: `noop`
|
|
70
69
|
|
|
71
70
|
### `onUnitChange`: `UnitControlOnChangeCallback`
|
|
72
71
|
|
|
73
72
|
Callback when the `unit` changes.
|
|
74
73
|
|
|
75
74
|
- Required: No
|
|
76
|
-
- Default: `noop`
|
|
77
75
|
|
|
78
76
|
### `size`: `string`
|
|
79
77
|
|
|
@@ -7,23 +7,23 @@ import type {
|
|
|
7
7
|
ForwardedRef,
|
|
8
8
|
SyntheticEvent,
|
|
9
9
|
ChangeEvent,
|
|
10
|
+
PointerEvent,
|
|
10
11
|
} from 'react';
|
|
11
|
-
import {
|
|
12
|
+
import { omit } from 'lodash';
|
|
12
13
|
import classnames from 'classnames';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* WordPress dependencies
|
|
16
17
|
*/
|
|
18
|
+
import deprecated from '@wordpress/deprecated';
|
|
17
19
|
import { forwardRef, useMemo, useRef, useEffect } from '@wordpress/element';
|
|
18
20
|
import { __ } from '@wordpress/i18n';
|
|
19
|
-
import { ENTER } from '@wordpress/keycodes';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Internal dependencies
|
|
23
24
|
*/
|
|
24
25
|
import type { WordPressComponentProps } from '../ui/context';
|
|
25
26
|
import * as inputControlActionTypes from '../input-control/reducer/actions';
|
|
26
|
-
import { composeStateReducers } from '../input-control/reducer/reducer';
|
|
27
27
|
import { Root, ValueInput } from './styles/unit-control-styles';
|
|
28
28
|
import UnitSelectControl from './unit-select-control';
|
|
29
29
|
import {
|
|
@@ -36,9 +36,16 @@ import { useControlledState } from '../utils/hooks';
|
|
|
36
36
|
import type { UnitControlProps, UnitControlOnChangeCallback } from './types';
|
|
37
37
|
import type { StateReducer } from '../input-control/reducer/state';
|
|
38
38
|
|
|
39
|
-
function
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
function UnforwardedUnitControl(
|
|
40
|
+
unitControlProps: WordPressComponentProps<
|
|
41
|
+
UnitControlProps,
|
|
42
|
+
'input',
|
|
43
|
+
false
|
|
44
|
+
>,
|
|
45
|
+
forwardedRef: ForwardedRef< any >
|
|
46
|
+
) {
|
|
47
|
+
const {
|
|
48
|
+
__unstableStateReducer: stateReducerProp,
|
|
42
49
|
autoComplete = 'off',
|
|
43
50
|
className,
|
|
44
51
|
disabled = false,
|
|
@@ -47,17 +54,24 @@ function UnitControl(
|
|
|
47
54
|
isResetValueOnUnitChange = false,
|
|
48
55
|
isUnitSelectTabbable = true,
|
|
49
56
|
label,
|
|
50
|
-
onChange
|
|
51
|
-
onUnitChange
|
|
57
|
+
onChange: onChangeProp,
|
|
58
|
+
onUnitChange,
|
|
52
59
|
size = 'default',
|
|
53
60
|
style,
|
|
54
61
|
unit: unitProp,
|
|
55
62
|
units: unitsProp = CSS_UNITS,
|
|
56
63
|
value: valueProp,
|
|
57
64
|
...props
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
) {
|
|
65
|
+
} = unitControlProps;
|
|
66
|
+
|
|
67
|
+
if ( 'unit' in unitControlProps ) {
|
|
68
|
+
deprecated( 'UnitControl unit prop', {
|
|
69
|
+
since: '5.6',
|
|
70
|
+
hint: 'The unit should be provided within the `value` prop.',
|
|
71
|
+
version: '6.2',
|
|
72
|
+
} );
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
// The `value` prop, in theory, should not be `null`, but the following line
|
|
62
76
|
// ensures it fallback to `undefined` in case a consumer of `UnitControl`
|
|
63
77
|
// still passes `null` as a `value`.
|
|
@@ -81,7 +95,9 @@ function UnitControl(
|
|
|
81
95
|
);
|
|
82
96
|
|
|
83
97
|
useEffect( () => {
|
|
84
|
-
|
|
98
|
+
if ( parsedUnit !== undefined ) {
|
|
99
|
+
setUnit( parsedUnit );
|
|
100
|
+
}
|
|
85
101
|
}, [ parsedUnit ] );
|
|
86
102
|
|
|
87
103
|
// Stores parsed value for hand-off in state reducer.
|
|
@@ -91,14 +107,18 @@ function UnitControl(
|
|
|
91
107
|
|
|
92
108
|
const handleOnQuantityChange = (
|
|
93
109
|
nextQuantityValue: number | string | undefined,
|
|
94
|
-
changeProps: {
|
|
110
|
+
changeProps: {
|
|
111
|
+
event:
|
|
112
|
+
| ChangeEvent< HTMLInputElement >
|
|
113
|
+
| PointerEvent< HTMLInputElement >;
|
|
114
|
+
}
|
|
95
115
|
) => {
|
|
96
116
|
if (
|
|
97
117
|
nextQuantityValue === '' ||
|
|
98
118
|
typeof nextQuantityValue === 'undefined' ||
|
|
99
119
|
nextQuantityValue === null
|
|
100
120
|
) {
|
|
101
|
-
|
|
121
|
+
onChangeProp?.( '', changeProps );
|
|
102
122
|
return;
|
|
103
123
|
}
|
|
104
124
|
|
|
@@ -113,7 +133,7 @@ function UnitControl(
|
|
|
113
133
|
unit
|
|
114
134
|
).join( '' );
|
|
115
135
|
|
|
116
|
-
|
|
136
|
+
onChangeProp?.( onChangeValue, changeProps );
|
|
117
137
|
};
|
|
118
138
|
|
|
119
139
|
const handleOnUnitChange: UnitControlOnChangeCallback = (
|
|
@@ -128,8 +148,8 @@ function UnitControl(
|
|
|
128
148
|
nextValue = `${ data.default }${ nextUnitValue }`;
|
|
129
149
|
}
|
|
130
150
|
|
|
131
|
-
|
|
132
|
-
onUnitChange( nextUnitValue, changeProps );
|
|
151
|
+
onChangeProp?.( nextValue, changeProps );
|
|
152
|
+
onUnitChange?.( nextUnitValue, changeProps );
|
|
133
153
|
|
|
134
154
|
setUnit( nextUnitValue );
|
|
135
155
|
};
|
|
@@ -157,11 +177,11 @@ function UnitControl(
|
|
|
157
177
|
: undefined;
|
|
158
178
|
const changeProps = { event, data };
|
|
159
179
|
|
|
160
|
-
|
|
180
|
+
onChangeProp?.(
|
|
161
181
|
`${ validParsedQuantity ?? '' }${ validParsedUnit }`,
|
|
162
182
|
changeProps
|
|
163
183
|
);
|
|
164
|
-
onUnitChange( validParsedUnit, changeProps );
|
|
184
|
+
onUnitChange?.( validParsedUnit, changeProps );
|
|
165
185
|
|
|
166
186
|
setUnit( validParsedUnit );
|
|
167
187
|
}
|
|
@@ -170,8 +190,8 @@ function UnitControl(
|
|
|
170
190
|
const handleOnBlur: FocusEventHandler< HTMLInputElement > = mayUpdateUnit;
|
|
171
191
|
|
|
172
192
|
const handleOnKeyDown = ( event: KeyboardEvent< HTMLInputElement > ) => {
|
|
173
|
-
const {
|
|
174
|
-
if (
|
|
193
|
+
const { key } = event;
|
|
194
|
+
if ( key === 'Enter' ) {
|
|
175
195
|
mayUpdateUnit( event );
|
|
176
196
|
}
|
|
177
197
|
};
|
|
@@ -186,6 +206,8 @@ function UnitControl(
|
|
|
186
206
|
* @return The updated state to apply to InputControl
|
|
187
207
|
*/
|
|
188
208
|
const unitControlStateReducer: StateReducer = ( state, action ) => {
|
|
209
|
+
const nextState = { ...state };
|
|
210
|
+
|
|
189
211
|
/*
|
|
190
212
|
* On commits (when pressing ENTER and on blur if
|
|
191
213
|
* isPressEnterToChange is true), if a parse has been performed
|
|
@@ -193,14 +215,24 @@ function UnitControl(
|
|
|
193
215
|
*/
|
|
194
216
|
if ( action.type === inputControlActionTypes.COMMIT ) {
|
|
195
217
|
if ( refParsedQuantity.current !== undefined ) {
|
|
196
|
-
|
|
218
|
+
nextState.value = (
|
|
219
|
+
refParsedQuantity.current ?? ''
|
|
220
|
+
).toString();
|
|
197
221
|
refParsedQuantity.current = undefined;
|
|
198
222
|
}
|
|
199
223
|
}
|
|
200
224
|
|
|
201
|
-
return
|
|
225
|
+
return nextState;
|
|
202
226
|
};
|
|
203
227
|
|
|
228
|
+
let stateReducer: StateReducer = unitControlStateReducer;
|
|
229
|
+
if ( stateReducerProp ) {
|
|
230
|
+
stateReducer = ( state, action ) => {
|
|
231
|
+
const baseState = unitControlStateReducer( state, action );
|
|
232
|
+
return stateReducerProp( baseState, action );
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
204
236
|
const inputSuffix = ! disableUnits ? (
|
|
205
237
|
<UnitSelectControl
|
|
206
238
|
aria-label={ __( 'Select unit' ) }
|
|
@@ -244,17 +276,14 @@ function UnitControl(
|
|
|
244
276
|
suffix={ inputSuffix }
|
|
245
277
|
value={ parsedQuantity ?? '' }
|
|
246
278
|
step={ step }
|
|
247
|
-
__unstableStateReducer={
|
|
248
|
-
unitControlStateReducer,
|
|
249
|
-
stateReducer
|
|
250
|
-
) }
|
|
279
|
+
__unstableStateReducer={ stateReducer }
|
|
251
280
|
/>
|
|
252
281
|
</Root>
|
|
253
282
|
);
|
|
254
283
|
}
|
|
255
284
|
|
|
256
285
|
/**
|
|
257
|
-
* `UnitControl` allows the user to set a
|
|
286
|
+
* `UnitControl` allows the user to set a numeric quantity as well as a unit (e.g. `px`).
|
|
258
287
|
*
|
|
259
288
|
*
|
|
260
289
|
* @example
|
|
@@ -269,7 +298,7 @@ function UnitControl(
|
|
|
269
298
|
* };
|
|
270
299
|
* ```
|
|
271
300
|
*/
|
|
272
|
-
const
|
|
301
|
+
export const UnitControl = forwardRef( UnforwardedUnitControl );
|
|
273
302
|
|
|
274
303
|
export { parseQuantityAndUnitFromRawValue, useCustomUnits } from './utils';
|
|
275
|
-
export default
|
|
304
|
+
export default UnitControl;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentMeta, ComponentStory } from '@storybook/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useState } from '@wordpress/element';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import { UnitControl } from '../';
|
|
15
|
+
import { CSS_UNITS } from '../utils';
|
|
16
|
+
|
|
17
|
+
const meta: ComponentMeta< typeof UnitControl > = {
|
|
18
|
+
component: UnitControl,
|
|
19
|
+
title: 'Components (Experimental)/UnitControl',
|
|
20
|
+
argTypes: {
|
|
21
|
+
__unstableInputWidth: {
|
|
22
|
+
control: { type: 'text' },
|
|
23
|
+
},
|
|
24
|
+
__unstableStateReducer: {
|
|
25
|
+
control: { type: null },
|
|
26
|
+
},
|
|
27
|
+
size: {
|
|
28
|
+
control: { type: 'select' },
|
|
29
|
+
},
|
|
30
|
+
onChange: {
|
|
31
|
+
action: 'onChange',
|
|
32
|
+
control: { type: null },
|
|
33
|
+
},
|
|
34
|
+
onUnitChange: {
|
|
35
|
+
control: { type: null },
|
|
36
|
+
},
|
|
37
|
+
value: {
|
|
38
|
+
control: { type: null },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
parameters: {
|
|
42
|
+
controls: {
|
|
43
|
+
expanded: true,
|
|
44
|
+
},
|
|
45
|
+
docs: { source: { state: 'open' } },
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export default meta;
|
|
49
|
+
|
|
50
|
+
const DefaultTemplate: ComponentStory< typeof UnitControl > = ( {
|
|
51
|
+
onChange,
|
|
52
|
+
...args
|
|
53
|
+
} ) => {
|
|
54
|
+
const [ value, setValue ] = useState< string | undefined >( '10px' );
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div style={ { maxWidth: '100px' } }>
|
|
58
|
+
<UnitControl
|
|
59
|
+
{ ...args }
|
|
60
|
+
value={ value }
|
|
61
|
+
onChange={ ( v, extra ) => {
|
|
62
|
+
setValue( v );
|
|
63
|
+
onChange?.( v, extra );
|
|
64
|
+
} }
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const Default: ComponentStory<
|
|
71
|
+
typeof UnitControl
|
|
72
|
+
> = DefaultTemplate.bind( {} );
|
|
73
|
+
Default.args = {
|
|
74
|
+
label: 'Label',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* If the `isPressEnterToChange` prop is set to `true`, the `onChange` callback
|
|
79
|
+
* will not fire while a new value is typed in the input field (you can verify this
|
|
80
|
+
* behavior by inspecting the console's output).
|
|
81
|
+
*/
|
|
82
|
+
export const PressEnterToChange: ComponentStory<
|
|
83
|
+
typeof UnitControl
|
|
84
|
+
> = DefaultTemplate.bind( {} );
|
|
85
|
+
PressEnterToChange.args = {
|
|
86
|
+
...Default.args,
|
|
87
|
+
isPressEnterToChange: true,
|
|
88
|
+
onChange: ( v ) => {
|
|
89
|
+
// eslint-disable-next-line no-console
|
|
90
|
+
console.log( v );
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Most of `NumberControl`'s props can be passed to `UnitControl`, and they will
|
|
96
|
+
* affect its numeric input field.
|
|
97
|
+
*/
|
|
98
|
+
export const TweakingTheNumberInput: ComponentStory<
|
|
99
|
+
typeof UnitControl
|
|
100
|
+
> = DefaultTemplate.bind( {} );
|
|
101
|
+
TweakingTheNumberInput.args = {
|
|
102
|
+
...Default.args,
|
|
103
|
+
min: 0,
|
|
104
|
+
max: 100,
|
|
105
|
+
step: 'any',
|
|
106
|
+
label: 'Custom label',
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* When only one unit is available, the unit selection dropdown becomes static text.
|
|
111
|
+
*/
|
|
112
|
+
export const WithSingleUnit: ComponentStory<
|
|
113
|
+
typeof UnitControl
|
|
114
|
+
> = DefaultTemplate.bind( {} );
|
|
115
|
+
WithSingleUnit.args = {
|
|
116
|
+
...Default.args,
|
|
117
|
+
units: CSS_UNITS.slice( 0, 1 ),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* It is possible to pass a custom list of units. Every time the unit changes,
|
|
122
|
+
* if the `isResetValueOnUnitChange` is set to `true`, the input's quantity is
|
|
123
|
+
* reset to the new unit's default value.
|
|
124
|
+
*/
|
|
125
|
+
export const WithCustomUnits: ComponentStory< typeof UnitControl > = ( {
|
|
126
|
+
onChange,
|
|
127
|
+
...args
|
|
128
|
+
} ) => {
|
|
129
|
+
const [ value, setValue ] = useState< string | undefined >( '80km' );
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<div style={ { maxWidth: '100px' } }>
|
|
133
|
+
<UnitControl
|
|
134
|
+
{ ...args }
|
|
135
|
+
value={ value }
|
|
136
|
+
onChange={ ( v, extra ) => {
|
|
137
|
+
setValue( v );
|
|
138
|
+
onChange?.( v, extra );
|
|
139
|
+
} }
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
};
|
|
144
|
+
WithCustomUnits.args = {
|
|
145
|
+
...Default.args,
|
|
146
|
+
isResetValueOnUnitChange: true,
|
|
147
|
+
min: 0,
|
|
148
|
+
units: [
|
|
149
|
+
{
|
|
150
|
+
value: 'km',
|
|
151
|
+
label: 'km',
|
|
152
|
+
default: 1,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
value: 'mi',
|
|
156
|
+
label: 'mi',
|
|
157
|
+
default: 1,
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
value: 'm',
|
|
161
|
+
label: 'm',
|
|
162
|
+
default: 1000,
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
value: 'yd',
|
|
166
|
+
label: 'yd',
|
|
167
|
+
default: 1760,
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
};
|