@wordpress/components 23.2.0 → 23.3.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 +35 -1
- package/CONTRIBUTING.md +1 -1
- package/build/alignment-matrix-control/utils.js +2 -2
- package/build/alignment-matrix-control/utils.js.map +1 -1
- package/build/autocomplete/autocompleter-ui.js +1 -3
- package/build/autocomplete/autocompleter-ui.js.map +1 -1
- package/build/border-box-control/border-box-control-linked-button/component.js.map +1 -1
- package/build/border-box-control/border-box-control-linked-button/hook.js.map +1 -1
- package/build/border-control/border-control-dropdown/component.js +8 -4
- package/build/border-control/border-control-dropdown/component.js.map +1 -1
- package/build/button/deprecated.js +8 -6
- package/build/button/deprecated.js.map +1 -1
- package/build/button/index.js +52 -23
- package/build/button/index.js.map +1 -1
- package/build/button/types.js +6 -0
- package/build/button/types.js.map +1 -0
- package/build/color-list-picker/index.js.map +1 -1
- package/build/color-list-picker/types.js +6 -0
- package/build/color-list-picker/types.js.map +1 -0
- package/build/color-palette/index.js +9 -61
- package/build/color-palette/index.js.map +1 -1
- package/build/color-palette/index.native.js +24 -9
- package/build/color-palette/index.native.js.map +1 -1
- package/build/color-palette/utils.js +103 -0
- package/build/color-palette/utils.js.map +1 -0
- package/build/custom-gradient-picker/gradient-bar/utils.js +1 -1
- package/build/custom-gradient-picker/gradient-bar/utils.js.map +1 -1
- package/build/date-time/date/index.js.map +1 -1
- package/build/dropdown/index.js +20 -8
- package/build/dropdown/index.js.map +1 -1
- package/build/form-token-field/token.js +1 -1
- package/build/form-token-field/token.js.map +1 -1
- package/build/gradient-picker/index.js +9 -1
- package/build/gradient-picker/index.js.map +1 -1
- package/build/h-stack/component.js +0 -1
- package/build/h-stack/component.js.map +1 -1
- package/build/input-control/input-field.js +4 -2
- package/build/input-control/input-field.js.map +1 -1
- package/build/keyboard-shortcuts/index.js +44 -16
- package/build/keyboard-shortcuts/index.js.map +1 -1
- package/build/keyboard-shortcuts/types.js +6 -0
- package/build/keyboard-shortcuts/types.js.map +1 -0
- package/build/modal/index.js +1 -1
- package/build/modal/index.js.map +1 -1
- package/build/notice/index.js +16 -18
- package/build/notice/index.js.map +1 -1
- package/build/notice/list.js +23 -8
- package/build/notice/list.js.map +1 -1
- package/build/notice/types.js +6 -0
- package/build/notice/types.js.map +1 -0
- package/build/number-control/index.js +1 -1
- package/build/number-control/index.js.map +1 -1
- package/build/query-controls/author-select.js +7 -3
- package/build/query-controls/author-select.js.map +1 -1
- package/build/query-controls/category-select.js +7 -3
- package/build/query-controls/category-select.js.map +1 -1
- package/build/query-controls/index.js +68 -20
- package/build/query-controls/index.js.map +1 -1
- package/build/query-controls/terms.js +4 -3
- package/build/query-controls/terms.js.map +1 -1
- package/build/query-controls/types.js +6 -0
- package/build/query-controls/types.js.map +1 -0
- package/build/slot-fill/bubbles-virtually/fill.js +1 -0
- package/build/slot-fill/bubbles-virtually/fill.js.map +1 -1
- package/build/slot-fill/slot.js +1 -0
- package/build/slot-fill/slot.js.map +1 -1
- package/build/slot-fill/use-slot.js +1 -11
- package/build/slot-fill/use-slot.js.map +1 -1
- package/build/snackbar/index.js.map +1 -1
- package/build/snackbar/list.js.map +1 -1
- package/build/tab-panel/index.js +36 -8
- package/build/tab-panel/index.js.map +1 -1
- package/build/tree-grid/index.js +1 -1
- package/build/tree-grid/index.js.map +1 -1
- package/build/tree-select/index.js +2 -6
- package/build/tree-select/index.js.map +1 -1
- package/build-module/alignment-matrix-control/utils.js +2 -2
- package/build-module/alignment-matrix-control/utils.js.map +1 -1
- package/build-module/autocomplete/autocompleter-ui.js +1 -2
- package/build-module/autocomplete/autocompleter-ui.js.map +1 -1
- package/build-module/border-box-control/border-box-control-linked-button/component.js.map +1 -1
- package/build-module/border-box-control/border-box-control-linked-button/hook.js.map +1 -1
- package/build-module/border-control/border-control-dropdown/component.js +7 -4
- package/build-module/border-control/border-control-dropdown/component.js.map +1 -1
- package/build-module/button/deprecated.js +8 -5
- package/build-module/button/deprecated.js.map +1 -1
- package/build-module/button/index.js +51 -22
- package/build-module/button/index.js.map +1 -1
- package/build-module/button/types.js +2 -0
- package/build-module/button/types.js.map +1 -0
- package/build-module/color-list-picker/index.js.map +1 -1
- package/build-module/color-list-picker/types.js +2 -0
- package/build-module/color-list-picker/types.js.map +1 -0
- package/build-module/color-palette/index.js +7 -54
- package/build-module/color-palette/index.js.map +1 -1
- package/build-module/color-palette/index.native.js +24 -8
- package/build-module/color-palette/index.native.js.map +1 -1
- package/build-module/color-palette/utils.js +79 -0
- package/build-module/color-palette/utils.js.map +1 -0
- package/build-module/custom-gradient-picker/gradient-bar/utils.js +1 -1
- package/build-module/custom-gradient-picker/gradient-bar/utils.js.map +1 -1
- package/build-module/date-time/date/index.js +1 -1
- package/build-module/date-time/date/index.js.map +1 -1
- package/build-module/dropdown/index.js +19 -8
- package/build-module/dropdown/index.js.map +1 -1
- package/build-module/form-token-field/token.js +1 -1
- package/build-module/form-token-field/token.js.map +1 -1
- package/build-module/gradient-picker/index.js +9 -2
- package/build-module/gradient-picker/index.js.map +1 -1
- package/build-module/h-stack/component.js +0 -1
- package/build-module/h-stack/component.js.map +1 -1
- package/build-module/input-control/input-field.js +4 -2
- package/build-module/input-control/input-field.js.map +1 -1
- package/build-module/keyboard-shortcuts/index.js +48 -16
- package/build-module/keyboard-shortcuts/index.js.map +1 -1
- package/build-module/keyboard-shortcuts/types.js +2 -0
- package/build-module/keyboard-shortcuts/types.js.map +1 -0
- package/build-module/modal/index.js +1 -1
- package/build-module/modal/index.js.map +1 -1
- package/build-module/notice/index.js +14 -15
- package/build-module/notice/index.js.map +1 -1
- package/build-module/notice/list.js +23 -8
- package/build-module/notice/list.js.map +1 -1
- package/build-module/notice/types.js +2 -0
- package/build-module/notice/types.js.map +1 -0
- package/build-module/number-control/index.js +1 -1
- package/build-module/number-control/index.js.map +1 -1
- package/build-module/query-controls/author-select.js +7 -3
- package/build-module/query-controls/author-select.js.map +1 -1
- package/build-module/query-controls/category-select.js +8 -4
- package/build-module/query-controls/category-select.js.map +1 -1
- package/build-module/query-controls/index.js +64 -20
- package/build-module/query-controls/index.js.map +1 -1
- package/build-module/query-controls/terms.js +8 -4
- package/build-module/query-controls/terms.js.map +1 -1
- package/build-module/query-controls/types.js +2 -0
- package/build-module/query-controls/types.js.map +1 -0
- package/build-module/slot-fill/bubbles-virtually/fill.js +1 -0
- package/build-module/slot-fill/bubbles-virtually/fill.js.map +1 -1
- package/build-module/slot-fill/slot.js +1 -0
- package/build-module/slot-fill/slot.js.map +1 -1
- package/build-module/slot-fill/use-slot.js +2 -12
- package/build-module/slot-fill/use-slot.js.map +1 -1
- package/build-module/snackbar/index.js.map +1 -1
- package/build-module/snackbar/list.js.map +1 -1
- package/build-module/tab-panel/index.js +36 -8
- package/build-module/tab-panel/index.js.map +1 -1
- package/build-module/tree-grid/index.js +1 -1
- package/build-module/tree-grid/index.js.map +1 -1
- package/build-module/tree-select/index.js +2 -6
- package/build-module/tree-select/index.js.map +1 -1
- package/build-style/style-rtl.css +5 -0
- package/build-style/style.css +5 -0
- package/build-types/border-box-control/border-box-control/hook.d.ts +1 -1
- package/build-types/border-box-control/border-box-control-linked-button/component.d.ts +1 -1
- package/build-types/border-box-control/border-box-control-linked-button/hook.d.ts +171 -160
- package/build-types/border-box-control/border-box-control-linked-button/hook.d.ts.map +1 -1
- package/build-types/border-box-control/border-box-control-split-controls/hook.d.ts +1 -1
- package/build-types/border-control/border-control/hook.d.ts +1 -1
- package/build-types/border-control/border-control-dropdown/component.d.ts.map +1 -1
- package/build-types/border-control/border-control-dropdown/hook.d.ts +1 -1
- package/build-types/button/deprecated.d.ts +143 -7
- package/build-types/button/deprecated.d.ts.map +1 -1
- package/build-types/button/index.d.ts +20 -3
- package/build-types/button/index.d.ts.map +1 -1
- package/build-types/button/stories/index.d.ts +20 -0
- package/build-types/button/stories/index.d.ts.map +1 -0
- package/build-types/button/test/index.d.ts +2 -0
- package/build-types/button/test/index.d.ts.map +1 -0
- package/build-types/button/types.d.ts +134 -0
- package/build-types/button/types.d.ts.map +1 -0
- package/build-types/color-list-picker/index.d.ts +5 -0
- package/build-types/color-list-picker/index.d.ts.map +1 -0
- package/build-types/color-list-picker/types.d.ts +42 -0
- package/build-types/color-list-picker/types.d.ts.map +1 -0
- package/build-types/color-palette/index.d.ts +2 -4
- package/build-types/color-palette/index.d.ts.map +1 -1
- package/build-types/color-palette/stories/index.d.ts +2 -2
- package/build-types/color-palette/styles.d.ts +1 -1
- package/build-types/color-palette/types.d.ts +1 -1
- package/build-types/color-palette/types.d.ts.map +1 -1
- package/build-types/color-palette/utils.d.ts +14 -0
- package/build-types/color-palette/utils.d.ts.map +1 -0
- package/build-types/color-picker/styles.d.ts +2 -2
- package/build-types/date-time/date/index.d.ts.map +1 -1
- package/build-types/date-time/date/styles.d.ts +3 -3
- package/build-types/dropdown/index.d.ts +4 -4
- package/build-types/dropdown/index.d.ts.map +1 -1
- package/build-types/dropdown/stories/index.d.ts.map +1 -1
- package/build-types/dropdown/types.d.ts +9 -10
- package/build-types/dropdown/types.d.ts.map +1 -1
- package/build-types/font-size-picker/styles.d.ts +2 -2
- package/build-types/h-stack/component.d.ts +0 -1
- package/build-types/h-stack/component.d.ts.map +1 -1
- package/build-types/input-control/input-field.d.ts.map +1 -1
- package/build-types/keyboard-shortcuts/index.d.ts +38 -0
- package/build-types/keyboard-shortcuts/index.d.ts.map +1 -0
- package/build-types/keyboard-shortcuts/stories/index.d.ts +12 -0
- package/build-types/keyboard-shortcuts/stories/index.d.ts.map +1 -0
- package/build-types/keyboard-shortcuts/test/index.d.ts +2 -0
- package/build-types/keyboard-shortcuts/test/index.d.ts.map +1 -0
- package/build-types/keyboard-shortcuts/types.d.ts +48 -0
- package/build-types/keyboard-shortcuts/types.d.ts.map +1 -0
- package/build-types/modal/index.d.ts.map +1 -1
- package/build-types/navigator/navigator-back-button/component.d.ts +1 -1
- package/build-types/navigator/navigator-back-button/hook.d.ts +2 -2
- package/build-types/navigator/navigator-button/component.d.ts +1 -1
- package/build-types/navigator/navigator-button/hook.d.ts +2 -2
- package/build-types/notice/index.d.ts +16 -0
- package/build-types/notice/index.d.ts.map +1 -0
- package/build-types/notice/list.d.ts +32 -0
- package/build-types/notice/list.d.ts.map +1 -0
- package/build-types/notice/stories/index.d.ts +17 -0
- package/build-types/notice/stories/index.d.ts.map +1 -0
- package/build-types/notice/test/index.d.ts +2 -0
- package/build-types/notice/test/index.d.ts.map +1 -0
- package/build-types/notice/test/list.d.ts +2 -0
- package/build-types/notice/test/list.d.ts.map +1 -0
- package/build-types/notice/types.d.ts +128 -0
- package/build-types/notice/types.d.ts.map +1 -0
- package/build-types/number-control/styles/number-control-styles.d.ts +2 -2
- package/build-types/number-control/styles/number-control-styles.d.ts.map +1 -1
- package/build-types/placeholder/stories/index.d.ts.map +1 -1
- package/build-types/query-controls/author-select.d.ts +4 -0
- package/build-types/query-controls/author-select.d.ts.map +1 -0
- package/build-types/query-controls/category-select.d.ts +4 -0
- package/build-types/query-controls/category-select.d.ts.map +1 -0
- package/build-types/query-controls/index.d.ts +30 -0
- package/build-types/query-controls/index.d.ts.map +1 -0
- package/build-types/query-controls/stories/index.d.ts +13 -0
- package/build-types/query-controls/stories/index.d.ts.map +1 -0
- package/build-types/query-controls/terms.d.ts +13 -0
- package/build-types/query-controls/terms.d.ts.map +1 -0
- package/build-types/query-controls/test/terms.d.ts +2 -0
- package/build-types/query-controls/test/terms.d.ts.map +1 -0
- package/build-types/query-controls/types.d.ts +131 -0
- package/build-types/query-controls/types.d.ts.map +1 -0
- package/build-types/range-control/index.d.ts +1 -1
- package/build-types/slot-fill/bubbles-virtually/fill.d.ts.map +1 -1
- package/build-types/slot-fill/use-slot.d.ts.map +1 -1
- package/build-types/snackbar/index.d.ts +9 -2
- package/build-types/snackbar/index.d.ts.map +1 -1
- package/build-types/snackbar/list.d.ts.map +1 -1
- package/build-types/snackbar/types.d.ts +15 -88
- package/build-types/snackbar/types.d.ts.map +1 -1
- package/build-types/tab-panel/index.d.ts.map +1 -1
- package/build-types/tab-panel/types.d.ts +1 -1
- package/build-types/tab-panel/types.d.ts.map +1 -1
- package/build-types/toggle-group-control/stories/index.d.ts.map +1 -1
- package/build-types/tree-select/index.d.ts.map +1 -1
- package/build-types/ui/form-group/form-group.d.ts +2 -2
- package/package.json +18 -17
- package/src/alignment-matrix-control/utils.tsx +2 -2
- package/src/autocomplete/autocompleter-ui.js +1 -2
- package/src/autocomplete/test/index.js +1 -5
- package/src/border-box-control/border-box-control-linked-button/component.tsx +1 -1
- package/src/border-box-control/border-box-control-linked-button/hook.ts +1 -1
- package/src/border-control/border-control-dropdown/component.tsx +9 -8
- package/src/box-control/test/index.js +11 -35
- package/src/button/README.md +49 -55
- package/src/button/{deprecated.js → deprecated.tsx} +19 -4
- package/src/button/{index.js → index.tsx} +95 -34
- package/src/button/stories/index.tsx +106 -0
- package/src/button/style.scss +3 -2
- package/src/button/test/{index.js → index.tsx} +30 -7
- package/src/button/types.ts +138 -0
- package/src/checkbox-control/test/index.tsx +1 -5
- package/src/color-list-picker/{index.js → index.tsx} +3 -2
- package/src/color-list-picker/types.ts +46 -0
- package/src/color-palette/README.md +1 -1
- package/src/color-palette/index.native.js +11 -4
- package/src/color-palette/index.tsx +11 -67
- package/src/color-palette/test/index.tsx +4 -14
- package/src/color-palette/test/utils.ts +1 -1
- package/src/color-palette/types.ts +1 -1
- package/src/color-palette/utils.ts +98 -0
- package/src/color-picker/test/index.js +6 -15
- package/src/combobox-control/test/index.js +1 -6
- package/src/confirm-dialog/test/index.js +9 -29
- package/src/custom-gradient-picker/gradient-bar/utils.js +1 -1
- package/src/date-time/date/index.tsx +2 -1
- package/src/date-time/date/test/index.tsx +2 -8
- package/src/date-time/time/test/index.tsx +9 -29
- package/src/dimension-control/test/index.test.js +2 -8
- package/src/disabled/test/index.tsx +1 -5
- package/src/draggable/test/index.native.js +4 -4
- package/src/dropdown/README.md +1 -8
- package/src/dropdown/index.tsx +17 -6
- package/src/dropdown/stories/index.tsx +3 -3
- package/src/dropdown/test/index.tsx +2 -8
- package/src/dropdown/types.ts +9 -10
- package/src/dropdown-menu/README.md +1 -1
- package/src/dropdown-menu/stories/index.js +96 -27
- package/src/dropdown-menu/test/index.js +2 -8
- package/src/external-link/test/index.tsx +1 -6
- package/src/focal-point-picker/test/index.js +3 -11
- package/src/font-size-picker/test/index.tsx +14 -44
- package/src/form-file-upload/test/index.tsx +2 -17
- package/src/form-toggle/test/index.tsx +1 -5
- package/src/form-token-field/test/index.tsx +80 -163
- package/src/form-token-field/token.tsx +1 -1
- package/src/gradient-picker/index.js +15 -4
- package/src/guide/test/index.js +5 -17
- package/src/h-stack/component.tsx +0 -1
- package/src/higher-order/with-filters/test/index.js +24 -24
- package/src/higher-order/with-focus-outside/test/index.js +11 -25
- package/src/higher-order/with-focus-return/test/index.js +1 -5
- package/src/input-control/input-field.tsx +3 -1
- package/src/input-control/test/index.js +1 -6
- package/src/isolated-event-container/test/index.js +2 -8
- package/src/keyboard-shortcuts/README.md +1 -1
- package/src/keyboard-shortcuts/index.tsx +93 -0
- package/src/keyboard-shortcuts/stories/index.tsx +60 -0
- package/src/keyboard-shortcuts/test/{index.js → index.tsx} +16 -6
- package/src/keyboard-shortcuts/types.ts +51 -0
- package/src/modal/index.tsx +1 -2
- package/src/navigable-container/test/navigable-menu.js +5 -17
- package/src/navigable-container/test/tababble-container.js +3 -11
- package/src/navigation/test/index.js +3 -11
- package/src/navigator/test/index.tsx +6 -20
- package/src/notice/README.md +89 -42
- package/src/notice/{index.js → index.tsx} +28 -20
- package/src/notice/list.tsx +72 -0
- package/src/notice/stories/index.tsx +119 -0
- package/src/notice/test/__snapshots__/{index.js.snap → index.tsx.snap} +0 -0
- package/src/notice/test/{index.js → index.tsx} +7 -4
- package/src/notice/test/{list.js → list.tsx} +0 -0
- package/src/notice/types.ts +136 -0
- package/src/number-control/index.tsx +1 -1
- package/src/number-control/test/index.tsx +28 -86
- package/src/panel/test/body.js +2 -8
- package/src/placeholder/stories/index.tsx +1 -0
- package/src/query-controls/README.md +56 -56
- package/src/query-controls/author-select.tsx +37 -0
- package/src/query-controls/category-select.tsx +46 -0
- package/src/query-controls/index.tsx +192 -0
- package/src/query-controls/stories/index.tsx +205 -0
- package/src/query-controls/terms.ts +57 -0
- package/src/query-controls/test/{terms.js → terms.ts} +36 -20
- package/src/query-controls/types.ts +150 -0
- package/src/select-control/test/select-control.tsx +1 -6
- package/src/slot-fill/bubbles-virtually/fill.js +1 -0
- package/src/slot-fill/slot.js +1 -1
- package/src/slot-fill/use-slot.js +6 -16
- package/src/snackbar/index.tsx +6 -5
- package/src/snackbar/list.tsx +4 -2
- package/src/snackbar/types.ts +18 -92
- package/src/tab-panel/index.tsx +38 -16
- package/src/tab-panel/style.scss +8 -0
- package/src/tab-panel/test/index.tsx +35 -7
- package/src/tab-panel/types.ts +1 -1
- package/src/theme/test/index.tsx +4 -4
- package/src/toggle-group-control/stories/index.tsx +1 -0
- package/src/toggle-group-control/test/index.tsx +7 -23
- package/src/toolbar/stories/index.js +75 -72
- package/src/tools-panel/stories/index.js +3 -0
- package/src/tools-panel/test/index.js +1 -1
- package/src/tree-grid/index.js +1 -1
- package/src/tree-select/index.tsx +3 -6
- package/src/ui/context/test/context-connect.tsx +2 -0
- package/src/ui/context/test/wordpress-component.tsx +2 -0
- package/src/unit-control/test/index.tsx +21 -74
- package/src/utils/hooks/test/use-latest-ref.js +15 -18
- package/tsconfig.json +1 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/build-types/radio-context/index.d.ts +0 -6
- package/build-types/radio-context/index.d.ts.map +0 -1
- package/src/button/stories/index.js +0 -179
- package/src/keyboard-shortcuts/index.js +0 -56
- package/src/notice/list.js +0 -48
- package/src/notice/stories/index.js +0 -46
- package/src/query-controls/author-select.js +0 -23
- package/src/query-controls/category-select.js +0 -31
- package/src/query-controls/index.js +0 -122
- package/src/query-controls/terms.js +0 -40
- package/src/toolbar/stories/toolbar-button.js +0 -32
- package/src/toolbar/stories/toolbar-group.js +0 -33
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { groupBy } from 'lodash';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import type {
|
|
10
|
+
Author,
|
|
11
|
+
Category,
|
|
12
|
+
TermWithParentAndChildren,
|
|
13
|
+
TermsByParent,
|
|
14
|
+
} from './types';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns terms in a tree form.
|
|
18
|
+
*
|
|
19
|
+
* @param flatTerms Array of terms in flat format.
|
|
20
|
+
*
|
|
21
|
+
* @return Terms in tree format.
|
|
22
|
+
*/
|
|
23
|
+
export function buildTermsTree( flatTerms: readonly ( Author | Category )[] ) {
|
|
24
|
+
const flatTermsWithParentAndChildren: TermWithParentAndChildren[] =
|
|
25
|
+
flatTerms.map( ( term ) => {
|
|
26
|
+
return {
|
|
27
|
+
children: [],
|
|
28
|
+
parent: null,
|
|
29
|
+
...term,
|
|
30
|
+
id: String( term.id ),
|
|
31
|
+
};
|
|
32
|
+
} );
|
|
33
|
+
|
|
34
|
+
const termsByParent: TermsByParent = groupBy(
|
|
35
|
+
flatTermsWithParentAndChildren,
|
|
36
|
+
'parent'
|
|
37
|
+
);
|
|
38
|
+
if ( termsByParent.null && termsByParent.null.length ) {
|
|
39
|
+
return flatTermsWithParentAndChildren;
|
|
40
|
+
}
|
|
41
|
+
const fillWithChildren = (
|
|
42
|
+
terms: TermWithParentAndChildren[]
|
|
43
|
+
): TermWithParentAndChildren[] => {
|
|
44
|
+
return terms.map( ( term ) => {
|
|
45
|
+
const children = termsByParent[ term.id ];
|
|
46
|
+
return {
|
|
47
|
+
...term,
|
|
48
|
+
children:
|
|
49
|
+
children && children.length
|
|
50
|
+
? fillWithChildren( children )
|
|
51
|
+
: [],
|
|
52
|
+
};
|
|
53
|
+
} );
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return fillWithChildren( termsByParent[ '0' ] || [] );
|
|
57
|
+
}
|
|
@@ -6,38 +6,53 @@ import { buildTermsTree } from '../terms';
|
|
|
6
6
|
describe( 'buildTermsTree()', () => {
|
|
7
7
|
it( 'Should return same array as input with null parent and empty children added if parent is never specified.', () => {
|
|
8
8
|
const input = Object.freeze( [
|
|
9
|
-
{ id: 2232, dummy: true },
|
|
10
|
-
{ id: 2245, dummy: true },
|
|
9
|
+
{ id: 2232, name: 'foo', dummy: true },
|
|
10
|
+
{ id: 2245, name: 'baz', dummy: true },
|
|
11
11
|
] );
|
|
12
12
|
const output = Object.freeze( [
|
|
13
|
-
{
|
|
14
|
-
|
|
13
|
+
{
|
|
14
|
+
id: '2232',
|
|
15
|
+
name: 'foo',
|
|
16
|
+
parent: null,
|
|
17
|
+
children: [],
|
|
18
|
+
dummy: true,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: '2245',
|
|
22
|
+
name: 'baz',
|
|
23
|
+
parent: null,
|
|
24
|
+
children: [],
|
|
25
|
+
dummy: true,
|
|
26
|
+
},
|
|
15
27
|
] );
|
|
16
28
|
const termsTreem = buildTermsTree( input );
|
|
17
29
|
expect( termsTreem ).toEqual( output );
|
|
18
30
|
} );
|
|
19
31
|
it( 'Should return same array as input with empty children added if all the elements are top level', () => {
|
|
20
32
|
const input = Object.freeze( [
|
|
21
|
-
{ id: 2232, parent: 0, dummy: true },
|
|
22
|
-
{ id: 2245, parent: 0, dummy: false },
|
|
33
|
+
{ id: 2232, name: 'foo', parent: 0, dummy: true },
|
|
34
|
+
{ id: 2245, name: 'baz', parent: 0, dummy: false },
|
|
23
35
|
] );
|
|
24
36
|
const output = [
|
|
25
|
-
{ id: 2232, parent: 0, children: [], dummy: true },
|
|
26
|
-
{ id: 2245, parent: 0, children: [], dummy: false },
|
|
37
|
+
{ id: '2232', name: 'foo', parent: 0, children: [], dummy: true },
|
|
38
|
+
{ id: '2245', name: 'baz', parent: 0, children: [], dummy: false },
|
|
27
39
|
];
|
|
28
40
|
const termsTreem = buildTermsTree( input );
|
|
29
41
|
expect( termsTreem ).toEqual( output );
|
|
30
42
|
} );
|
|
31
43
|
it( 'Should return element with its child if a child exists', () => {
|
|
32
44
|
const input = Object.freeze( [
|
|
33
|
-
{ id: 2232, parent: 0 },
|
|
34
|
-
{ id: 2245, parent: 2232 },
|
|
45
|
+
{ id: 2232, name: 'foo', parent: 0 },
|
|
46
|
+
{ id: 2245, name: 'baz', parent: 2232 },
|
|
35
47
|
] );
|
|
36
48
|
const output = [
|
|
37
49
|
{
|
|
38
|
-
id: 2232,
|
|
50
|
+
id: '2232',
|
|
51
|
+
name: 'foo',
|
|
39
52
|
parent: 0,
|
|
40
|
-
children: [
|
|
53
|
+
children: [
|
|
54
|
+
{ id: '2245', name: 'baz', parent: 2232, children: [] },
|
|
55
|
+
],
|
|
41
56
|
},
|
|
42
57
|
];
|
|
43
58
|
const termsTreem = buildTermsTree( input );
|
|
@@ -45,21 +60,22 @@ describe( 'buildTermsTree()', () => {
|
|
|
45
60
|
} );
|
|
46
61
|
it( 'Should return elements with multiple children and elements with no children', () => {
|
|
47
62
|
const input = Object.freeze( [
|
|
48
|
-
{ id: 2232, parent: 0 },
|
|
49
|
-
{ id: 2245, parent: 2232 },
|
|
50
|
-
{ id: 2249, parent: 0 },
|
|
51
|
-
{ id: 2246, parent: 2232 },
|
|
63
|
+
{ id: 2232, name: 'a', parent: 0 },
|
|
64
|
+
{ id: 2245, name: 'b', parent: 2232 },
|
|
65
|
+
{ id: 2249, name: 'c', parent: 0 },
|
|
66
|
+
{ id: 2246, name: 'd', parent: 2232 },
|
|
52
67
|
] );
|
|
53
68
|
const output = [
|
|
54
69
|
{
|
|
55
|
-
id: 2232,
|
|
70
|
+
id: '2232',
|
|
71
|
+
name: 'a',
|
|
56
72
|
parent: 0,
|
|
57
73
|
children: [
|
|
58
|
-
{ id: 2245, parent: 2232, children: [] },
|
|
59
|
-
{ id: 2246, parent: 2232, children: [] },
|
|
74
|
+
{ id: '2245', name: 'b', parent: 2232, children: [] },
|
|
75
|
+
{ id: '2246', name: 'd', parent: 2232, children: [] },
|
|
60
76
|
],
|
|
61
77
|
},
|
|
62
|
-
{ id: 2249, parent: 0, children: [] },
|
|
78
|
+
{ id: '2249', name: 'c', parent: 0, children: [] },
|
|
63
79
|
];
|
|
64
80
|
const termsTreem = buildTermsTree( input );
|
|
65
81
|
expect( termsTreem ).toEqual( output );
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { FormTokenFieldProps } from '../form-token-field/types';
|
|
5
|
+
import type { TreeSelectProps } from '../tree-select/types';
|
|
6
|
+
|
|
7
|
+
export type Author = {
|
|
8
|
+
id: number;
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type Category = {
|
|
13
|
+
id: number;
|
|
14
|
+
name: string;
|
|
15
|
+
parent: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type TermWithParentAndChildren = {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
parent: number | null;
|
|
22
|
+
children: TermWithParentAndChildren[];
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type TermsByParent = Record< string, TermWithParentAndChildren[] >;
|
|
26
|
+
|
|
27
|
+
export type CategorySelectProps = Pick<
|
|
28
|
+
TreeSelectProps,
|
|
29
|
+
'label' | 'noOptionLabel'
|
|
30
|
+
> & {
|
|
31
|
+
categoriesList: Category[];
|
|
32
|
+
onChange: ( newCategory: string ) => void;
|
|
33
|
+
selectedCategoryId?: Category[ 'id' ];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type AuthorSelectProps = Pick<
|
|
37
|
+
TreeSelectProps,
|
|
38
|
+
'label' | 'noOptionLabel'
|
|
39
|
+
> & {
|
|
40
|
+
authorList?: Author[];
|
|
41
|
+
onChange: ( newAuthor: string ) => void;
|
|
42
|
+
selectedAuthorId?: Author[ 'id' ];
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type Order = 'asc' | 'desc';
|
|
46
|
+
type OrderBy = 'date' | 'title';
|
|
47
|
+
|
|
48
|
+
type BaseQueryControlsProps = {
|
|
49
|
+
/**
|
|
50
|
+
* An array of the authors to select from.
|
|
51
|
+
*/
|
|
52
|
+
authorList?: AuthorSelectProps[ 'authorList' ];
|
|
53
|
+
/**
|
|
54
|
+
* The maximum number of items.
|
|
55
|
+
*
|
|
56
|
+
* @default 100
|
|
57
|
+
*/
|
|
58
|
+
maxItems?: number;
|
|
59
|
+
/**
|
|
60
|
+
* The minimum number of items.
|
|
61
|
+
*
|
|
62
|
+
* @default 1
|
|
63
|
+
*/
|
|
64
|
+
minItems?: number;
|
|
65
|
+
/**
|
|
66
|
+
* The selected number of items to retrieve via the query.
|
|
67
|
+
*/
|
|
68
|
+
numberOfItems?: number;
|
|
69
|
+
/**
|
|
70
|
+
* A function that receives the new author value.
|
|
71
|
+
* If not specified, the author controls are not rendered.
|
|
72
|
+
*/
|
|
73
|
+
onAuthorChange?: AuthorSelectProps[ 'onChange' ];
|
|
74
|
+
/**
|
|
75
|
+
* A function that receives the new number of items.
|
|
76
|
+
* If not specified, then the number of items
|
|
77
|
+
* range control is not rendered.
|
|
78
|
+
*/
|
|
79
|
+
onNumberOfItemsChange?: ( newNumber?: number ) => void;
|
|
80
|
+
/**
|
|
81
|
+
* A function that receives the new order value.
|
|
82
|
+
* If this prop or the `onOrderByChange` prop are not specified,
|
|
83
|
+
* then the order controls are not rendered.
|
|
84
|
+
*/
|
|
85
|
+
onOrderChange?: ( newOrder: Order ) => void;
|
|
86
|
+
/**
|
|
87
|
+
* A function that receives the new orderby value.
|
|
88
|
+
* If this prop or the `onOrderChange` prop are not specified,
|
|
89
|
+
* then the order controls are not rendered.
|
|
90
|
+
*/
|
|
91
|
+
onOrderByChange?: ( newOrderBy: OrderBy ) => void;
|
|
92
|
+
/**
|
|
93
|
+
* The order in which to retrieve posts.
|
|
94
|
+
*/
|
|
95
|
+
order?: Order;
|
|
96
|
+
/**
|
|
97
|
+
* The meta key by which to order posts.
|
|
98
|
+
*/
|
|
99
|
+
orderBy?: OrderBy;
|
|
100
|
+
/**
|
|
101
|
+
* The selected author ID.
|
|
102
|
+
*/
|
|
103
|
+
selectedAuthorId?: AuthorSelectProps[ 'selectedAuthorId' ];
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export type QueryControlsWithSingleCategorySelectionProps =
|
|
107
|
+
BaseQueryControlsProps & {
|
|
108
|
+
/**
|
|
109
|
+
* An array of categories. When passed in conjunction with the
|
|
110
|
+
* `onCategoryChange` prop, it causes the component to render UI that allows
|
|
111
|
+
* selecting one category at a time.
|
|
112
|
+
*/
|
|
113
|
+
categoriesList?: CategorySelectProps[ 'categoriesList' ];
|
|
114
|
+
/**
|
|
115
|
+
* The selected category for the `categoriesList` prop.
|
|
116
|
+
*/
|
|
117
|
+
selectedCategoryId?: CategorySelectProps[ 'selectedCategoryId' ];
|
|
118
|
+
/**
|
|
119
|
+
* A function that receives the new category value. If not specified, the
|
|
120
|
+
* category controls are not rendered.
|
|
121
|
+
* The function's signature changes depending on whether multiple category
|
|
122
|
+
* selection is enabled or not.
|
|
123
|
+
*/
|
|
124
|
+
onCategoryChange?: CategorySelectProps[ 'onChange' ];
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export type QueryControlsWithMultipleCategorySelectionProps =
|
|
128
|
+
BaseQueryControlsProps & {
|
|
129
|
+
/**
|
|
130
|
+
* An object of categories with the category name as the key. When passed in
|
|
131
|
+
* conjunction with the `onCategoryChange` prop, it causes the component to
|
|
132
|
+
* render UI that enables multiple selection.
|
|
133
|
+
*/
|
|
134
|
+
categorySuggestions?: Record< Category[ 'name' ], Category >;
|
|
135
|
+
/**
|
|
136
|
+
* The selected categories for the `categorySuggestions` prop.
|
|
137
|
+
*/
|
|
138
|
+
selectedCategories?: Category[];
|
|
139
|
+
/**
|
|
140
|
+
* A function that receives the new category value. If not specified, the
|
|
141
|
+
* category controls are not rendered.
|
|
142
|
+
* The function's signature changes depending on whether multiple category
|
|
143
|
+
* selection is enabled or not.
|
|
144
|
+
*/
|
|
145
|
+
onCategoryChange?: FormTokenFieldProps[ 'onChange' ];
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export type QueryControlsProps =
|
|
149
|
+
| QueryControlsWithSingleCategorySelectionProps
|
|
150
|
+
| QueryControlsWithMultipleCategorySelectionProps;
|
|
@@ -9,12 +9,7 @@ import userEvent from '@testing-library/user-event';
|
|
|
9
9
|
*/
|
|
10
10
|
import SelectControl from '..';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const setupUser = () =>
|
|
15
|
-
userEvent.setup( {
|
|
16
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
17
|
-
} );
|
|
12
|
+
const setupUser = () => userEvent.setup();
|
|
18
13
|
|
|
19
14
|
describe( 'SelectControl', () => {
|
|
20
15
|
it( 'should not render when no options or children are provided', () => {
|
package/src/slot-fill/slot.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* WordPress dependencies
|
|
4
4
|
*/
|
|
5
|
-
import { useContext,
|
|
5
|
+
import { useContext, useSyncExternalStore } from '@wordpress/element';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Internal dependencies
|
|
@@ -17,21 +17,11 @@ import SlotFillContext from './context';
|
|
|
17
17
|
*/
|
|
18
18
|
const useSlot = ( name ) => {
|
|
19
19
|
const { getSlot, subscribe } = useContext( SlotFillContext );
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
setSlot( getSlot( name ) );
|
|
26
|
-
} );
|
|
27
|
-
|
|
28
|
-
return unsubscribe;
|
|
29
|
-
// Ignore reason: Modifying this dep array could introduce unexpected changes in behavior,
|
|
30
|
-
// so we'll leave it as=is until the hook can be properly refactored for exhaustive-deps.
|
|
31
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
32
|
-
}, [ name ] );
|
|
33
|
-
|
|
34
|
-
return slot;
|
|
20
|
+
return useSyncExternalStore(
|
|
21
|
+
subscribe,
|
|
22
|
+
() => getSlot( name ),
|
|
23
|
+
() => getSlot( name )
|
|
24
|
+
);
|
|
35
25
|
};
|
|
36
26
|
|
|
37
27
|
export default useSlot;
|
package/src/snackbar/index.tsx
CHANGED
|
@@ -16,7 +16,8 @@ import warning from '@wordpress/warning';
|
|
|
16
16
|
* Internal dependencies
|
|
17
17
|
*/
|
|
18
18
|
import Button from '../button';
|
|
19
|
-
import type {
|
|
19
|
+
import type { SnackbarProps } from './types';
|
|
20
|
+
import type { NoticeAction } from '../notice/types';
|
|
20
21
|
import type { WordPressComponentProps } from '../ui/context';
|
|
21
22
|
|
|
22
23
|
const NOTICE_TIMEOUT = 10000;
|
|
@@ -73,7 +74,7 @@ function UnforwardedSnackbar(
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
function onActionClick(
|
|
76
|
-
event: MouseEvent
|
|
77
|
+
event: MouseEvent< HTMLButtonElement >,
|
|
77
78
|
onClick: NoticeAction[ 'onClick' ]
|
|
78
79
|
) {
|
|
79
80
|
event.stopPropagation();
|
|
@@ -139,9 +140,9 @@ function UnforwardedSnackbar(
|
|
|
139
140
|
key={ index }
|
|
140
141
|
href={ url }
|
|
141
142
|
variant="tertiary"
|
|
142
|
-
onClick={ (
|
|
143
|
-
|
|
144
|
-
}
|
|
143
|
+
onClick={ (
|
|
144
|
+
event: MouseEvent< HTMLButtonElement >
|
|
145
|
+
) => onActionClick( event, onClick ) }
|
|
145
146
|
className="components-snackbar__action"
|
|
146
147
|
>
|
|
147
148
|
{ label }
|
package/src/snackbar/list.tsx
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
__unstableMotion as motion,
|
|
18
18
|
__unstableAnimatePresence as AnimatePresence,
|
|
19
19
|
} from '../animation';
|
|
20
|
-
import type {
|
|
20
|
+
import type { SnackbarListProps } from './types';
|
|
21
21
|
import type { WordPressComponentProps } from '../ui/context';
|
|
22
22
|
|
|
23
23
|
const SNACKBAR_VARIANTS = {
|
|
@@ -61,7 +61,9 @@ export function SnackbarList( {
|
|
|
61
61
|
const listRef = useRef< HTMLDivElement | null >( null );
|
|
62
62
|
const isReducedMotion = useReducedMotion();
|
|
63
63
|
className = classnames( 'components-snackbar-list', className );
|
|
64
|
-
const removeNotice =
|
|
64
|
+
const removeNotice =
|
|
65
|
+
( notice: SnackbarListProps[ 'notices' ][ number ] ) => () =>
|
|
66
|
+
onRemove?.( notice.id );
|
|
65
67
|
return (
|
|
66
68
|
<div className={ className } tabIndex={ -1 } ref={ listRef }>
|
|
67
69
|
{ children }
|
package/src/snackbar/types.ts
CHANGED
|
@@ -1,116 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type { MutableRefObject, ReactNode
|
|
4
|
+
import type { MutableRefObject, ReactNode } from 'react';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
type NoticeActionWithOnClick = {
|
|
13
|
-
label: string;
|
|
14
|
-
url?: string;
|
|
15
|
-
onClick: ( event: SyntheticEvent ) => void;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
// TODO: move this type to the Notice component once it gets typed.
|
|
19
|
-
export type NoticeAction = NoticeActionWithURL | NoticeActionWithOnClick;
|
|
20
|
-
|
|
21
|
-
export type Notice = {
|
|
22
|
-
id: string;
|
|
23
|
-
spokenMessage: string;
|
|
24
|
-
actions: NoticeAction[];
|
|
25
|
-
icon?: ReactNode;
|
|
26
|
-
onDismiss?: () => void;
|
|
27
|
-
content: string;
|
|
28
|
-
isDismissible: boolean;
|
|
29
|
-
explicitDismiss: boolean;
|
|
30
|
-
};
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import type { NoticeProps, NoticeChildren } from '../notice/types';
|
|
31
10
|
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The displayed message of a notice.
|
|
35
|
-
*
|
|
36
|
-
* Also used as the spoken message for assistive technology,
|
|
37
|
-
* unless `spokenMessage` is provided as an alternative message.
|
|
38
|
-
*/
|
|
39
|
-
children: string;
|
|
40
|
-
/**
|
|
41
|
-
* Used to provide a custom spoken message.
|
|
42
|
-
*
|
|
43
|
-
* @default children
|
|
44
|
-
*/
|
|
45
|
-
spokenMessage?: Notice[ 'spokenMessage' ];
|
|
46
|
-
/**
|
|
47
|
-
* A politeness level for the notice's spoken message. Should be provided as
|
|
48
|
-
* one of the valid options for an `aria-live` attribute value. Note that this
|
|
49
|
-
* value should be considered a suggestion; assistive technologies may
|
|
50
|
-
* override it based on internal heuristics.
|
|
51
|
-
*
|
|
52
|
-
* A value of `'assertive'` is to be used for important, and usually
|
|
53
|
-
* time-sensitive, information. It will interrupt anything else the screen
|
|
54
|
-
* reader is announcing in that moment.
|
|
55
|
-
* A value of `'polite'` is to be used for advisory information. It should
|
|
56
|
-
* not interrupt what the screen reader is announcing in that moment
|
|
57
|
-
* (the "speech queue") or interrupt the current task.
|
|
58
|
-
*
|
|
59
|
-
* @see https://www.w3.org/TR/wai-aria-1.1/#aria-live
|
|
60
|
-
*
|
|
61
|
-
* @default 'polite'
|
|
62
|
-
*/
|
|
63
|
-
politeness?: 'polite' | 'assertive';
|
|
64
|
-
/**
|
|
65
|
-
* An array of action objects.
|
|
66
|
-
*
|
|
67
|
-
* Each member object should contain
|
|
68
|
-
* a `label` and either a `url` link string or `onClick` callback function.
|
|
69
|
-
*
|
|
70
|
-
* @default []
|
|
71
|
-
*/
|
|
72
|
-
actions?: Notice[ 'actions' ];
|
|
73
|
-
/**
|
|
74
|
-
* Called to remove the snackbar from the UI.
|
|
75
|
-
*/
|
|
76
|
-
onRemove?: () => void;
|
|
11
|
+
type SnackbarOnlyProps = {
|
|
77
12
|
/**
|
|
78
13
|
* The icon to render in the snackbar.
|
|
79
14
|
*
|
|
80
15
|
* @default null
|
|
81
16
|
*/
|
|
82
|
-
icon?:
|
|
17
|
+
icon?: ReactNode;
|
|
83
18
|
/**
|
|
84
19
|
* Whether to require user action to dismiss the snackbar.
|
|
85
20
|
* By default, this is dismissed on a timeout, without user interaction.
|
|
86
21
|
*
|
|
87
22
|
* @default false
|
|
88
23
|
*/
|
|
89
|
-
explicitDismiss?:
|
|
90
|
-
/**
|
|
91
|
-
* A callback executed when the snackbar is dismissed.
|
|
92
|
-
*
|
|
93
|
-
* It is distinct from onRemove, which _looks_ like a callback but is
|
|
94
|
-
* actually the function to call to remove the snackbar from the UI.
|
|
95
|
-
*/
|
|
96
|
-
onDismiss?: Notice[ 'onDismiss' ];
|
|
24
|
+
explicitDismiss?: boolean;
|
|
97
25
|
/**
|
|
98
26
|
* A ref to the list that contains the snackbar.
|
|
99
27
|
*/
|
|
100
28
|
listRef?: MutableRefObject< HTMLDivElement | null >;
|
|
101
29
|
};
|
|
102
30
|
|
|
31
|
+
export type SnackbarProps = NoticeProps & SnackbarOnlyProps;
|
|
32
|
+
|
|
103
33
|
export type SnackbarListProps = {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
children?:
|
|
112
|
-
/**
|
|
113
|
-
* Function called when a notice should be removed / dismissed.
|
|
114
|
-
*/
|
|
115
|
-
onRemove?: ( id: Notice[ 'id' ] ) => void;
|
|
34
|
+
notices: Array<
|
|
35
|
+
Omit< SnackbarProps, 'children' > & {
|
|
36
|
+
id: string;
|
|
37
|
+
content: string;
|
|
38
|
+
}
|
|
39
|
+
>;
|
|
40
|
+
onRemove: ( id: string ) => void;
|
|
41
|
+
children?: NoticeChildren | Array< NoticeChildren >;
|
|
116
42
|
};
|
package/src/tab-panel/index.tsx
CHANGED
|
@@ -25,7 +25,7 @@ const TabButton = ( {
|
|
|
25
25
|
}: TabButtonProps ) => (
|
|
26
26
|
<Button
|
|
27
27
|
role="tab"
|
|
28
|
-
tabIndex={ selected ?
|
|
28
|
+
tabIndex={ selected ? undefined : -1 }
|
|
29
29
|
aria-selected={ selected }
|
|
30
30
|
id={ tabId }
|
|
31
31
|
__experimentalIsFocusable
|
|
@@ -103,25 +103,47 @@ export function TabPanel( {
|
|
|
103
103
|
const selectedTab = tabs.find( ( { name } ) => name === selected );
|
|
104
104
|
const selectedId = `${ instanceId }-${ selectedTab?.name ?? 'none' }`;
|
|
105
105
|
|
|
106
|
+
// Handle selecting the initial tab.
|
|
106
107
|
useEffect( () => {
|
|
107
|
-
|
|
108
|
+
// If there's a selected tab, don't override it.
|
|
109
|
+
if ( selectedTab ) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
108
113
|
const initialTab = tabs.find( ( tab ) => tab.name === initialTabName );
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
114
|
+
|
|
115
|
+
// Wait for the denoted initial tab to be declared before making a
|
|
116
|
+
// selection. This ensures that if a tab is declared lazily it can
|
|
117
|
+
// still receive initial selection.
|
|
118
|
+
if ( initialTabName && ! initialTab ) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if ( initialTab && ! initialTab.disabled ) {
|
|
123
|
+
// Select the initial tab if it's not disabled.
|
|
124
|
+
handleTabSelection( initialTab.name );
|
|
125
|
+
} else {
|
|
126
|
+
// Fallback to the first enabled tab when the initial is disabled.
|
|
127
|
+
const firstEnabledTab = tabs.find( ( tab ) => ! tab.disabled );
|
|
128
|
+
if ( firstEnabledTab ) handleTabSelection( firstEnabledTab.name );
|
|
129
|
+
}
|
|
130
|
+
}, [ tabs, selectedTab, initialTabName, handleTabSelection ] );
|
|
131
|
+
|
|
132
|
+
// Handle the currently selected tab becoming disabled.
|
|
133
|
+
useEffect( () => {
|
|
134
|
+
// This effect only runs when the selected tab is defined and becomes disabled.
|
|
135
|
+
if ( ! selectedTab?.disabled ) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const firstEnabledTab = tabs.find( ( tab ) => ! tab.disabled );
|
|
140
|
+
|
|
141
|
+
// If the currently selected tab becomes disabled, select the first enabled tab.
|
|
142
|
+
// (if there is one).
|
|
143
|
+
if ( firstEnabledTab ) {
|
|
116
144
|
handleTabSelection( firstEnabledTab.name );
|
|
117
145
|
}
|
|
118
|
-
}, [
|
|
119
|
-
tabs,
|
|
120
|
-
selectedTab?.name,
|
|
121
|
-
selectedTab?.disabled,
|
|
122
|
-
initialTabName,
|
|
123
|
-
handleTabSelection,
|
|
124
|
-
] );
|
|
146
|
+
}, [ tabs, selectedTab?.disabled, handleTabSelection ] );
|
|
125
147
|
|
|
126
148
|
return (
|
|
127
149
|
<div className={ className }>
|
package/src/tab-panel/style.scss
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
&:focus:not(:disabled) {
|
|
25
25
|
position: relative;
|
|
26
26
|
box-shadow: none;
|
|
27
|
+
outline: none;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
// Tab indicator
|
|
@@ -48,6 +49,10 @@
|
|
|
48
49
|
// Active.
|
|
49
50
|
&.is-active::after {
|
|
50
51
|
height: calc(1 * var(--wp-admin-border-width-focus));
|
|
52
|
+
|
|
53
|
+
// Windows high contrast mode.
|
|
54
|
+
outline: 2px solid transparent;
|
|
55
|
+
outline-offset: -1px;
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
// Focus.
|
|
@@ -71,5 +76,8 @@
|
|
|
71
76
|
|
|
72
77
|
&:focus-visible::before {
|
|
73
78
|
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $components-color-accent;
|
|
79
|
+
|
|
80
|
+
// Windows high contrast mode.
|
|
81
|
+
outline: 2px solid transparent;
|
|
74
82
|
}
|
|
75
83
|
}
|