@wordpress/components 28.8.1-next.1f6eadc42.0 → 28.8.1
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 +14 -1
- package/build/box-control/all-input-control.js +1 -2
- package/build/box-control/all-input-control.js.map +1 -1
- package/build/card/card/component.js +2 -2
- package/build/card/card/component.js.map +1 -1
- package/build/card/styles.js +18 -18
- package/build/card/styles.js.map +1 -1
- package/build/combobox-control/index.js +3 -1
- package/build/combobox-control/index.js.map +1 -1
- package/build/combobox-control/types.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/dropdown-menu-v2/styles.js +17 -17
- package/build/dropdown-menu-v2/styles.js.map +1 -1
- package/build/modal/index.js +17 -9
- package/build/modal/index.js.map +1 -1
- package/build/modal/types.js.map +1 -1
- package/build/modal/use-modal-exit-animation.js +75 -0
- package/build/modal/use-modal-exit-animation.js.map +1 -0
- package/build/range-control/styles/range-control-styles.js +28 -28
- package/build/range-control/styles/range-control-styles.js.map +1 -1
- package/build/tabs/styles.js +3 -3
- package/build/tabs/styles.js.map +1 -1
- package/build/utils/config-values.js +4 -5
- package/build/utils/config-values.js.map +1 -1
- package/build-module/box-control/all-input-control.js +2 -2
- package/build-module/box-control/all-input-control.js.map +1 -1
- package/build-module/card/card/component.js +2 -2
- package/build-module/card/card/component.js.map +1 -1
- package/build-module/card/styles.js +18 -18
- package/build-module/card/styles.js.map +1 -1
- package/build-module/combobox-control/index.js +3 -1
- package/build-module/combobox-control/index.js.map +1 -1
- package/build-module/combobox-control/types.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/dropdown-menu-v2/styles.js +17 -17
- package/build-module/dropdown-menu-v2/styles.js.map +1 -1
- package/build-module/modal/index.js +18 -9
- package/build-module/modal/index.js.map +1 -1
- package/build-module/modal/types.js.map +1 -1
- package/build-module/modal/use-modal-exit-animation.js +68 -0
- package/build-module/modal/use-modal-exit-animation.js.map +1 -0
- package/build-module/range-control/styles/range-control-styles.js +28 -28
- package/build-module/range-control/styles/range-control-styles.js.map +1 -1
- package/build-module/tabs/styles.js +3 -3
- package/build-module/tabs/styles.js.map +1 -1
- package/build-module/utils/config-values.js +4 -5
- package/build-module/utils/config-values.js.map +1 -1
- package/build-style/style-rtl.css +50 -6
- package/build-style/style.css +50 -6
- package/build-types/box-control/all-input-control.d.ts.map +1 -1
- package/build-types/button-group/stories/index.story.d.ts +2 -2
- package/build-types/button-group/stories/index.story.d.ts.map +1 -1
- package/build-types/combobox-control/index.d.ts.map +1 -1
- package/build-types/combobox-control/stories/index.story.d.ts +4 -0
- package/build-types/combobox-control/stories/index.story.d.ts.map +1 -1
- package/build-types/combobox-control/types.d.ts +4 -0
- package/build-types/combobox-control/types.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/styles.d.ts.map +1 -1
- package/build-types/modal/index.d.ts.map +1 -1
- package/build-types/modal/types.d.ts +6 -10
- package/build-types/modal/types.d.ts.map +1 -1
- package/build-types/modal/use-modal-exit-animation.d.ts +9 -0
- package/build-types/modal/use-modal-exit-animation.d.ts.map +1 -0
- package/build-types/range-control/styles/range-control-styles.d.ts.map +1 -1
- package/build-types/utils/config-values.d.ts +0 -1
- package/package.json +19 -19
- package/src/box-control/README.md +7 -0
- package/src/box-control/all-input-control.tsx +2 -3
- package/src/button-group/stories/index.story.tsx +10 -15
- package/src/card/card/component.tsx +1 -1
- package/src/card/styles.ts +1 -1
- package/src/card/test/__snapshots__/index.tsx.snap +54 -54
- package/src/combobox-control/README.md +7 -0
- package/src/combobox-control/index.tsx +2 -0
- package/src/combobox-control/test/index.tsx +40 -0
- package/src/combobox-control/types.ts +4 -0
- package/src/custom-select-control-v2/styles.ts +1 -0
- package/src/dropdown-menu-v2/styles.ts +1 -1
- package/src/form-toggle/style.scss +1 -0
- package/src/modal/index.tsx +27 -13
- package/src/modal/style.scss +30 -3
- package/src/modal/types.ts +6 -18
- package/src/modal/use-modal-exit-animation.ts +99 -0
- package/src/popover/style.scss +1 -1
- package/src/range-control/styles/range-control-styles.ts +1 -0
- package/src/resizable-box/style.scss +1 -1
- package/src/snackbar/style.scss +1 -1
- package/src/tabs/styles.ts +1 -1
- package/src/tooltip/style.scss +1 -0
- package/src/utils/config-values.js +4 -5
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -188,6 +188,46 @@ describe.each( [
|
|
|
188
188
|
expect( input ).toHaveValue( targetOption.label );
|
|
189
189
|
} );
|
|
190
190
|
|
|
191
|
+
it( 'calls onFilterValueChange whenever the textbox changes', async () => {
|
|
192
|
+
const user = userEvent.setup();
|
|
193
|
+
const onFilterValueChangeSpy = jest.fn();
|
|
194
|
+
render(
|
|
195
|
+
<Component
|
|
196
|
+
options={ timezones }
|
|
197
|
+
label={ defaultLabelText }
|
|
198
|
+
onFilterValueChange={ onFilterValueChangeSpy }
|
|
199
|
+
/>
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
const input = getInput( defaultLabelText );
|
|
203
|
+
|
|
204
|
+
await user.type( input, 'a' );
|
|
205
|
+
expect( onFilterValueChangeSpy ).toHaveBeenCalledWith( 'a' );
|
|
206
|
+
} );
|
|
207
|
+
|
|
208
|
+
it( 'clears the textbox value if there is no selected value on blur', async () => {
|
|
209
|
+
const user = userEvent.setup();
|
|
210
|
+
const onFilterValueChangeSpy = jest.fn();
|
|
211
|
+
render(
|
|
212
|
+
<Component
|
|
213
|
+
options={ timezones }
|
|
214
|
+
label={ defaultLabelText }
|
|
215
|
+
onFilterValueChange={ onFilterValueChangeSpy }
|
|
216
|
+
/>
|
|
217
|
+
);
|
|
218
|
+
const input = getInput( defaultLabelText );
|
|
219
|
+
|
|
220
|
+
await user.type( input, 'a' );
|
|
221
|
+
expect( input ).toHaveValue( 'a' );
|
|
222
|
+
|
|
223
|
+
// Blur and focus the input.
|
|
224
|
+
await user.tab();
|
|
225
|
+
await user.click( input );
|
|
226
|
+
|
|
227
|
+
expect( input ).toHaveValue( '' );
|
|
228
|
+
expect( onFilterValueChangeSpy ).toHaveBeenLastCalledWith( '' );
|
|
229
|
+
} );
|
|
230
|
+
|
|
191
231
|
it( 'should select the correct option from a search', async () => {
|
|
192
232
|
const user = await userEvent.setup();
|
|
193
233
|
const targetOption = timezones[ 13 ];
|
|
@@ -120,6 +120,7 @@ export const SelectPopover = styled( Ariakit.SelectPopover )`
|
|
|
120
120
|
background-color: ${ COLORS.theme.background };
|
|
121
121
|
border-radius: ${ CONFIG.radiusSmall };
|
|
122
122
|
border: 1px solid ${ COLORS.theme.foreground };
|
|
123
|
+
box-shadow: ${ CONFIG.elevationMedium };
|
|
123
124
|
|
|
124
125
|
/* z-index(".components-popover") */
|
|
125
126
|
z-index: 1000000;
|
|
@@ -37,7 +37,7 @@ const DIVIDER_COLOR = COLORS.theme.gray[ 200 ];
|
|
|
37
37
|
const LIGHTER_TEXT_COLOR = COLORS.theme.gray[ 700 ];
|
|
38
38
|
const LIGHT_BACKGROUND_COLOR = COLORS.theme.gray[ 100 ];
|
|
39
39
|
const TOOLBAR_VARIANT_BORDER_COLOR = COLORS.theme.foreground;
|
|
40
|
-
const DEFAULT_BOX_SHADOW = `0 0 0 ${ CONFIG.borderWidth } ${ DEFAULT_BORDER_COLOR }, ${ CONFIG.
|
|
40
|
+
const DEFAULT_BOX_SHADOW = `0 0 0 ${ CONFIG.borderWidth } ${ DEFAULT_BORDER_COLOR }, ${ CONFIG.elevationMedium }`;
|
|
41
41
|
const TOOLBAR_VARIANT_BOX_SHADOW = `0 0 0 ${ CONFIG.borderWidth } ${ TOOLBAR_VARIANT_BORDER_COLOR }`;
|
|
42
42
|
|
|
43
43
|
const GRID_TEMPLATE_COLS = 'minmax( 0, max-content ) 1fr';
|
|
@@ -60,6 +60,7 @@ $transition-duration: 0.2s;
|
|
|
60
60
|
$transition-duration background-color ease-out;
|
|
61
61
|
@include reduce-motion("transition");
|
|
62
62
|
background-color: $gray-900;
|
|
63
|
+
box-shadow: $elevation-x-small;
|
|
63
64
|
|
|
64
65
|
// Transparent border acts as a fill in Windows High Contrast Mode.
|
|
65
66
|
border: math.div($toggle-thumb-size, 2) solid transparent;
|
package/src/modal/index.tsx
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
-
import type { ForwardedRef, KeyboardEvent, RefObject, UIEvent } from 'react';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* WordPress dependencies
|
|
@@ -38,10 +37,11 @@ import StyleProvider from '../style-provider';
|
|
|
38
37
|
import type { ModalProps } from './types';
|
|
39
38
|
import { withIgnoreIMEEvents } from '../utils/with-ignore-ime-events';
|
|
40
39
|
import { Spacer } from '../spacer';
|
|
40
|
+
import { useModalExitAnimation } from './use-modal-exit-animation';
|
|
41
41
|
|
|
42
42
|
// Used to track and dismiss the prior modal when another opens unless nested.
|
|
43
43
|
type Dismissers = Set<
|
|
44
|
-
RefObject< ModalProps[ 'onRequestClose' ] | undefined >
|
|
44
|
+
React.RefObject< ModalProps[ 'onRequestClose' ] | undefined >
|
|
45
45
|
>;
|
|
46
46
|
const ModalContext = createContext< Dismissers >( new Set() );
|
|
47
47
|
|
|
@@ -50,7 +50,7 @@ const bodyOpenClasses = new Map< string, number >();
|
|
|
50
50
|
|
|
51
51
|
function UnforwardedModal(
|
|
52
52
|
props: ModalProps,
|
|
53
|
-
forwardedRef: ForwardedRef< HTMLDivElement >
|
|
53
|
+
forwardedRef: React.ForwardedRef< HTMLDivElement >
|
|
54
54
|
) {
|
|
55
55
|
const {
|
|
56
56
|
bodyOpenClassName = 'modal-open',
|
|
@@ -70,7 +70,7 @@ function UnforwardedModal(
|
|
|
70
70
|
closeButtonLabel,
|
|
71
71
|
children,
|
|
72
72
|
style,
|
|
73
|
-
overlayClassName,
|
|
73
|
+
overlayClassName: overlayClassnameProp,
|
|
74
74
|
className,
|
|
75
75
|
contentLabel,
|
|
76
76
|
onKeyDown,
|
|
@@ -184,6 +184,9 @@ function UnforwardedModal(
|
|
|
184
184
|
};
|
|
185
185
|
}, [ bodyOpenClassName ] );
|
|
186
186
|
|
|
187
|
+
const { closeModal, frameRef, frameStyle, overlayClassname } =
|
|
188
|
+
useModalExitAnimation();
|
|
189
|
+
|
|
187
190
|
// Calls the isContentScrollable callback when the Modal children container resizes.
|
|
188
191
|
useLayoutEffect( () => {
|
|
189
192
|
if ( ! window.ResizeObserver || ! childrenContainerRef.current ) {
|
|
@@ -200,21 +203,21 @@ function UnforwardedModal(
|
|
|
200
203
|
};
|
|
201
204
|
}, [ isContentScrollable, childrenContainerRef ] );
|
|
202
205
|
|
|
203
|
-
function handleEscapeKeyDown(
|
|
206
|
+
function handleEscapeKeyDown(
|
|
207
|
+
event: React.KeyboardEvent< HTMLDivElement >
|
|
208
|
+
) {
|
|
204
209
|
if (
|
|
205
210
|
shouldCloseOnEsc &&
|
|
206
211
|
( event.code === 'Escape' || event.key === 'Escape' ) &&
|
|
207
212
|
! event.defaultPrevented
|
|
208
213
|
) {
|
|
209
214
|
event.preventDefault();
|
|
210
|
-
|
|
211
|
-
onRequestClose( event );
|
|
212
|
-
}
|
|
215
|
+
closeModal().then( () => onRequestClose( event ) );
|
|
213
216
|
}
|
|
214
217
|
}
|
|
215
218
|
|
|
216
219
|
const onContentContainerScroll = useCallback(
|
|
217
|
-
( e: UIEvent< HTMLDivElement > ) => {
|
|
220
|
+
( e: React.UIEvent< HTMLDivElement > ) => {
|
|
218
221
|
const scrollY = e?.currentTarget?.scrollTop ?? -1;
|
|
219
222
|
|
|
220
223
|
if ( ! hasScrolledContent && scrollY > 0 ) {
|
|
@@ -248,7 +251,7 @@ function UnforwardedModal(
|
|
|
248
251
|
const isSameTarget = target === pressTarget;
|
|
249
252
|
pressTarget = null;
|
|
250
253
|
if ( button === 0 && isSameTarget ) {
|
|
251
|
-
onRequestClose();
|
|
254
|
+
closeModal().then( () => onRequestClose() );
|
|
252
255
|
}
|
|
253
256
|
},
|
|
254
257
|
};
|
|
@@ -259,7 +262,8 @@ function UnforwardedModal(
|
|
|
259
262
|
ref={ useMergeRefs( [ ref, forwardedRef ] ) }
|
|
260
263
|
className={ clsx(
|
|
261
264
|
'components-modal__screen-overlay',
|
|
262
|
-
|
|
265
|
+
overlayClassname,
|
|
266
|
+
overlayClassnameProp
|
|
263
267
|
) }
|
|
264
268
|
onKeyDown={ withIgnoreIMEEvents( handleEscapeKeyDown ) }
|
|
265
269
|
{ ...( shouldCloseOnClickOutside ? overlayPressHandlers : {} ) }
|
|
@@ -271,8 +275,12 @@ function UnforwardedModal(
|
|
|
271
275
|
sizeClass,
|
|
272
276
|
className
|
|
273
277
|
) }
|
|
274
|
-
style={
|
|
278
|
+
style={ {
|
|
279
|
+
...frameStyle,
|
|
280
|
+
...style,
|
|
281
|
+
} }
|
|
275
282
|
ref={ useMergeRefs( [
|
|
283
|
+
frameRef,
|
|
276
284
|
constrainedTabbingRef,
|
|
277
285
|
focusReturnRef,
|
|
278
286
|
focusOnMount !== 'firstContentElement'
|
|
@@ -331,7 +339,13 @@ function UnforwardedModal(
|
|
|
331
339
|
/>
|
|
332
340
|
<Button
|
|
333
341
|
size="small"
|
|
334
|
-
onClick={
|
|
342
|
+
onClick={ (
|
|
343
|
+
event: React.MouseEvent< HTMLButtonElement >
|
|
344
|
+
) =>
|
|
345
|
+
closeModal().then( () =>
|
|
346
|
+
onRequestClose( event )
|
|
347
|
+
)
|
|
348
|
+
}
|
|
335
349
|
icon={ close }
|
|
336
350
|
label={
|
|
337
351
|
closeButtonLabel ||
|
package/src/modal/style.scss
CHANGED
|
@@ -8,8 +8,15 @@
|
|
|
8
8
|
background-color: rgba($black, 0.35);
|
|
9
9
|
z-index: z-index(".components-modal__screen-overlay");
|
|
10
10
|
display: flex;
|
|
11
|
-
// This animates the appearance of the
|
|
12
|
-
@include
|
|
11
|
+
// This animates the appearance of the backdrop.
|
|
12
|
+
@include animation__fade-in();
|
|
13
|
+
|
|
14
|
+
&.is-animating-out {
|
|
15
|
+
// Note: it's important that the fade-out animation doesn't end after the
|
|
16
|
+
// modal frame's disappear animation, because the component will be removed
|
|
17
|
+
// from the DOM when that animation ends.
|
|
18
|
+
@include animation__fade-out($delay: 80ms);
|
|
19
|
+
}
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
// The modal window element.
|
|
@@ -25,10 +32,17 @@
|
|
|
25
32
|
// Have the content element fill the vertical space yet not overflow.
|
|
26
33
|
display: flex;
|
|
27
34
|
// Animate the modal frame/contents appearing on the page.
|
|
28
|
-
animation: components-modal__appear-animation
|
|
35
|
+
animation-name: components-modal__appear-animation;
|
|
36
|
+
animation-duration: var(--modal-frame-animation-duration);
|
|
29
37
|
animation-fill-mode: forwards;
|
|
38
|
+
animation-timing-function: cubic-bezier(0.29, 0, 0, 1);
|
|
30
39
|
@include reduce-motion("animation");
|
|
31
40
|
|
|
41
|
+
.components-modal__screen-overlay.is-animating-out & {
|
|
42
|
+
animation-name: components-modal__disappear-animation;
|
|
43
|
+
animation-timing-function: cubic-bezier(1, 0, 0.2, 1);
|
|
44
|
+
}
|
|
45
|
+
|
|
32
46
|
// Show a centered modal on bigger screens.
|
|
33
47
|
@include break-small() {
|
|
34
48
|
border-radius: $radius-large;
|
|
@@ -88,6 +102,19 @@
|
|
|
88
102
|
}
|
|
89
103
|
}
|
|
90
104
|
|
|
105
|
+
// Note: this animation is also used in the animationend JS event listener.
|
|
106
|
+
// Make sure that the animation name is kept in sync across the two files.
|
|
107
|
+
@keyframes components-modal__disappear-animation {
|
|
108
|
+
from {
|
|
109
|
+
opacity: 1;
|
|
110
|
+
transform: scale(1);
|
|
111
|
+
}
|
|
112
|
+
to {
|
|
113
|
+
opacity: 0;
|
|
114
|
+
transform: scale(0.9);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
91
118
|
// Fix header to the top so it is always there to provide context to the modal
|
|
92
119
|
// if the content needs to be scrolled (for example, on the keyboard shortcuts
|
|
93
120
|
// modal screen).
|
package/src/modal/types.ts
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import type {
|
|
5
|
-
AriaRole,
|
|
6
|
-
CSSProperties,
|
|
7
|
-
ReactNode,
|
|
8
|
-
KeyboardEventHandler,
|
|
9
|
-
KeyboardEvent,
|
|
10
|
-
SyntheticEvent,
|
|
11
|
-
} from 'react';
|
|
12
|
-
|
|
13
1
|
/**
|
|
14
2
|
* WordPress dependencies
|
|
15
3
|
*/
|
|
@@ -42,7 +30,7 @@ export type ModalProps = {
|
|
|
42
30
|
/**
|
|
43
31
|
* The children elements.
|
|
44
32
|
*/
|
|
45
|
-
children: ReactNode;
|
|
33
|
+
children: React.ReactNode;
|
|
46
34
|
/**
|
|
47
35
|
* If this property is added, it will an additional class name to the modal
|
|
48
36
|
* content `div`.
|
|
@@ -77,7 +65,7 @@ export type ModalProps = {
|
|
|
77
65
|
*
|
|
78
66
|
* @default null
|
|
79
67
|
*/
|
|
80
|
-
headerActions?: ReactNode;
|
|
68
|
+
headerActions?: React.ReactNode;
|
|
81
69
|
|
|
82
70
|
/**
|
|
83
71
|
* If this property is added, an icon will be added before the title.
|
|
@@ -108,12 +96,12 @@ export type ModalProps = {
|
|
|
108
96
|
/**
|
|
109
97
|
* Handle the key down on the modal frame `div`.
|
|
110
98
|
*/
|
|
111
|
-
onKeyDown?: KeyboardEventHandler< HTMLDivElement >;
|
|
99
|
+
onKeyDown?: React.KeyboardEventHandler< HTMLDivElement >;
|
|
112
100
|
/**
|
|
113
101
|
* This function is called to indicate that the modal should be closed.
|
|
114
102
|
*/
|
|
115
103
|
onRequestClose: (
|
|
116
|
-
event?: KeyboardEvent< HTMLDivElement > | SyntheticEvent
|
|
104
|
+
event?: React.KeyboardEvent< HTMLDivElement > | React.SyntheticEvent
|
|
117
105
|
) => void;
|
|
118
106
|
/**
|
|
119
107
|
* If this property is added, it will an additional class name to the modal
|
|
@@ -126,7 +114,7 @@ export type ModalProps = {
|
|
|
126
114
|
*
|
|
127
115
|
* @default 'dialog'
|
|
128
116
|
*/
|
|
129
|
-
role?: AriaRole;
|
|
117
|
+
role?: React.AriaRole;
|
|
130
118
|
/**
|
|
131
119
|
* If this property is added, it will determine whether the modal requests
|
|
132
120
|
* to close when a mouse click occurs outside of the modal content.
|
|
@@ -144,7 +132,7 @@ export type ModalProps = {
|
|
|
144
132
|
/**
|
|
145
133
|
* If this property is added, it will be added to the modal frame `div`.
|
|
146
134
|
*/
|
|
147
|
-
style?: CSSProperties;
|
|
135
|
+
style?: React.CSSProperties;
|
|
148
136
|
/**
|
|
149
137
|
* This property is used as the modal header's title.
|
|
150
138
|
*
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useReducedMotion } from '@wordpress/compose';
|
|
5
|
+
import { useCallback, useRef, useState } from '@wordpress/element';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { CONFIG } from '../utils';
|
|
11
|
+
import warning from '@wordpress/warning';
|
|
12
|
+
|
|
13
|
+
// Animation duration (ms) extracted to JS in order to be used on a setTimeout.
|
|
14
|
+
const FRAME_ANIMATION_DURATION = CONFIG.transitionDuration;
|
|
15
|
+
const FRAME_ANIMATION_DURATION_NUMBER = Number.parseInt(
|
|
16
|
+
CONFIG.transitionDuration
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const EXIT_ANIMATION_NAME = 'components-modal__disappear-animation';
|
|
20
|
+
|
|
21
|
+
export function useModalExitAnimation() {
|
|
22
|
+
const frameRef = useRef< HTMLDivElement >();
|
|
23
|
+
const [ isAnimatingOut, setIsAnimatingOut ] = useState( false );
|
|
24
|
+
const isReducedMotion = useReducedMotion();
|
|
25
|
+
|
|
26
|
+
const closeModal = useCallback(
|
|
27
|
+
() =>
|
|
28
|
+
new Promise< void >( ( closeModalResolve ) => {
|
|
29
|
+
// Grab a "stable" reference of the frame element, since
|
|
30
|
+
// the value held by the react ref might change at runtime.
|
|
31
|
+
const frameEl = frameRef.current;
|
|
32
|
+
|
|
33
|
+
if ( isReducedMotion ) {
|
|
34
|
+
closeModalResolve();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if ( ! frameEl ) {
|
|
39
|
+
warning(
|
|
40
|
+
"wp.components.Modal: the Modal component can't be closed with an exit animation because of a missing reference to the modal frame element."
|
|
41
|
+
);
|
|
42
|
+
closeModalResolve();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let handleAnimationEnd:
|
|
47
|
+
| undefined
|
|
48
|
+
| ( ( e: AnimationEvent ) => void );
|
|
49
|
+
|
|
50
|
+
const startAnimation = () =>
|
|
51
|
+
new Promise< void >( ( animationResolve ) => {
|
|
52
|
+
handleAnimationEnd = ( e: AnimationEvent ) => {
|
|
53
|
+
if ( e.animationName === EXIT_ANIMATION_NAME ) {
|
|
54
|
+
animationResolve();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
frameEl.addEventListener(
|
|
59
|
+
'animationend',
|
|
60
|
+
handleAnimationEnd
|
|
61
|
+
);
|
|
62
|
+
setIsAnimatingOut( true );
|
|
63
|
+
} );
|
|
64
|
+
const animationTimeout = () =>
|
|
65
|
+
new Promise< void >( ( timeoutResolve ) => {
|
|
66
|
+
setTimeout(
|
|
67
|
+
() => timeoutResolve(),
|
|
68
|
+
// Allow an extra 20% of the animation duration for the
|
|
69
|
+
// animationend event to fire, in case the animation frame is
|
|
70
|
+
// slightly delayes by some other events in the event loop.
|
|
71
|
+
FRAME_ANIMATION_DURATION_NUMBER * 1.2
|
|
72
|
+
);
|
|
73
|
+
} );
|
|
74
|
+
|
|
75
|
+
Promise.race( [ startAnimation(), animationTimeout() ] ).then(
|
|
76
|
+
() => {
|
|
77
|
+
if ( handleAnimationEnd ) {
|
|
78
|
+
frameEl.removeEventListener(
|
|
79
|
+
'animationend',
|
|
80
|
+
handleAnimationEnd
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
setIsAnimatingOut( false );
|
|
84
|
+
closeModalResolve();
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
} ),
|
|
88
|
+
[ isReducedMotion ]
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
overlayClassname: isAnimatingOut ? 'is-animating-out' : undefined,
|
|
93
|
+
frameRef,
|
|
94
|
+
frameStyle: {
|
|
95
|
+
'--modal-frame-animation-duration': `${ FRAME_ANIMATION_DURATION }`,
|
|
96
|
+
},
|
|
97
|
+
closeModal,
|
|
98
|
+
};
|
|
99
|
+
}
|
package/src/popover/style.scss
CHANGED
|
@@ -22,7 +22,7 @@ $shadow-popover-border-top-only-alternate: 0 #{-$border-width} 0 $gray-900;
|
|
|
22
22
|
|
|
23
23
|
.components-popover__content {
|
|
24
24
|
background: $white;
|
|
25
|
-
box-shadow: $shadow-popover-border-default, $elevation-
|
|
25
|
+
box-shadow: $shadow-popover-border-default, $elevation-medium;
|
|
26
26
|
border-radius: $radius-medium;
|
|
27
27
|
box-sizing: border-box;
|
|
28
28
|
width: min-content;
|
|
@@ -35,7 +35,7 @@ $resize-handler-container-size: $resize-handler-size + ($grid-unit-05 * 2); // M
|
|
|
35
35
|
top: calc(50% - #{ceil($resize-handler-size * 0.5)});
|
|
36
36
|
right: calc(50% - #{ceil($resize-handler-size * 0.5)});
|
|
37
37
|
|
|
38
|
-
box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) $components-color-accent;
|
|
38
|
+
box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) $components-color-accent, $elevation-x-small;
|
|
39
39
|
// Only visible in Windows High Contrast mode.
|
|
40
40
|
outline: 2px solid transparent;
|
|
41
41
|
}
|
package/src/snackbar/style.scss
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
background: rgba($black, 0.85); // Emulates #1e1e1e closely.
|
|
5
5
|
backdrop-filter: blur($grid-unit-20) saturate(180%);
|
|
6
6
|
border-radius: $radius-medium;
|
|
7
|
-
box-shadow: $elevation-
|
|
7
|
+
box-shadow: $elevation-small;
|
|
8
8
|
color: $white;
|
|
9
9
|
padding: $grid-unit-15 ($grid-unit-05 * 5);
|
|
10
10
|
width: 100%;
|
package/src/tabs/styles.ts
CHANGED
|
@@ -76,7 +76,7 @@ export const TabListWrapper = styled.div`
|
|
|
76
76
|
top: 0;
|
|
77
77
|
left: 0;
|
|
78
78
|
width: 100%;
|
|
79
|
-
|
|
79
|
+
height: calc( var( --antialiasing-factor ) * 1px );
|
|
80
80
|
transform: translateY( calc( var( --indicator-top ) * 1px ) )
|
|
81
81
|
scaleY(
|
|
82
82
|
calc( var( --indicator-height ) / var( --antialiasing-factor ) )
|
package/src/tooltip/style.scss
CHANGED
|
@@ -68,15 +68,14 @@ export default Object.assign( {}, CONTROL_PROPS, TOGGLE_GROUP_CONTROL_PROPS, {
|
|
|
68
68
|
fontWeight: 'normal',
|
|
69
69
|
fontWeightHeading: '600',
|
|
70
70
|
gridBase: '4px',
|
|
71
|
-
cardBorderRadius: '2px',
|
|
72
71
|
cardPaddingXSmall: `${ space( 2 ) }`,
|
|
73
72
|
cardPaddingSmall: `${ space( 4 ) }`,
|
|
74
73
|
cardPaddingMedium: `${ space( 4 ) } ${ space( 6 ) }`,
|
|
75
74
|
cardPaddingLarge: `${ space( 6 ) } ${ space( 8 ) }`,
|
|
76
|
-
elevationXSmall: `0
|
|
77
|
-
elevationSmall: `0
|
|
78
|
-
elevationMedium: `0 0
|
|
79
|
-
elevationLarge: `0
|
|
75
|
+
elevationXSmall: `0 1px 1px rgba(0, 0, 0, 0.03), 0 1px 2px rgba(0, 0, 0, 0.02), 0 3px 3px rgba(0, 0, 0, 0.02), 0 4px 4px rgba(0, 0, 0, 0.01)`,
|
|
76
|
+
elevationSmall: `0 1px 2px rgba(0, 0, 0, 0.05), 0 2px 3px rgba(0, 0, 0, 0.04), 0 6px 6px rgba(0, 0, 0, 0.03), 0 8px 8px rgba(0, 0, 0, 0.02)`,
|
|
77
|
+
elevationMedium: `0 2px 3px rgba(0, 0, 0, 0.05), 0 4px 5px rgba(0, 0, 0, 0.04), 0 12px 12px rgba(0, 0, 0, 0.03), 0 16px 16px rgba(0, 0, 0, 0.02)`,
|
|
78
|
+
elevationLarge: `0 5px 15px rgba(0, 0, 0, 0.08), 0 15px 27px rgba(0, 0, 0, 0.07), 0 30px 36px rgba(0, 0, 0, 0.04), 0 50px 43px rgba(0, 0, 0, 0.02)`,
|
|
80
79
|
surfaceBackgroundColor: COLORS.white,
|
|
81
80
|
surfaceBackgroundSubtleColor: '#F3F3F3',
|
|
82
81
|
surfaceBackgroundTintColor: '#F5F5F5',
|