@wordpress/components 19.3.0 → 19.4.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 +27 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +8 -4
- package/build/base-field/hook.js +1 -1
- package/build/base-field/hook.js.map +1 -1
- package/build/button/deprecated.js +2 -1
- package/build/button/deprecated.js.map +1 -1
- package/build/button/index.js +2 -1
- package/build/button/index.js.map +1 -1
- package/build/card/card/component.js +1 -1
- package/build/card/card/component.js.map +1 -1
- package/build/card/card/hook.js +1 -1
- package/build/card/card/hook.js.map +1 -1
- package/build/card/card-body/hook.js +1 -1
- package/build/card/card-body/hook.js.map +1 -1
- package/build/card/card-divider/hook.js +1 -1
- package/build/card/card-divider/hook.js.map +1 -1
- package/build/card/card-footer/hook.js +1 -1
- package/build/card/card-footer/hook.js.map +1 -1
- package/build/card/card-header/hook.js +1 -1
- package/build/card/card-header/hook.js.map +1 -1
- package/build/card/card-media/hook.js +1 -1
- package/build/card/card-media/hook.js.map +1 -1
- package/build/circular-option-picker/index.js +2 -0
- package/build/circular-option-picker/index.js.map +1 -1
- package/build/color-indicator/index.js +2 -0
- package/build/color-indicator/index.js.map +1 -1
- package/build/color-palette/index.js +2 -0
- package/build/color-palette/index.js.map +1 -1
- package/build/color-picker/color-display.js.map +1 -1
- package/build/color-picker/color-input.js.map +1 -1
- package/build/color-picker/component.js +1 -1
- package/build/color-picker/component.js.map +1 -1
- package/build/color-picker/use-deprecated-props.js +2 -0
- package/build/color-picker/use-deprecated-props.js.map +1 -1
- package/build/date-time/time.js +1 -1
- package/build/date-time/time.js.map +1 -1
- package/build/dropdown/index.js +3 -3
- package/build/dropdown/index.js.map +1 -1
- package/build/elevation/hook.js +5 -5
- package/build/elevation/hook.js.map +1 -1
- package/build/flex/flex/hook.js +4 -4
- package/build/flex/flex/hook.js.map +1 -1
- package/build/grid/hook.js +2 -2
- package/build/grid/hook.js.map +1 -1
- package/build/item-group/item/hook.js +1 -1
- package/build/item-group/item/hook.js.map +1 -1
- package/build/mobile/inserter-button/index.native.js +3 -3
- package/build/mobile/inserter-button/index.native.js.map +1 -1
- package/build/mobile/inserter-button/sparkles.js +25 -0
- package/build/mobile/inserter-button/sparkles.js.map +1 -0
- package/build/modal/index.js +1 -12
- package/build/modal/index.js.map +1 -1
- package/build/navigator/context.js +2 -2
- package/build/navigator/context.js.map +1 -1
- package/build/navigator/navigator-provider/component.js +18 -25
- package/build/navigator/navigator-provider/component.js.map +1 -1
- package/build/navigator/navigator-screen/component.js +39 -13
- package/build/navigator/navigator-screen/component.js.map +1 -1
- package/build/navigator/use-navigator.js +4 -4
- package/build/navigator/use-navigator.js.map +1 -1
- package/build/placeholder/index.js +4 -4
- package/build/placeholder/index.js.map +1 -1
- package/build/scrollable/hook.js +1 -1
- package/build/scrollable/hook.js.map +1 -1
- package/build/slot-fill/bubbles-virtually/fill.js +11 -2
- package/build/slot-fill/bubbles-virtually/fill.js.map +1 -1
- package/build/spinner/index.js +44 -5
- package/build/spinner/index.js.map +1 -1
- package/build/spinner/styles.js +56 -0
- package/build/spinner/styles.js.map +1 -0
- package/build/surface/hook.js +1 -1
- package/build/surface/hook.js.map +1 -1
- package/build/text/hook.js +5 -5
- package/build/text/hook.js.map +1 -1
- package/build/tip/index.js +4 -8
- package/build/tip/index.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control/component.js +1 -1
- package/build/toggle-group-control/toggle-group-control/component.js.map +1 -1
- package/build/tools-panel/tools-panel/hook.js +7 -7
- package/build/tools-panel/tools-panel/hook.js.map +1 -1
- package/build/tools-panel/tools-panel-header/hook.js +3 -3
- package/build/tools-panel/tools-panel-header/hook.js.map +1 -1
- package/build/tools-panel/tools-panel-item/hook.js +1 -1
- package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
- package/build/tree-grid/index.js +13 -6
- package/build/tree-grid/index.js.map +1 -1
- package/build/truncate/hook.js +2 -2
- package/build/truncate/hook.js.map +1 -1
- package/build/utils/config-values.js +1 -1
- package/build/utils/config-values.js.map +1 -1
- package/build-module/base-field/hook.js +1 -1
- package/build-module/base-field/hook.js.map +1 -1
- package/build-module/button/deprecated.js +2 -1
- package/build-module/button/deprecated.js.map +1 -1
- package/build-module/button/index.js +2 -1
- package/build-module/button/index.js.map +1 -1
- package/build-module/card/card/component.js +1 -1
- package/build-module/card/card/component.js.map +1 -1
- package/build-module/card/card/hook.js +1 -1
- package/build-module/card/card/hook.js.map +1 -1
- package/build-module/card/card-body/hook.js +1 -1
- package/build-module/card/card-body/hook.js.map +1 -1
- package/build-module/card/card-divider/hook.js +1 -1
- package/build-module/card/card-divider/hook.js.map +1 -1
- package/build-module/card/card-footer/hook.js +1 -1
- package/build-module/card/card-footer/hook.js.map +1 -1
- package/build-module/card/card-header/hook.js +1 -1
- package/build-module/card/card-header/hook.js.map +1 -1
- package/build-module/card/card-media/hook.js +1 -1
- package/build-module/card/card-media/hook.js.map +1 -1
- package/build-module/circular-option-picker/index.js +1 -0
- package/build-module/circular-option-picker/index.js.map +1 -1
- package/build-module/color-indicator/index.js +1 -0
- package/build-module/color-indicator/index.js.map +1 -1
- package/build-module/color-palette/index.js +1 -0
- package/build-module/color-palette/index.js.map +1 -1
- package/build-module/color-picker/color-display.js.map +1 -1
- package/build-module/color-picker/color-input.js.map +1 -1
- package/build-module/color-picker/component.js +1 -1
- package/build-module/color-picker/component.js.map +1 -1
- package/build-module/color-picker/use-deprecated-props.js +2 -0
- package/build-module/color-picker/use-deprecated-props.js.map +1 -1
- package/build-module/date-time/time.js +1 -1
- package/build-module/date-time/time.js.map +1 -1
- package/build-module/dropdown/index.js +3 -3
- package/build-module/dropdown/index.js.map +1 -1
- package/build-module/elevation/hook.js +5 -5
- package/build-module/elevation/hook.js.map +1 -1
- package/build-module/flex/flex/hook.js +4 -4
- package/build-module/flex/flex/hook.js.map +1 -1
- package/build-module/grid/hook.js +2 -2
- package/build-module/grid/hook.js.map +1 -1
- package/build-module/item-group/item/hook.js +1 -1
- package/build-module/item-group/item/hook.js.map +1 -1
- package/build-module/mobile/inserter-button/index.native.js +1 -1
- package/build-module/mobile/inserter-button/index.native.js.map +1 -1
- package/build-module/mobile/inserter-button/sparkles.js +16 -0
- package/build-module/mobile/inserter-button/sparkles.js.map +1 -0
- package/build-module/modal/index.js +1 -11
- package/build-module/modal/index.js.map +1 -1
- package/build-module/navigator/context.js +2 -2
- package/build-module/navigator/context.js.map +1 -1
- package/build-module/navigator/navigator-provider/component.js +18 -25
- package/build-module/navigator/navigator-provider/component.js.map +1 -1
- package/build-module/navigator/navigator-screen/component.js +39 -15
- package/build-module/navigator/navigator-screen/component.js.map +1 -1
- package/build-module/navigator/use-navigator.js +4 -4
- package/build-module/navigator/use-navigator.js.map +1 -1
- package/build-module/placeholder/index.js +4 -4
- package/build-module/placeholder/index.js.map +1 -1
- package/build-module/scrollable/hook.js +1 -1
- package/build-module/scrollable/hook.js.map +1 -1
- package/build-module/slot-fill/bubbles-virtually/fill.js +11 -2
- package/build-module/slot-fill/bubbles-virtually/fill.js.map +1 -1
- package/build-module/spinner/index.js +40 -5
- package/build-module/spinner/index.js.map +1 -1
- package/build-module/spinner/styles.js +49 -0
- package/build-module/spinner/styles.js.map +1 -0
- package/build-module/surface/hook.js +1 -1
- package/build-module/surface/hook.js.map +1 -1
- package/build-module/text/hook.js +5 -5
- package/build-module/text/hook.js.map +1 -1
- package/build-module/tip/index.js +4 -8
- package/build-module/tip/index.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control/component.js +1 -1
- package/build-module/toggle-group-control/toggle-group-control/component.js.map +1 -1
- package/build-module/tools-panel/tools-panel/hook.js +7 -7
- package/build-module/tools-panel/tools-panel/hook.js.map +1 -1
- package/build-module/tools-panel/tools-panel-header/hook.js +3 -3
- package/build-module/tools-panel/tools-panel-header/hook.js.map +1 -1
- package/build-module/tools-panel/tools-panel-item/hook.js +1 -1
- package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
- package/build-module/tree-grid/index.js +12 -6
- package/build-module/tree-grid/index.js.map +1 -1
- package/build-module/truncate/hook.js +2 -2
- package/build-module/truncate/hook.js.map +1 -1
- package/build-module/utils/config-values.js +1 -1
- package/build-module/utils/config-values.js.map +1 -1
- package/build-style/style-rtl.css +12 -2
- package/build-style/style.css +12 -2
- package/build-types/button/index.d.ts.map +1 -1
- package/build-types/circular-option-picker/index.d.ts +31 -0
- package/build-types/circular-option-picker/index.d.ts.map +1 -0
- package/build-types/color-palette/index.d.ts +16 -0
- package/build-types/color-palette/index.d.ts.map +1 -0
- package/build-types/color-palette/styles.d.ts +8 -0
- package/build-types/color-palette/styles.d.ts.map +1 -0
- package/build-types/color-picker/color-display.d.ts +14 -0
- package/build-types/color-picker/color-display.d.ts.map +1 -0
- package/build-types/color-picker/color-input.d.ts +14 -0
- package/build-types/color-picker/color-input.d.ts.map +1 -0
- package/build-types/color-picker/component.d.ts +11 -0
- package/build-types/color-picker/component.d.ts.map +1 -0
- package/build-types/color-picker/hex-input.d.ts +13 -0
- package/build-types/color-picker/hex-input.d.ts.map +1 -0
- package/build-types/color-picker/hsl-input.d.ts +13 -0
- package/build-types/color-picker/hsl-input.d.ts.map +1 -0
- package/build-types/color-picker/index.d.ts +5 -0
- package/build-types/color-picker/index.d.ts.map +1 -0
- package/build-types/color-picker/input-with-slider.d.ts +12 -0
- package/build-types/color-picker/input-with-slider.d.ts.map +1 -0
- package/build-types/color-picker/legacy-adapter.d.ts +6 -0
- package/build-types/color-picker/legacy-adapter.d.ts.map +1 -0
- package/build-types/color-picker/picker.d.ts +10 -0
- package/build-types/color-picker/picker.d.ts.map +1 -0
- package/build-types/color-picker/rgb-input.d.ts +13 -0
- package/build-types/color-picker/rgb-input.d.ts.map +1 -0
- package/build-types/color-picker/styles.d.ts +76 -0
- package/build-types/color-picker/styles.d.ts.map +1 -0
- package/build-types/color-picker/types.d.ts +2 -0
- package/build-types/color-picker/types.d.ts.map +1 -0
- package/build-types/color-picker/use-deprecated-props.d.ts +49 -0
- package/build-types/color-picker/use-deprecated-props.d.ts.map +1 -0
- package/build-types/dropdown/index.d.ts +1 -13
- package/build-types/dropdown/index.d.ts.map +1 -1
- package/build-types/elevation/hook.d.ts.map +1 -1
- package/build-types/flex/flex/hook.d.ts.map +1 -1
- package/build-types/grid/hook.d.ts.map +1 -1
- package/build-types/navigator/navigator-provider/component.d.ts +4 -4
- package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
- package/build-types/navigator/navigator-screen/component.d.ts +4 -4
- package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
- package/build-types/navigator/types.d.ts +5 -3
- package/build-types/navigator/types.d.ts.map +1 -1
- package/build-types/resizable-box/index.d.ts +1 -1
- package/build-types/resizable-box/resize-tooltip/index.d.ts +1 -1
- package/build-types/slot-fill/bubbles-virtually/fill.d.ts.map +1 -1
- package/build-types/spinner/index.d.ts +18 -1
- package/build-types/spinner/index.d.ts.map +1 -1
- package/build-types/spinner/styles.d.ts +13 -0
- package/build-types/spinner/styles.d.ts.map +1 -0
- package/build-types/surface/hook.d.ts.map +1 -1
- package/build-types/text/hook.d.ts.map +1 -1
- package/build-types/tip/index.d.ts.map +1 -1
- package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
- package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
- package/build-types/unit-control/index.d.ts +3 -2
- package/build-types/unit-control/index.d.ts.map +1 -1
- package/build-types/unit-control/types.d.ts +2 -1
- package/build-types/unit-control/types.d.ts.map +1 -1
- package/build-types/utils/config-values.d.ts +1 -1
- package/package.json +16 -17
- package/src/base-field/hook.js +1 -1
- package/src/button/deprecated.js +1 -0
- package/src/button/index.js +1 -0
- package/src/card/card/component.js +1 -1
- package/src/card/card/hook.js +1 -1
- package/src/card/card-body/hook.js +1 -1
- package/src/card/card-divider/hook.js +1 -1
- package/src/card/card-footer/hook.js +1 -1
- package/src/card/card-header/hook.js +1 -1
- package/src/card/card-media/hook.js +1 -1
- package/src/circular-option-picker/index.js +1 -0
- package/src/color-indicator/index.js +2 -0
- package/src/color-palette/index.js +1 -0
- package/src/color-palette/test/__snapshots__/index.js.snap +0 -1
- package/src/color-picker/color-display.tsx +1 -1
- package/src/color-picker/color-input.tsx +1 -1
- package/src/color-picker/component.tsx +1 -1
- package/src/color-picker/use-deprecated-props.ts +2 -0
- package/src/combobox-control/stories/index.js +6 -2
- package/src/combobox-control/style.scss +2 -2
- package/src/date-time/README.md +4 -4
- package/src/date-time/test/time.js +2 -2
- package/src/date-time/time.js +2 -2
- package/src/dropdown/index.js +14 -13
- package/src/elevation/hook.js +1 -0
- package/src/flex/flex/hook.js +1 -0
- package/src/grid/hook.js +1 -0
- package/src/item-group/item/hook.ts +1 -1
- package/src/item-group/stories/index.js +2 -2
- package/src/mobile/inserter-button/index.native.js +1 -2
- package/src/mobile/inserter-button/sparkles.js +15 -0
- package/src/mobile/link-settings/test/edit.native.js +5 -5
- package/src/modal/index.js +1 -10
- package/src/navigator/context.ts +2 -2
- package/src/navigator/navigator-provider/README.md +11 -9
- package/src/navigator/navigator-provider/component.tsx +16 -25
- package/src/navigator/navigator-screen/component.tsx +55 -15
- package/src/navigator/stories/index.js +19 -5
- package/src/navigator/test/index.js +77 -25
- package/src/navigator/types.ts +5 -3
- package/src/navigator/use-navigator.ts +3 -3
- package/src/placeholder/index.js +8 -6
- package/src/placeholder/style.scss +12 -0
- package/src/placeholder/test/index.js +18 -1
- package/src/scrollable/hook.js +1 -1
- package/src/slot-fill/bubbles-virtually/fill.js +12 -1
- package/src/spinner/README.md +10 -10
- package/src/spinner/index.js +42 -3
- package/src/spinner/stories/index.js +36 -3
- package/src/spinner/styles.js +47 -0
- package/src/surface/hook.js +1 -0
- package/src/text/hook.js +1 -0
- package/src/tip/index.js +2 -4
- package/src/toggle-group-control/toggle-group-control/component.tsx +1 -1
- package/src/tools-panel/stories/index.js +20 -1
- package/src/tools-panel/test/__snapshots__/index.js.snap +0 -1
- package/src/tools-panel/test/index.js +31 -1
- package/src/tools-panel/tools-panel/hook.ts +14 -9
- package/src/tools-panel/tools-panel-header/hook.ts +3 -3
- package/src/tools-panel/tools-panel-item/hook.ts +1 -0
- package/src/tree-grid/index.js +19 -5
- package/src/truncate/hook.js +1 -1
- package/src/unit-control/types.ts +2 -1
- package/src/utils/config-values.js +1 -1
- package/src/utils/hooks/stories/use-cx.js +121 -44
- package/tsconfig.json +3 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/build/spinner/styles/spinner-styles.js +0 -40
- package/build/spinner/styles/spinner-styles.js.map +0 -1
- package/build-module/spinner/styles/spinner-styles.js +0 -28
- package/build-module/spinner/styles/spinner-styles.js.map +0 -1
- package/build-types/spinner/styles/spinner-styles.d.ts +0 -5
- package/build-types/spinner/styles/spinner-styles.d.ts.map +0 -1
- package/src/spinner/styles/spinner-styles.js +0 -47
- package/src/ui/visually-hidden/README.md +0 -21
|
@@ -42,37 +42,25 @@ function NavigatorProvider(
|
|
|
42
42
|
>( [
|
|
43
43
|
{
|
|
44
44
|
path: initialPath,
|
|
45
|
-
isBack: false,
|
|
46
|
-
isInitial: true,
|
|
47
45
|
},
|
|
48
46
|
] );
|
|
49
47
|
|
|
50
|
-
const
|
|
51
|
-
( path, options ) => {
|
|
52
|
-
// Force the `isBack` flag to `false` when navigating forward on both the
|
|
53
|
-
// previous and the new location.
|
|
54
|
-
// Also force the `isInitial` flag to `false` for the new location, to make
|
|
55
|
-
// sure it doesn't get overridden by mistake.
|
|
48
|
+
const goTo: NavigatorContextType[ 'goTo' ] = useCallback(
|
|
49
|
+
( path, options = {} ) => {
|
|
56
50
|
setLocationHistory( [
|
|
57
|
-
...locationHistory
|
|
58
|
-
{
|
|
59
|
-
...locationHistory[ locationHistory.length - 1 ],
|
|
60
|
-
isBack: false,
|
|
61
|
-
},
|
|
51
|
+
...locationHistory,
|
|
62
52
|
{
|
|
63
53
|
...options,
|
|
64
54
|
path,
|
|
65
55
|
isBack: false,
|
|
66
|
-
isInitial: false,
|
|
67
56
|
},
|
|
68
57
|
] );
|
|
69
58
|
},
|
|
70
59
|
[ locationHistory ]
|
|
71
60
|
);
|
|
72
61
|
|
|
73
|
-
const
|
|
62
|
+
const goBack: NavigatorContextType[ 'goBack' ] = useCallback( () => {
|
|
74
63
|
if ( locationHistory.length > 1 ) {
|
|
75
|
-
// Force the `isBack` flag to `true` when navigating back.
|
|
76
64
|
setLocationHistory( [
|
|
77
65
|
...locationHistory.slice( 0, -2 ),
|
|
78
66
|
{
|
|
@@ -85,18 +73,21 @@ function NavigatorProvider(
|
|
|
85
73
|
|
|
86
74
|
const navigatorContextValue: NavigatorContextType = useMemo(
|
|
87
75
|
() => ( {
|
|
88
|
-
location:
|
|
89
|
-
|
|
90
|
-
|
|
76
|
+
location: {
|
|
77
|
+
...locationHistory[ locationHistory.length - 1 ],
|
|
78
|
+
isInitial: locationHistory.length === 1,
|
|
79
|
+
},
|
|
80
|
+
goTo,
|
|
81
|
+
goBack,
|
|
91
82
|
} ),
|
|
92
|
-
[ locationHistory,
|
|
83
|
+
[ locationHistory, goTo, goBack ]
|
|
93
84
|
);
|
|
94
85
|
|
|
95
86
|
const cx = useCx();
|
|
96
87
|
const classes = useMemo(
|
|
97
88
|
// Prevents horizontal overflow while animating screen transitions
|
|
98
89
|
() => cx( css( { overflowX: 'hidden' } ), className ),
|
|
99
|
-
[ className ]
|
|
90
|
+
[ className, cx ]
|
|
100
91
|
);
|
|
101
92
|
|
|
102
93
|
return (
|
|
@@ -120,19 +111,19 @@ function NavigatorProvider(
|
|
|
120
111
|
* } from '@wordpress/components';
|
|
121
112
|
*
|
|
122
113
|
* function NavigatorButton( { path, ...props } ) {
|
|
123
|
-
* const {
|
|
114
|
+
* const { goTo } = useNavigator();
|
|
124
115
|
* return (
|
|
125
116
|
* <Button
|
|
126
117
|
* variant="primary"
|
|
127
|
-
* onClick={ () =>
|
|
118
|
+
* onClick={ () => goTo( path ) }
|
|
128
119
|
* { ...props }
|
|
129
120
|
* />
|
|
130
121
|
* );
|
|
131
122
|
* }
|
|
132
123
|
*
|
|
133
124
|
* function NavigatorBackButton( props ) {
|
|
134
|
-
* const {
|
|
135
|
-
* return <Button variant="secondary" onClick={ () =>
|
|
125
|
+
* const { goBack } = useNavigator();
|
|
126
|
+
* return <Button variant="secondary" onClick={ () => goBack() } { ...props } />;
|
|
136
127
|
* }
|
|
137
128
|
*
|
|
138
129
|
* const MyNavigation = () => (
|
|
@@ -9,8 +9,13 @@ import { css } from '@emotion/react';
|
|
|
9
9
|
/**
|
|
10
10
|
* WordPress dependencies
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { focus } from '@wordpress/dom';
|
|
13
|
+
import { useContext, useEffect, useMemo, useRef } from '@wordpress/element';
|
|
14
|
+
import {
|
|
15
|
+
useReducedMotion,
|
|
16
|
+
useMergeRefs,
|
|
17
|
+
usePrevious,
|
|
18
|
+
} from '@wordpress/compose';
|
|
14
19
|
import { isRTL } from '@wordpress/i18n';
|
|
15
20
|
|
|
16
21
|
/**
|
|
@@ -47,7 +52,9 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) {
|
|
|
47
52
|
const prefersReducedMotion = useReducedMotion();
|
|
48
53
|
const { location } = useContext( NavigatorContext );
|
|
49
54
|
const isMatch = location.path === path;
|
|
50
|
-
const
|
|
55
|
+
const wrapperRef = useRef< HTMLDivElement >( null );
|
|
56
|
+
|
|
57
|
+
const previousLocation = usePrevious( location );
|
|
51
58
|
|
|
52
59
|
const cx = useCx();
|
|
53
60
|
const classes = useMemo(
|
|
@@ -61,15 +68,44 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) {
|
|
|
61
68
|
} ),
|
|
62
69
|
className
|
|
63
70
|
),
|
|
64
|
-
[ className ]
|
|
71
|
+
[ className, cx ]
|
|
65
72
|
);
|
|
66
73
|
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
const [ hasPathChanged, setHasPathChanged ] = useState( false );
|
|
74
|
+
// Focus restoration
|
|
75
|
+
const isInitialLocation = location.isInitial && ! location.isBack;
|
|
70
76
|
useEffect( () => {
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
// Only attempt to restore focus:
|
|
78
|
+
// - if the current location is not the initial one (to avoid moving focus on page load)
|
|
79
|
+
// - when the screen becomes visible
|
|
80
|
+
// - if the wrapper ref has been assigned
|
|
81
|
+
if ( isInitialLocation || ! isMatch || ! wrapperRef.current ) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let elementToFocus: HTMLElement | null = null;
|
|
86
|
+
|
|
87
|
+
// When navigating back, if a selector is provided, use it to look for the
|
|
88
|
+
// target element (assumed to be a node inside the current NavigatorScreen)
|
|
89
|
+
if ( location.isBack && previousLocation?.focusTargetSelector ) {
|
|
90
|
+
elementToFocus = wrapperRef.current.querySelector(
|
|
91
|
+
previousLocation.focusTargetSelector
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// If the previous query didn't run or find any element to focus, fallback
|
|
96
|
+
// to the first tabbable element in the screen (or the screen itself).
|
|
97
|
+
if ( ! elementToFocus ) {
|
|
98
|
+
const firstTabbable = ( focus.tabbable.find(
|
|
99
|
+
wrapperRef.current
|
|
100
|
+
) as HTMLElement[] )[ 0 ];
|
|
101
|
+
|
|
102
|
+
elementToFocus = firstTabbable ?? wrapperRef.current;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
elementToFocus.focus();
|
|
106
|
+
}, [ isInitialLocation, isMatch ] );
|
|
107
|
+
|
|
108
|
+
const mergedWrapperRef = useMergeRefs( [ forwardedRef, wrapperRef ] );
|
|
73
109
|
|
|
74
110
|
if ( ! isMatch ) {
|
|
75
111
|
return null;
|
|
@@ -77,7 +113,11 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) {
|
|
|
77
113
|
|
|
78
114
|
if ( prefersReducedMotion ) {
|
|
79
115
|
return (
|
|
80
|
-
<View
|
|
116
|
+
<View
|
|
117
|
+
ref={ mergedWrapperRef }
|
|
118
|
+
className={ classes }
|
|
119
|
+
{ ...otherProps }
|
|
120
|
+
>
|
|
81
121
|
{ children }
|
|
82
122
|
</View>
|
|
83
123
|
);
|
|
@@ -120,7 +160,7 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) {
|
|
|
120
160
|
|
|
121
161
|
return (
|
|
122
162
|
<motion.div
|
|
123
|
-
ref={
|
|
163
|
+
ref={ mergedWrapperRef }
|
|
124
164
|
className={ classes }
|
|
125
165
|
{ ...otherProps }
|
|
126
166
|
{ ...animatedProps }
|
|
@@ -142,19 +182,19 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) {
|
|
|
142
182
|
* } from '@wordpress/components';
|
|
143
183
|
*
|
|
144
184
|
* function NavigatorButton( { path, ...props } ) {
|
|
145
|
-
* const {
|
|
185
|
+
* const { goTo } = useNavigator();
|
|
146
186
|
* return (
|
|
147
187
|
* <Button
|
|
148
188
|
* variant="primary"
|
|
149
|
-
* onClick={ () =>
|
|
189
|
+
* onClick={ () => goTo( path ) }
|
|
150
190
|
* { ...props }
|
|
151
191
|
* />
|
|
152
192
|
* );
|
|
153
193
|
* }
|
|
154
194
|
*
|
|
155
195
|
* function NavigatorBackButton( props ) {
|
|
156
|
-
* const {
|
|
157
|
-
* return <Button variant="secondary" onClick={ () =>
|
|
196
|
+
* const { goBack } = useNavigator();
|
|
197
|
+
* return <Button variant="secondary" onClick={ () => goBack() } { ...props } />;
|
|
158
198
|
* }
|
|
159
199
|
*
|
|
160
200
|
* const MyNavigation = () => (
|
|
@@ -19,19 +19,33 @@ export default {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
function NavigatorButton( { path, ...props } ) {
|
|
22
|
-
const {
|
|
22
|
+
const { goTo } = useNavigator();
|
|
23
|
+
const dataAttrName = 'data-navigator-focusable-id';
|
|
24
|
+
const dataAttrValue = path;
|
|
25
|
+
|
|
26
|
+
const dataAttrCssSelector = `[${ dataAttrName }="${ dataAttrValue }"]`;
|
|
27
|
+
|
|
28
|
+
const buttonProps = {
|
|
29
|
+
...props,
|
|
30
|
+
[ dataAttrName ]: dataAttrValue,
|
|
31
|
+
};
|
|
32
|
+
|
|
23
33
|
return (
|
|
24
34
|
<Button
|
|
25
35
|
variant="secondary"
|
|
26
|
-
onClick={ () =>
|
|
27
|
-
|
|
36
|
+
onClick={ () =>
|
|
37
|
+
goTo( path, { focusTargetSelector: dataAttrCssSelector } )
|
|
38
|
+
}
|
|
39
|
+
{ ...buttonProps }
|
|
28
40
|
/>
|
|
29
41
|
);
|
|
30
42
|
}
|
|
31
43
|
|
|
32
44
|
function NavigatorBackButton( props ) {
|
|
33
|
-
const {
|
|
34
|
-
return
|
|
45
|
+
const { goBack } = useNavigator();
|
|
46
|
+
return (
|
|
47
|
+
<Button variant="secondary" onClick={ () => goBack() } { ...props } />
|
|
48
|
+
);
|
|
35
49
|
}
|
|
36
50
|
|
|
37
51
|
const MyNavigation = () => {
|
|
@@ -31,27 +31,51 @@ const PATHS = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
function NavigatorButton( { path, onClick, ...props } ) {
|
|
34
|
-
const {
|
|
34
|
+
const { goTo } = useNavigator();
|
|
35
35
|
return (
|
|
36
36
|
<button
|
|
37
37
|
onClick={ () => {
|
|
38
|
-
|
|
39
|
-
// Used to spy on the values passed to `navigator.
|
|
40
|
-
onClick?.( { type: '
|
|
38
|
+
goTo( path );
|
|
39
|
+
// Used to spy on the values passed to `navigator.goTo`
|
|
40
|
+
onClick?.( { type: 'goTo', path } );
|
|
41
41
|
} }
|
|
42
42
|
{ ...props }
|
|
43
43
|
/>
|
|
44
44
|
);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function NavigatorButtonWithFocusRestoration( { path, onClick, ...props } ) {
|
|
48
|
+
const { goTo } = useNavigator();
|
|
49
|
+
const dataAttrName = 'data-navigator-focusable-id';
|
|
50
|
+
const dataAttrValue = path;
|
|
51
|
+
|
|
52
|
+
const dataAttrCssSelector = `[${ dataAttrName }="${ dataAttrValue }"]`;
|
|
53
|
+
|
|
54
|
+
const buttonProps = {
|
|
55
|
+
...props,
|
|
56
|
+
[ dataAttrName ]: dataAttrValue,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<button
|
|
61
|
+
onClick={ () => {
|
|
62
|
+
goTo( path, { focusTargetSelector: dataAttrCssSelector } );
|
|
63
|
+
// Used to spy on the values passed to `navigator.goTo`
|
|
64
|
+
onClick?.( { type: 'goTo', path } );
|
|
65
|
+
} }
|
|
66
|
+
{ ...buttonProps }
|
|
67
|
+
/>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
47
71
|
function NavigatorBackButton( { onClick, ...props } ) {
|
|
48
|
-
const {
|
|
72
|
+
const { goBack } = useNavigator();
|
|
49
73
|
return (
|
|
50
74
|
<button
|
|
51
75
|
onClick={ () => {
|
|
52
|
-
|
|
53
|
-
// Used to spy on the values passed to `navigator.
|
|
54
|
-
onClick?.( { type: '
|
|
76
|
+
goBack();
|
|
77
|
+
// Used to spy on the values passed to `navigator.goBack`
|
|
78
|
+
onClick?.( { type: 'goBack' } );
|
|
55
79
|
} }
|
|
56
80
|
{ ...props }
|
|
57
81
|
/>
|
|
@@ -65,28 +89,28 @@ const MyNavigation = ( {
|
|
|
65
89
|
<NavigatorProvider initialPath={ initialPath }>
|
|
66
90
|
<NavigatorScreen path={ PATHS.HOME }>
|
|
67
91
|
<p>This is the home screen.</p>
|
|
68
|
-
<NavigatorButton
|
|
69
|
-
path={ PATHS.CHILD }
|
|
70
|
-
onClick={ onNavigatorButtonClick }
|
|
71
|
-
>
|
|
72
|
-
Navigate to child screen.
|
|
73
|
-
</NavigatorButton>
|
|
74
92
|
<NavigatorButton
|
|
75
93
|
path={ PATHS.NOT_FOUND }
|
|
76
94
|
onClick={ onNavigatorButtonClick }
|
|
77
95
|
>
|
|
78
96
|
Navigate to non-existing screen.
|
|
79
97
|
</NavigatorButton>
|
|
98
|
+
<NavigatorButtonWithFocusRestoration
|
|
99
|
+
path={ PATHS.CHILD }
|
|
100
|
+
onClick={ onNavigatorButtonClick }
|
|
101
|
+
>
|
|
102
|
+
Navigate to child screen.
|
|
103
|
+
</NavigatorButtonWithFocusRestoration>
|
|
80
104
|
</NavigatorScreen>
|
|
81
105
|
|
|
82
106
|
<NavigatorScreen path={ PATHS.CHILD }>
|
|
83
107
|
<p>This is the child screen.</p>
|
|
84
|
-
<
|
|
108
|
+
<NavigatorButtonWithFocusRestoration
|
|
85
109
|
path={ PATHS.NESTED }
|
|
86
110
|
onClick={ onNavigatorButtonClick }
|
|
87
111
|
>
|
|
88
112
|
Navigate to nested screen.
|
|
89
|
-
</
|
|
113
|
+
</NavigatorButtonWithFocusRestoration>
|
|
90
114
|
<NavigatorBackButton onClick={ onNavigatorButtonClick }>
|
|
91
115
|
Go back
|
|
92
116
|
</NavigatorBackButton>
|
|
@@ -246,28 +270,28 @@ describe( 'Navigator', () => {
|
|
|
246
270
|
expect( getHomeScreen() ).toBeInTheDocument();
|
|
247
271
|
expect( getToChildScreenButton() ).toBeInTheDocument();
|
|
248
272
|
|
|
249
|
-
// Check the values passed to `navigator.
|
|
273
|
+
// Check the values passed to `navigator.goTo()`
|
|
250
274
|
expect( spy ).toHaveBeenCalledTimes( 6 );
|
|
251
275
|
expect( spy ).toHaveBeenNthCalledWith( 1, {
|
|
252
276
|
path: PATHS.CHILD,
|
|
253
|
-
type: '
|
|
277
|
+
type: 'goTo',
|
|
254
278
|
} );
|
|
255
279
|
expect( spy ).toHaveBeenNthCalledWith( 2, {
|
|
256
|
-
type: '
|
|
280
|
+
type: 'goBack',
|
|
257
281
|
} );
|
|
258
282
|
expect( spy ).toHaveBeenNthCalledWith( 3, {
|
|
259
283
|
path: PATHS.CHILD,
|
|
260
|
-
type: '
|
|
284
|
+
type: 'goTo',
|
|
261
285
|
} );
|
|
262
286
|
expect( spy ).toHaveBeenNthCalledWith( 4, {
|
|
263
287
|
path: PATHS.NESTED,
|
|
264
|
-
type: '
|
|
288
|
+
type: 'goTo',
|
|
265
289
|
} );
|
|
266
290
|
expect( spy ).toHaveBeenNthCalledWith( 5, {
|
|
267
|
-
type: '
|
|
291
|
+
type: 'goBack',
|
|
268
292
|
} );
|
|
269
293
|
expect( spy ).toHaveBeenNthCalledWith( 6, {
|
|
270
|
-
type: '
|
|
294
|
+
type: 'goBack',
|
|
271
295
|
} );
|
|
272
296
|
} );
|
|
273
297
|
|
|
@@ -291,11 +315,39 @@ describe( 'Navigator', () => {
|
|
|
291
315
|
getNestedScreen( { throwIfNotFound: false } )
|
|
292
316
|
).not.toBeInTheDocument();
|
|
293
317
|
|
|
294
|
-
// Check the values passed to `navigator.
|
|
318
|
+
// Check the values passed to `navigator.goTo()`
|
|
295
319
|
expect( spy ).toHaveBeenCalledTimes( 1 );
|
|
296
320
|
expect( spy ).toHaveBeenNthCalledWith( 1, {
|
|
297
321
|
path: PATHS.NOT_FOUND,
|
|
298
|
-
type: '
|
|
322
|
+
type: 'goTo',
|
|
299
323
|
} );
|
|
300
324
|
} );
|
|
325
|
+
|
|
326
|
+
it( 'should restore focus correctly', () => {
|
|
327
|
+
render( <MyNavigation /> );
|
|
328
|
+
|
|
329
|
+
expect( getHomeScreen() ).toBeInTheDocument();
|
|
330
|
+
|
|
331
|
+
// Navigate to child screen
|
|
332
|
+
fireEvent.click( getToChildScreenButton() );
|
|
333
|
+
|
|
334
|
+
expect( getChildScreen() ).toBeInTheDocument();
|
|
335
|
+
|
|
336
|
+
// Navigate to nested screen
|
|
337
|
+
fireEvent.click( getToNestedScreenButton() );
|
|
338
|
+
|
|
339
|
+
expect( getNestedScreen() ).toBeInTheDocument();
|
|
340
|
+
|
|
341
|
+
// Navigate back to child screen, check that focus was correctly restored
|
|
342
|
+
fireEvent.click( getBackButton() );
|
|
343
|
+
|
|
344
|
+
expect( getChildScreen() ).toBeInTheDocument();
|
|
345
|
+
expect( getToNestedScreenButton() ).toHaveFocus();
|
|
346
|
+
|
|
347
|
+
// Navigate back to home screen, check that focus was correctly restored
|
|
348
|
+
fireEvent.click( getBackButton() );
|
|
349
|
+
|
|
350
|
+
expect( getHomeScreen() ).toBeInTheDocument();
|
|
351
|
+
expect( getToChildScreenButton() ).toHaveFocus();
|
|
352
|
+
} );
|
|
301
353
|
} );
|
package/src/navigator/types.ts
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { ReactNode } from 'react';
|
|
5
5
|
|
|
6
|
-
type NavigateOptions = {
|
|
6
|
+
type NavigateOptions = {
|
|
7
|
+
focusTargetSelector?: string;
|
|
8
|
+
};
|
|
7
9
|
|
|
8
10
|
export type NavigatorLocation = NavigateOptions & {
|
|
9
11
|
isInitial?: boolean;
|
|
@@ -13,8 +15,8 @@ export type NavigatorLocation = NavigateOptions & {
|
|
|
13
15
|
|
|
14
16
|
export type NavigatorContext = {
|
|
15
17
|
location: NavigatorLocation;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
goTo: ( path: string, options?: NavigateOptions ) => void;
|
|
19
|
+
goBack: () => void;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
// Returned by the `useNavigator` hook
|
|
@@ -13,12 +13,12 @@ import type { Navigator } from './types';
|
|
|
13
13
|
* Retrieves a `navigator` instance.
|
|
14
14
|
*/
|
|
15
15
|
function useNavigator(): Navigator {
|
|
16
|
-
const { location,
|
|
16
|
+
const { location, goTo, goBack } = useContext( NavigatorContext );
|
|
17
17
|
|
|
18
18
|
return {
|
|
19
19
|
location,
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
goTo,
|
|
21
|
+
goBack,
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
|
package/src/placeholder/index.js
CHANGED
|
@@ -73,12 +73,14 @@ function Placeholder( {
|
|
|
73
73
|
<Icon icon={ icon } />
|
|
74
74
|
{ label }
|
|
75
75
|
</div>
|
|
76
|
-
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
<fieldset className={ fieldsetClasses }>
|
|
77
|
+
{ !! instructions && (
|
|
78
|
+
<legend className="components-placeholder__instructions">
|
|
79
|
+
{ instructions }
|
|
80
|
+
</legend>
|
|
81
|
+
) }
|
|
82
|
+
{ children }
|
|
83
|
+
</fieldset>
|
|
82
84
|
</div>
|
|
83
85
|
);
|
|
84
86
|
}
|
|
@@ -77,6 +77,18 @@
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
// Overrides for browser and editor fieldset styles.
|
|
81
|
+
.components-placeholder__fieldset.components-placeholder__fieldset {
|
|
82
|
+
border: none;
|
|
83
|
+
padding: 0;
|
|
84
|
+
|
|
85
|
+
.components-placeholder__instructions {
|
|
86
|
+
padding: 0;
|
|
87
|
+
font-weight: normal;
|
|
88
|
+
font-size: 1em;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
80
92
|
.components-placeholder__fieldset.is-column-layout,
|
|
81
93
|
.components-placeholder__fieldset.is-column-layout form {
|
|
82
94
|
flex-direction: column;
|
|
@@ -88,7 +88,7 @@ describe( 'Placeholder', () => {
|
|
|
88
88
|
const element = <div>Fieldset</div>;
|
|
89
89
|
const placeholder = shallow( <Placeholder children={ element } /> );
|
|
90
90
|
const placeholderFieldset = placeholder.find(
|
|
91
|
-
'.components-placeholder__fieldset'
|
|
91
|
+
'fieldset.components-placeholder__fieldset'
|
|
92
92
|
);
|
|
93
93
|
const child = placeholderFieldset.childAt( 0 );
|
|
94
94
|
|
|
@@ -96,6 +96,23 @@ describe( 'Placeholder', () => {
|
|
|
96
96
|
expect( child.matchesElement( element ) ).toBe( true );
|
|
97
97
|
} );
|
|
98
98
|
|
|
99
|
+
it( 'should display a legend if instructions are passed', () => {
|
|
100
|
+
const element = <div>Fieldset</div>;
|
|
101
|
+
const instructions = 'Choose an option.';
|
|
102
|
+
const placeholder = shallow(
|
|
103
|
+
<Placeholder
|
|
104
|
+
children={ element }
|
|
105
|
+
instructions={ instructions }
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
const placeholderLegend = placeholder.find(
|
|
109
|
+
'legend.components-placeholder__instructions'
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
expect( placeholderLegend.exists() ).toBe( true );
|
|
113
|
+
expect( placeholderLegend.text() ).toEqual( instructions );
|
|
114
|
+
} );
|
|
115
|
+
|
|
99
116
|
it( 'should add an additional className to the top container', () => {
|
|
100
117
|
const placeholder = shallow(
|
|
101
118
|
<Placeholder className="wp-placeholder" />
|
package/src/scrollable/hook.js
CHANGED
|
@@ -36,7 +36,7 @@ export function useScrollable( props ) {
|
|
|
36
36
|
scrollDirection === 'auto' && styles.scrollAuto,
|
|
37
37
|
className
|
|
38
38
|
),
|
|
39
|
-
[ className, scrollDirection, smoothScroll ]
|
|
39
|
+
[ className, cx, scrollDirection, smoothScroll ]
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
return { ...otherProps, className: classes };
|
|
@@ -8,6 +8,7 @@ import { useRef, useState, useEffect, createPortal } from '@wordpress/element';
|
|
|
8
8
|
* Internal dependencies
|
|
9
9
|
*/
|
|
10
10
|
import useSlot from './use-slot';
|
|
11
|
+
import StyleProvider from '../../style-provider';
|
|
11
12
|
|
|
12
13
|
function useForceUpdate() {
|
|
13
14
|
const [ , setState ] = useState( {} );
|
|
@@ -48,5 +49,15 @@ export default function Fill( { name, children } ) {
|
|
|
48
49
|
children = children( slot.fillProps );
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
// When using a `Fill`, the `children` will be rendered in the document of the
|
|
53
|
+
// `Slot`. This means that we need to wrap the `children` in a `StyleProvider`
|
|
54
|
+
// to make sure we're referencing the right document/iframe (instead of the
|
|
55
|
+
// context of the `Fill`'s parent).
|
|
56
|
+
const wrappedChildren = (
|
|
57
|
+
<StyleProvider document={ slot.ref.current.ownerDocument }>
|
|
58
|
+
{ children }
|
|
59
|
+
</StyleProvider>
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
return createPortal( wrappedChildren, slot.ref.current );
|
|
52
63
|
}
|
package/src/spinner/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# Spinner
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-

|
|
6
|
-
|
|
7
|
-
## Best practices
|
|
8
|
-
|
|
9
|
-
The spinner component should:
|
|
10
|
-
|
|
11
|
-
- Signal to users that the processing of their request is underway and will soon complete.
|
|
3
|
+
`Spinner` is a component used to notify users that their action is being processed.
|
|
12
4
|
|
|
13
5
|
## Usage
|
|
14
6
|
|
|
15
7
|
```jsx
|
|
16
8
|
import { Spinner } from '@wordpress/components';
|
|
17
9
|
|
|
18
|
-
|
|
10
|
+
function Example() {
|
|
11
|
+
return <Spinner />;
|
|
12
|
+
}
|
|
19
13
|
```
|
|
14
|
+
|
|
15
|
+
## Best practices
|
|
16
|
+
|
|
17
|
+
The spinner component should:
|
|
18
|
+
|
|
19
|
+
- Signal to users that the processing of their request is underway and will soon complete.
|
package/src/spinner/index.js
CHANGED
|
@@ -1,8 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import classNames from 'classnames';
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Internal dependencies
|
|
3
8
|
*/
|
|
4
|
-
import { StyledSpinner } from './styles
|
|
9
|
+
import { StyledSpinner, SpinnerTrack, SpinnerIndicator } from './styles';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef OwnProps
|
|
13
|
+
*
|
|
14
|
+
* @property {string} [className] Class name
|
|
15
|
+
*/
|
|
16
|
+
/** @typedef {import('react').ComponentPropsWithoutRef<'svg'> & OwnProps} Props */
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {Props} props
|
|
20
|
+
* @return {JSX.Element} Element
|
|
21
|
+
*/
|
|
22
|
+
export default function Spinner( { className, ...props } ) {
|
|
23
|
+
return (
|
|
24
|
+
<StyledSpinner
|
|
25
|
+
className={ classNames( 'components-spinner', className ) }
|
|
26
|
+
viewBox="0 0 100 100"
|
|
27
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
28
|
+
role="presentation"
|
|
29
|
+
focusable="false"
|
|
30
|
+
{ ...props }
|
|
31
|
+
>
|
|
32
|
+
{ /* Gray circular background */ }
|
|
33
|
+
<SpinnerTrack
|
|
34
|
+
cx="50"
|
|
35
|
+
cy="50"
|
|
36
|
+
r="50"
|
|
37
|
+
vectorEffect="non-scaling-stroke"
|
|
38
|
+
/>
|
|
5
39
|
|
|
6
|
-
|
|
7
|
-
|
|
40
|
+
{ /* Theme-colored arc */ }
|
|
41
|
+
<SpinnerIndicator
|
|
42
|
+
d="m 50 0 a 50 50 0 0 1 50 50"
|
|
43
|
+
vectorEffect="non-scaling-stroke"
|
|
44
|
+
/>
|
|
45
|
+
</StyledSpinner>
|
|
46
|
+
);
|
|
8
47
|
}
|