@wordpress/components 26.0.4 → 27.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.stylelintrc.js +2 -2
- package/CHANGELOG.md +45 -0
- package/CONTRIBUTING.md +72 -0
- package/build/autocomplete/index.js +3 -8
- package/build/autocomplete/index.js.map +1 -1
- package/build/base-control/index.native.js.map +1 -1
- package/build/border-box-control/border-box-control/component.js.map +1 -1
- package/build/border-box-control/border-box-control-split-controls/component.js.map +1 -1
- package/build/border-control/border-control-dropdown/component.js.map +1 -1
- package/build/button/index.js +2 -2
- package/build/button/index.js.map +1 -1
- package/build/button/index.native.js.map +1 -1
- package/build/color-picker/component.js +10 -1
- package/build/color-picker/component.js.map +1 -1
- package/build/color-picker/styles.js +8 -9
- package/build/color-picker/styles.js.map +1 -1
- package/build/combobox-control/index.js +4 -9
- package/build/combobox-control/index.js.map +1 -1
- package/build/confirm-dialog/component.js.map +1 -1
- package/build/custom-select-control/index.js +2 -15
- package/build/custom-select-control/index.js.map +1 -1
- package/build/custom-select-control-v2/custom-select-item.js +32 -0
- package/build/custom-select-control-v2/custom-select-item.js.map +1 -0
- package/build/custom-select-control-v2/custom-select.js +91 -0
- package/build/custom-select-control-v2/custom-select.js.map +1 -0
- package/build/custom-select-control-v2/default-component/index.js +41 -0
- package/build/custom-select-control-v2/default-component/index.js.map +1 -0
- package/build/custom-select-control-v2/index.js +13 -82
- package/build/custom-select-control-v2/index.js.map +1 -1
- package/build/custom-select-control-v2/legacy-component/index.js +123 -0
- package/build/custom-select-control-v2/legacy-component/index.js.map +1 -0
- package/build/custom-select-control-v2/styles.js +73 -50
- package/build/custom-select-control-v2/styles.js.map +1 -1
- package/build/custom-select-control-v2/types.js.map +1 -1
- package/build/draggable/index.native.js +2 -2
- package/build/draggable/index.native.js.map +1 -1
- package/build/dropdown-menu/index.native.js.map +1 -1
- package/build/flex/flex/hook.js +1 -1
- package/build/flex/flex/hook.js.map +1 -1
- package/build/font-size-picker/font-size-picker-select.js +0 -1
- package/build/font-size-picker/font-size-picker-select.js.map +1 -1
- package/build/font-size-picker/index.native.js.map +1 -1
- package/build/form-token-field/index.js +3 -8
- package/build/form-token-field/index.js.map +1 -1
- package/build/form-token-field/suggestions-list.js +5 -12
- package/build/form-token-field/suggestions-list.js.map +1 -1
- package/build/h-stack/hook.js +6 -1
- package/build/h-stack/hook.js.map +1 -1
- package/build/mobile/bottom-sheet/button.native.js.map +1 -1
- package/build/mobile/bottom-sheet/index.native.js.map +1 -1
- package/build/mobile/bottom-sheet/range-cell.native.js.map +1 -1
- package/build/mobile/bottom-sheet/stepper-cell/index.native.js.map +1 -1
- package/build/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
- package/build/mobile/bottom-sheet-text-control/index.native.js.map +1 -1
- package/build/mobile/gradient/index.native.js.map +1 -1
- package/build/mobile/image/index.native.js +4 -13
- package/build/mobile/image/index.native.js.map +1 -1
- package/build/mobile/keyboard-aware-flat-list/use-scroll-to-section.native.js +1 -1
- package/build/mobile/keyboard-aware-flat-list/use-scroll-to-section.native.js.map +1 -1
- package/build/mobile/media-edit/index.native.js.map +1 -1
- package/build/modal/index.js +2 -10
- package/build/modal/index.js.map +1 -1
- package/build/palette-edit/index.js.map +1 -1
- package/build/progress-bar/styles.js +5 -5
- package/build/progress-bar/styles.js.map +1 -1
- package/build/query-controls/index.native.js.map +1 -1
- package/build/range-control/index.js.map +1 -1
- package/build/search-control/index.native.js.map +1 -1
- package/build/snackbar/index.js +3 -2
- package/build/snackbar/index.js.map +1 -1
- package/build/snackbar/list.js +2 -1
- package/build/snackbar/list.js.map +1 -1
- package/build/snackbar/types.js.map +1 -1
- package/build/tabs/index.js +7 -7
- package/build/tabs/index.js.map +1 -1
- package/build/tabs/types.js.map +1 -1
- package/build/utils/hooks/index.js +0 -7
- package/build/utils/hooks/index.js.map +1 -1
- package/build/utils/with-ignore-ime-events.js +34 -0
- package/build/utils/with-ignore-ime-events.js.map +1 -0
- package/build-module/autocomplete/index.js +3 -8
- package/build-module/autocomplete/index.js.map +1 -1
- package/build-module/base-control/index.native.js.map +1 -1
- package/build-module/border-box-control/border-box-control/component.js.map +1 -1
- package/build-module/border-box-control/border-box-control-split-controls/component.js.map +1 -1
- package/build-module/border-control/border-control-dropdown/component.js.map +1 -1
- package/build-module/button/index.js +2 -2
- package/build-module/button/index.js.map +1 -1
- package/build-module/button/index.native.js.map +1 -1
- package/build-module/color-picker/component.js +11 -2
- package/build-module/color-picker/component.js.map +1 -1
- package/build-module/color-picker/styles.js +8 -9
- package/build-module/color-picker/styles.js.map +1 -1
- package/build-module/combobox-control/index.js +4 -9
- package/build-module/combobox-control/index.js.map +1 -1
- package/build-module/confirm-dialog/component.js.map +1 -1
- package/build-module/custom-select-control/index.js +2 -15
- package/build-module/custom-select-control/index.js.map +1 -1
- package/build-module/custom-select-control-v2/custom-select-item.js +26 -0
- package/build-module/custom-select-control-v2/custom-select-item.js.map +1 -0
- package/build-module/custom-select-control-v2/custom-select.js +82 -0
- package/build-module/custom-select-control-v2/custom-select.js.map +1 -0
- package/build-module/custom-select-control-v2/default-component/index.js +30 -0
- package/build-module/custom-select-control-v2/default-component/index.js.map +1 -0
- package/build-module/custom-select-control-v2/index.js +2 -74
- package/build-module/custom-select-control-v2/index.js.map +1 -1
- package/build-module/custom-select-control-v2/legacy-component/index.js +111 -0
- package/build-module/custom-select-control-v2/legacy-component/index.js.map +1 -0
- package/build-module/custom-select-control-v2/styles.js +73 -42
- package/build-module/custom-select-control-v2/styles.js.map +1 -1
- package/build-module/custom-select-control-v2/types.js.map +1 -1
- package/build-module/draggable/index.native.js +2 -2
- package/build-module/draggable/index.native.js.map +1 -1
- package/build-module/dropdown-menu/index.native.js.map +1 -1
- package/build-module/flex/flex/hook.js +1 -1
- package/build-module/flex/flex/hook.js.map +1 -1
- package/build-module/font-size-picker/font-size-picker-select.js +0 -1
- package/build-module/font-size-picker/font-size-picker-select.js.map +1 -1
- package/build-module/font-size-picker/index.native.js.map +1 -1
- package/build-module/form-token-field/index.js +3 -8
- package/build-module/form-token-field/index.js.map +1 -1
- package/build-module/form-token-field/suggestions-list.js +5 -12
- package/build-module/form-token-field/suggestions-list.js.map +1 -1
- package/build-module/h-stack/hook.js +6 -1
- package/build-module/h-stack/hook.js.map +1 -1
- package/build-module/mobile/bottom-sheet/button.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet/index.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet/range-cell.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet/stepper-cell/index.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet-text-control/index.native.js.map +1 -1
- package/build-module/mobile/gradient/index.native.js.map +1 -1
- package/build-module/mobile/image/index.native.js +6 -15
- package/build-module/mobile/image/index.native.js.map +1 -1
- package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-section.native.js +1 -1
- package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-section.native.js.map +1 -1
- package/build-module/mobile/media-edit/index.native.js.map +1 -1
- package/build-module/modal/index.js +3 -10
- package/build-module/modal/index.js.map +1 -1
- package/build-module/palette-edit/index.js.map +1 -1
- package/build-module/progress-bar/styles.js +5 -5
- package/build-module/progress-bar/styles.js.map +1 -1
- package/build-module/query-controls/index.native.js.map +1 -1
- package/build-module/range-control/index.js.map +1 -1
- package/build-module/search-control/index.native.js.map +1 -1
- package/build-module/snackbar/index.js +3 -2
- package/build-module/snackbar/index.js.map +1 -1
- package/build-module/snackbar/list.js +2 -1
- package/build-module/snackbar/list.js.map +1 -1
- package/build-module/snackbar/types.js.map +1 -1
- package/build-module/tabs/index.js +7 -7
- package/build-module/tabs/index.js.map +1 -1
- package/build-module/tabs/types.js.map +1 -1
- package/build-module/utils/hooks/index.js +0 -1
- package/build-module/utils/hooks/index.js.map +1 -1
- package/build-module/utils/with-ignore-ime-events.js +28 -0
- package/build-module/utils/with-ignore-ime-events.js.map +1 -0
- package/build-style/style-rtl.css +10 -2
- package/build-style/style.css +10 -2
- package/build-types/alignment-matrix-control/stories/index.story.d.ts +1 -1
- package/build-types/angle-picker-control/stories/index.story.d.ts +1 -1
- package/build-types/animate/stories/index.story.d.ts +7 -7
- package/build-types/autocomplete/index.d.ts.map +1 -1
- package/build-types/base-control/stories/index.story.d.ts +1 -1
- package/build-types/border-box-control/stories/index.story.d.ts +1 -1
- package/build-types/border-control/stories/index.story.d.ts +6 -6
- package/build-types/box-control/stories/index.story.d.ts +6 -6
- package/build-types/button/stories/e2e/index.story.d.ts +1 -1
- package/build-types/button/stories/index.story.d.ts +7 -7
- package/build-types/card/stories/index.story.d.ts +2 -2
- package/build-types/circular-option-picker/stories/index.story.d.ts +5 -5
- package/build-types/color-palette/stories/index.story.d.ts +3 -3
- package/build-types/color-picker/component.d.ts.map +1 -1
- package/build-types/color-picker/stories/index.story.d.ts +1 -1
- package/build-types/color-picker/styles.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 +2 -2
- package/build-types/confirm-dialog/stories/index.story.d.ts +2 -2
- package/build-types/custom-gradient-picker/stories/index.story.d.ts +1 -1
- package/build-types/custom-select-control/index.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/custom-select-item.d.ts +9 -0
- package/build-types/custom-select-control-v2/custom-select-item.d.ts.map +1 -0
- package/build-types/custom-select-control-v2/custom-select.d.ts +6 -0
- package/build-types/custom-select-control-v2/custom-select.d.ts.map +1 -0
- package/build-types/custom-select-control-v2/default-component/index.d.ts +6 -0
- package/build-types/custom-select-control-v2/default-component/index.d.ts.map +1 -0
- package/build-types/custom-select-control-v2/index.d.ts +5 -6
- package/build-types/custom-select-control-v2/index.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/legacy-component/index.d.ts +5 -0
- package/build-types/custom-select-control-v2/legacy-component/index.d.ts.map +1 -0
- package/build-types/custom-select-control-v2/legacy-component/test/index.d.ts +2 -0
- package/build-types/custom-select-control-v2/legacy-component/test/index.d.ts.map +1 -0
- package/build-types/custom-select-control-v2/stories/default.story.d.ts +30 -0
- package/build-types/custom-select-control-v2/stories/default.story.d.ts.map +1 -0
- package/build-types/custom-select-control-v2/stories/legacy.story.d.ts +12 -0
- package/build-types/custom-select-control-v2/stories/legacy.story.d.ts.map +1 -0
- package/build-types/custom-select-control-v2/styles.d.ts +31 -6
- package/build-types/custom-select-control-v2/styles.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/types.d.ts +136 -14
- package/build-types/custom-select-control-v2/types.d.ts.map +1 -1
- package/build-types/dimension-control/stories/index.story.d.ts +2 -2
- package/build-types/drop-zone/stories/index.story.d.ts +1 -1
- package/build-types/dropdown/stories/index.story.d.ts +3 -3
- package/build-types/dropdown-menu/stories/index.story.d.ts +2 -2
- package/build-types/dropdown-menu-v2/stories/index.story.d.ts.map +1 -1
- package/build-types/duotone-picker/stories/duotone-picker.story.d.ts +1 -1
- package/build-types/duotone-picker/stories/duotone-swatch.story.d.ts +3 -3
- package/build-types/flex/flex/hook.d.ts +2 -3
- package/build-types/flex/flex/hook.d.ts.map +1 -1
- package/build-types/focal-point-picker/stories/index.story.d.ts +4 -4
- package/build-types/font-size-picker/font-size-picker-select.d.ts.map +1 -1
- package/build-types/form-file-upload/stories/index.story.d.ts +5 -5
- package/build-types/form-token-field/index.d.ts.map +1 -1
- package/build-types/form-token-field/suggestions-list.d.ts.map +1 -1
- package/build-types/gradient-picker/stories/index.story.d.ts +3 -3
- package/build-types/guide/stories/index.story.d.ts +1 -1
- package/build-types/h-stack/hook.d.ts +2 -4
- package/build-types/h-stack/hook.d.ts.map +1 -1
- package/build-types/icon/stories/index.story.d.ts +4 -4
- package/build-types/input-control/stories/index.story.d.ts +6 -6
- package/build-types/keyboard-shortcuts/stories/index.story.d.ts +1 -1
- package/build-types/menu-group/stories/index.story.d.ts +1 -1
- package/build-types/menu-item/stories/index.story.d.ts +4 -4
- package/build-types/modal/index.d.ts.map +1 -1
- package/build-types/navigation/stories/index.story.d.ts +6 -6
- package/build-types/navigation/stories/utils/hide-if-empty.d.ts.map +1 -1
- package/build-types/notice/stories/index.story.d.ts +4 -4
- package/build-types/number-control/stories/index.story.d.ts +1 -1
- package/build-types/palette-edit/stories/index.story.d.ts +2 -2
- package/build-types/progress-bar/stories/index.story.d.ts.map +1 -1
- package/build-types/query-controls/stories/index.story.d.ts +1 -1
- package/build-types/radio-group/stories/index.story.d.ts.map +1 -1
- package/build-types/resizable-box/stories/index.story.d.ts +2 -2
- package/build-types/responsive-wrapper/stories/index.story.d.ts +1 -1
- package/build-types/sandbox/stories/index.story.d.ts +1 -1
- package/build-types/search-control/stories/index.story.d.ts +2 -2
- package/build-types/select-control/stories/index.story.d.ts +2 -2
- package/build-types/shortcut/stories/index.story.d.ts +1 -1
- package/build-types/snackbar/index.d.ts +5 -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/test/index.d.ts +2 -0
- package/build-types/snackbar/test/index.d.ts.map +1 -0
- package/build-types/snackbar/test/list.d.ts +2 -0
- package/build-types/snackbar/test/list.d.ts.map +1 -0
- package/build-types/snackbar/types.d.ts +18 -2
- package/build-types/snackbar/types.d.ts.map +1 -1
- package/build-types/tab-panel/stories/index.story.d.ts +4 -4
- package/build-types/tabs/index.d.ts +1 -1
- package/build-types/tabs/stories/index.story.d.ts +9 -9
- package/build-types/tabs/stories/index.story.d.ts.map +1 -1
- package/build-types/tabs/types.d.ts +1 -1
- package/build-types/text/stories/index.story.d.ts +3 -3
- package/build-types/theme/stories/index.story.d.ts +1 -1
- package/build-types/theme/stories/index.story.d.ts.map +1 -1
- package/build-types/toggle-control/stories/index.story.d.ts +2 -2
- package/build-types/toolbar/stories/index.story.d.ts +3 -3
- package/build-types/tooltip/stories/index.story.d.ts +1 -1
- package/build-types/tree-grid/stories/index.story.d.ts +1 -1
- package/build-types/tree-select/stories/index.story.d.ts +1 -1
- package/build-types/utils/hooks/index.d.ts +0 -1
- package/build-types/utils/with-ignore-ime-events.d.ts +15 -0
- package/build-types/utils/with-ignore-ime-events.d.ts.map +1 -0
- package/build-types/v-stack/hook.d.ts +2 -4
- package/build-types/v-stack/hook.d.ts.map +1 -1
- package/build-types/v-stack/stories/index.story.d.ts +1 -1
- package/package.json +19 -20
- package/src/alignment-matrix-control/test/index.tsx +3 -1
- package/src/autocomplete/index.tsx +3 -10
- package/src/base-control/index.native.js +1 -1
- package/src/base-control/test/index.tsx +1 -1
- package/src/border-box-control/border-box-control/component.tsx +1 -1
- package/src/border-box-control/border-box-control-split-controls/component.tsx +4 -4
- package/src/border-control/border-control-dropdown/component.tsx +1 -1
- package/src/button/index.native.js +1 -1
- package/src/button/index.tsx +1 -1
- package/src/button/style.scss +1 -3
- package/src/circular-option-picker/test/index.tsx +6 -5
- package/src/color-picker/component.tsx +22 -11
- package/src/color-picker/styles.ts +1 -15
- package/src/combobox-control/index.tsx +33 -41
- package/src/combobox-control/test/index.tsx +1 -1
- package/src/composite/legacy/test/index.tsx +18 -2
- package/src/confirm-dialog/component.tsx +1 -1
- package/src/confirm-dialog/test/index.tsx +5 -21
- package/src/custom-select-control/README.md +0 -10
- package/src/custom-select-control/index.js +3 -22
- package/src/custom-select-control/stories/index.story.js +0 -1
- package/src/custom-select-control/test/index.js +17 -17
- package/src/custom-select-control-v2/README.md +97 -7
- package/src/custom-select-control-v2/custom-select-item.tsx +29 -0
- package/src/custom-select-control-v2/custom-select.tsx +122 -0
- package/src/custom-select-control-v2/default-component/index.tsx +27 -0
- package/src/custom-select-control-v2/index.tsx +2 -102
- package/src/custom-select-control-v2/legacy-component/index.tsx +133 -0
- package/src/custom-select-control-v2/legacy-component/test/index.tsx +457 -0
- package/src/custom-select-control-v2/stories/{index.story.tsx → default.story.tsx} +27 -33
- package/src/custom-select-control-v2/stories/legacy.story.tsx +87 -0
- package/src/custom-select-control-v2/styles.ts +82 -38
- package/src/custom-select-control-v2/test/index.tsx +207 -17
- package/src/custom-select-control-v2/types.ts +147 -20
- package/src/disabled/test/index.tsx +1 -1
- package/src/draggable/index.native.js +2 -2
- package/src/draggable/test/index.native.js +6 -2
- package/src/dropdown-menu/index.native.js +2 -2
- package/src/dropdown-menu-v2/stories/index.story.tsx +1 -0
- package/src/dropdown-menu-v2/test/index.tsx +4 -1
- package/src/flex/flex/hook.ts +1 -1
- package/src/font-size-picker/font-size-picker-select.tsx +0 -1
- package/src/font-size-picker/index.native.js +2 -2
- package/src/form-token-field/index.tsx +4 -11
- package/src/form-token-field/suggestions-list.tsx +5 -17
- package/src/h-stack/hook.tsx +2 -1
- package/src/h-stack/test/index.tsx +10 -0
- package/src/item-group/test/index.js +2 -2
- package/src/mobile/bottom-sheet/bottom-sheet-navigation/test/navigation-container.native.js +10 -15
- package/src/mobile/bottom-sheet/button.native.js +1 -5
- package/src/mobile/bottom-sheet/index.native.js +2 -2
- package/src/mobile/bottom-sheet/range-cell.native.js +1 -1
- package/src/mobile/bottom-sheet/stepper-cell/index.native.js +2 -2
- package/src/mobile/bottom-sheet-select-control/index.native.js +1 -1
- package/src/mobile/bottom-sheet-text-control/index.native.js +1 -1
- package/src/mobile/gradient/index.native.js +1 -1
- package/src/mobile/image/index.native.js +8 -23
- package/src/mobile/keyboard-aware-flat-list/use-scroll-to-section.native.js +1 -1
- package/src/mobile/media-edit/index.native.js +1 -1
- package/src/modal/index.tsx +2 -12
- package/src/modal/style.scss +1 -0
- package/src/modal/test/index.tsx +1 -1
- package/src/navigation/stories/utils/hide-if-empty.tsx +2 -6
- package/src/palette-edit/index.tsx +2 -2
- package/src/popover/test/index.tsx +1 -4
- package/src/progress-bar/stories/index.story.tsx +1 -0
- package/src/progress-bar/styles.ts +2 -2
- package/src/query-controls/index.native.js +2 -2
- package/src/radio-group/stories/index.story.tsx +1 -0
- package/src/range-control/index.tsx +3 -3
- package/src/range-control/test/index.tsx +2 -2
- package/src/search-control/index.native.js +1 -1
- package/src/snackbar/index.tsx +5 -2
- package/src/snackbar/list.tsx +6 -1
- package/src/snackbar/stories/list.story.tsx +0 -3
- package/src/snackbar/test/index.tsx +267 -0
- package/src/snackbar/test/list.tsx +46 -0
- package/src/snackbar/types.ts +31 -3
- package/src/tab-panel/test/index.tsx +8 -1
- package/src/tabs/README.md +18 -18
- package/src/tabs/index.tsx +7 -7
- package/src/tabs/stories/index.story.tsx +2 -1
- package/src/tabs/test/index.tsx +66 -36
- package/src/tabs/types.ts +1 -1
- package/src/theme/stories/index.story.tsx +1 -0
- package/src/toggle-group-control/test/index.tsx +5 -1
- package/src/toolbar/toolbar-group/style.scss +1 -0
- package/src/tools-panel/stories/index.story.tsx +8 -8
- package/src/tools-panel/test/index.tsx +10 -28
- package/src/tooltip/style.scss +2 -1
- package/src/tooltip/test/index.native.js +3 -3
- package/src/tooltip/test/index.tsx +5 -0
- package/src/tree-grid/test/index.tsx +1 -1
- package/src/utils/hooks/index.js +0 -1
- package/src/utils/with-ignore-ime-events.ts +32 -0
- package/src/v-stack/test/index.tsx +10 -0
- package/tsconfig.json +0 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/build/custom-select-control/styles.js +0 -27
- package/build/custom-select-control/styles.js.map +0 -1
- package/build/utils/hooks/use-latest-ref.js +0 -33
- package/build/utils/hooks/use-latest-ref.js.map +0 -1
- package/build-module/custom-select-control/styles.js +0 -18
- package/build-module/custom-select-control/styles.js.map +0 -1
- package/build-module/utils/hooks/use-latest-ref.js +0 -27
- package/build-module/utils/hooks/use-latest-ref.js.map +0 -1
- package/build-types/custom-select-control/styles.d.ts +0 -11
- package/build-types/custom-select-control/styles.d.ts.map +0 -1
- package/build-types/custom-select-control-v2/stories/index.story.d.ts +0 -20
- package/build-types/custom-select-control-v2/stories/index.story.d.ts.map +0 -1
- package/build-types/utils/hooks/use-latest-ref.d.ts +0 -15
- package/build-types/utils/hooks/use-latest-ref.d.ts.map +0 -1
- package/src/custom-select-control/styles.ts +0 -28
- package/src/utils/hooks/test/use-latest-ref.js +0 -119
- package/src/utils/hooks/use-latest-ref.ts +0 -29
package/src/tabs/README.md
CHANGED
|
@@ -14,7 +14,7 @@ Tabs organizes content across different screens, data sets, and interactions. It
|
|
|
14
14
|
|
|
15
15
|
#### Uncontrolled Mode
|
|
16
16
|
|
|
17
|
-
Tabs can be used in an uncontrolled mode, where the component manages its own state. In this mode, the `
|
|
17
|
+
Tabs can be used in an uncontrolled mode, where the component manages its own state. In this mode, the `defaultTabId` prop can be used to set the initially selected tab. If this prop is not set, the first tab will be selected by default. In addition, in most cases where the currently active tab becomes disabled or otherwise unavailable, uncontrolled mode will automatically fall back to selecting the first available tab.
|
|
18
18
|
|
|
19
19
|
```jsx
|
|
20
20
|
import { Tabs } from '@wordpress/components';
|
|
@@ -24,25 +24,25 @@ const onSelect = ( tabName ) => {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const MyUncontrolledTabs = () => (
|
|
27
|
-
<Tabs onSelect={onSelect}
|
|
28
|
-
<Tabs.TabList
|
|
29
|
-
<Tabs.Tab
|
|
27
|
+
<Tabs onSelect={ onSelect } defaultTabId="tab2">
|
|
28
|
+
<Tabs.TabList>
|
|
29
|
+
<Tabs.Tab tabId="tab1" title="Tab 1">
|
|
30
30
|
Tab 1
|
|
31
31
|
</Tabs.Tab>
|
|
32
|
-
<Tabs.Tab
|
|
32
|
+
<Tabs.Tab tabId="tab2" title="Tab 2">
|
|
33
33
|
Tab 2
|
|
34
34
|
</Tabs.Tab>
|
|
35
|
-
<Tabs.Tab
|
|
35
|
+
<Tabs.Tab tabId="tab3" title="Tab 3">
|
|
36
36
|
Tab 3
|
|
37
37
|
</Tabs.Tab>
|
|
38
38
|
</Tabs.TabList>
|
|
39
|
-
<Tabs.TabPanel
|
|
39
|
+
<Tabs.TabPanel tabId="tab1">
|
|
40
40
|
<p>Selected tab: Tab 1</p>
|
|
41
41
|
</Tabs.TabPanel>
|
|
42
|
-
<Tabs.TabPanel
|
|
42
|
+
<Tabs.TabPanel tabId="tab2">
|
|
43
43
|
<p>Selected tab: Tab 2</p>
|
|
44
44
|
</Tabs.TabPanel>
|
|
45
|
-
<Tabs.TabPanel
|
|
45
|
+
<Tabs.TabPanel tabId="tab3">
|
|
46
46
|
<p>Selected tab: Tab 3</p>
|
|
47
47
|
</Tabs.TabPanel>
|
|
48
48
|
</Tabs>
|
|
@@ -51,7 +51,7 @@ const MyUncontrolledTabs = () => (
|
|
|
51
51
|
|
|
52
52
|
#### Controlled Mode
|
|
53
53
|
|
|
54
|
-
Tabs can also be used in a controlled mode, where the parent component specifies the `selectedTabId` and the `onSelect` props to control tab selection. In this mode, the `
|
|
54
|
+
Tabs can also be used in a controlled mode, where the parent component specifies the `selectedTabId` and the `onSelect` props to control tab selection. In this mode, the `defaultTabId` prop will be ignored if it is provided. If the `selectedTabId` is `null`, no tab is selected. In this mode, if the currently selected tab becomes disabled or otherwise unavailable, the component will _not_ fall back to another available tab, leaving the controlling component in charge of implementing the desired logic.
|
|
55
55
|
|
|
56
56
|
```jsx
|
|
57
57
|
import { Tabs } from '@wordpress/components';
|
|
@@ -71,24 +71,24 @@ const MyControlledTabs = () => (
|
|
|
71
71
|
onSelect( selectedId );
|
|
72
72
|
} }
|
|
73
73
|
>
|
|
74
|
-
<Tabs.TabList
|
|
75
|
-
<Tabs.Tab
|
|
74
|
+
<Tabs.TabList>
|
|
75
|
+
<Tabs.Tab tabId="tab1" title="Tab 1">
|
|
76
76
|
Tab 1
|
|
77
77
|
</Tabs.Tab>
|
|
78
|
-
<Tabs.Tab
|
|
78
|
+
<Tabs.Tab tabId="tab2" title="Tab 2">
|
|
79
79
|
Tab 2
|
|
80
80
|
</Tabs.Tab>
|
|
81
|
-
<Tabs.Tab
|
|
81
|
+
<Tabs.Tab tabId="tab3" title="Tab 3">
|
|
82
82
|
Tab 3
|
|
83
83
|
</Tabs.Tab>
|
|
84
84
|
</Tabs.TabList>
|
|
85
|
-
<Tabs.TabPanel
|
|
85
|
+
<Tabs.TabPanel tabId="tab1">
|
|
86
86
|
<p>Selected tab: Tab 1</p>
|
|
87
87
|
</Tabs.TabPanel>
|
|
88
|
-
<Tabs.TabPanel
|
|
88
|
+
<Tabs.TabPanel tabId="tab2">
|
|
89
89
|
<p>Selected tab: Tab 2</p>
|
|
90
90
|
</Tabs.TabPanel>
|
|
91
|
-
<Tabs.TabPanel
|
|
91
|
+
<Tabs.TabPanel tabId="tab3">
|
|
92
92
|
<p>Selected tab: Tab 3</p>
|
|
93
93
|
</Tabs.TabPanel>
|
|
94
94
|
</Tabs>
|
|
@@ -120,7 +120,7 @@ When `true`, the tab will be selected when receiving focus (automatic tab activa
|
|
|
120
120
|
- Required: No
|
|
121
121
|
- Default: `true`
|
|
122
122
|
|
|
123
|
-
###### `
|
|
123
|
+
###### `defaultTabId`: `string`
|
|
124
124
|
|
|
125
125
|
The id of the tab to be selected upon mounting of component. If this prop is not set, the first tab will be selected by default. The id provided will be internally prefixed with a unique instance ID to avoid collisions.
|
|
126
126
|
|
package/src/tabs/index.tsx
CHANGED
|
@@ -26,7 +26,7 @@ import { TabPanel } from './tabpanel';
|
|
|
26
26
|
|
|
27
27
|
function Tabs( {
|
|
28
28
|
selectOnMove = true,
|
|
29
|
-
|
|
29
|
+
defaultTabId,
|
|
30
30
|
orientation = 'horizontal',
|
|
31
31
|
onSelect,
|
|
32
32
|
children,
|
|
@@ -36,7 +36,7 @@ function Tabs( {
|
|
|
36
36
|
const store = Ariakit.useTabStore( {
|
|
37
37
|
selectOnMove,
|
|
38
38
|
orientation,
|
|
39
|
-
defaultSelectedId:
|
|
39
|
+
defaultSelectedId: defaultTabId && `${ instanceId }-${ defaultTabId }`,
|
|
40
40
|
setSelectedId: ( selectedId ) => {
|
|
41
41
|
const strippedDownId =
|
|
42
42
|
typeof selectedId === 'string'
|
|
@@ -66,7 +66,7 @@ function Tabs( {
|
|
|
66
66
|
return ! item.dimmed;
|
|
67
67
|
} );
|
|
68
68
|
const initialTab = items.find(
|
|
69
|
-
( item ) => item.id === `${ instanceId }-${
|
|
69
|
+
( item ) => item.id === `${ instanceId }-${ defaultTabId }`
|
|
70
70
|
);
|
|
71
71
|
|
|
72
72
|
// Handle selecting the initial tab.
|
|
@@ -78,8 +78,8 @@ function Tabs( {
|
|
|
78
78
|
// Wait for the denoted initial tab to be declared before making a
|
|
79
79
|
// selection. This ensures that if a tab is declared lazily it can
|
|
80
80
|
// still receive initial selection, as well as ensuring no tab is
|
|
81
|
-
// selected if an invalid `
|
|
82
|
-
if (
|
|
81
|
+
// selected if an invalid `defaultTabId` is provided.
|
|
82
|
+
if ( defaultTabId && ! initialTab ) {
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -101,7 +101,7 @@ function Tabs( {
|
|
|
101
101
|
}, [
|
|
102
102
|
firstEnabledTab,
|
|
103
103
|
initialTab,
|
|
104
|
-
|
|
104
|
+
defaultTabId,
|
|
105
105
|
isControlled,
|
|
106
106
|
items,
|
|
107
107
|
selectedId,
|
|
@@ -122,7 +122,7 @@ function Tabs( {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
// If the currently selected tab becomes disabled, fall back to the
|
|
125
|
-
// `
|
|
125
|
+
// `defaultTabId` if possible. Otherwise select the first
|
|
126
126
|
// enabled tab (if there is one).
|
|
127
127
|
if ( initialTab && ! initialTab.dimmed ) {
|
|
128
128
|
setSelectedId( initialTab.id );
|
|
@@ -28,6 +28,7 @@ const meta: Meta< typeof Tabs > = {
|
|
|
28
28
|
// @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170
|
|
29
29
|
'Tabs.TabPanel': Tabs.TabPanel,
|
|
30
30
|
},
|
|
31
|
+
tags: [ 'status-private' ],
|
|
31
32
|
parameters: {
|
|
32
33
|
actions: { argTypesRegex: '^on.*' },
|
|
33
34
|
badges: [ 'private' ],
|
|
@@ -72,7 +73,7 @@ const DisabledTabTemplate: StoryFn< typeof Tabs > = ( props ) => {
|
|
|
72
73
|
return (
|
|
73
74
|
<Tabs { ...props }>
|
|
74
75
|
<Tabs.TabList>
|
|
75
|
-
<Tabs.Tab tabId="tab1" disabled
|
|
76
|
+
<Tabs.Tab tabId="tab1" disabled>
|
|
76
77
|
Tab 1
|
|
77
78
|
</Tabs.Tab>
|
|
78
79
|
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
|
package/src/tabs/test/index.tsx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
5
|
-
import { press, click } from '@ariakit/test';
|
|
5
|
+
import { press, click, sleep } from '@ariakit/test';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* WordPress dependencies
|
|
@@ -194,12 +194,14 @@ describe( 'Tabs', () => {
|
|
|
194
194
|
|
|
195
195
|
// Tab should initially focus the first tab in the tablist, which
|
|
196
196
|
// is Alpha.
|
|
197
|
+
await sleep();
|
|
197
198
|
await press.Tab();
|
|
198
199
|
expect(
|
|
199
200
|
await screen.findByRole( 'tab', { name: 'Alpha' } )
|
|
200
201
|
).toHaveFocus();
|
|
201
202
|
|
|
202
203
|
// By default the tabpanel should receive focus
|
|
204
|
+
await sleep();
|
|
203
205
|
await press.Tab();
|
|
204
206
|
expect( selectedTabPanel ).toHaveFocus();
|
|
205
207
|
} );
|
|
@@ -229,12 +231,14 @@ describe( 'Tabs', () => {
|
|
|
229
231
|
|
|
230
232
|
// Tab should initially focus the first tab in the tablist, which
|
|
231
233
|
// is Alpha.
|
|
234
|
+
await sleep();
|
|
232
235
|
await press.Tab();
|
|
233
236
|
expect(
|
|
234
237
|
await screen.findByRole( 'tab', { name: 'Alpha' } )
|
|
235
238
|
).toHaveFocus();
|
|
236
239
|
// Because the alpha tabpanel is set to `focusable: false`, pressing
|
|
237
240
|
// the Tab key should focus the button, not the tabpanel
|
|
241
|
+
await sleep();
|
|
238
242
|
await press.Tab();
|
|
239
243
|
expect( alphaButton ).toHaveFocus();
|
|
240
244
|
} );
|
|
@@ -305,6 +309,7 @@ describe( 'Tabs', () => {
|
|
|
305
309
|
// Tab to focus the tablist. Make sure alpha is focused.
|
|
306
310
|
expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
|
|
307
311
|
expect( await getSelectedTab() ).not.toHaveFocus();
|
|
312
|
+
await sleep();
|
|
308
313
|
await press.Tab();
|
|
309
314
|
expect( await getSelectedTab() ).toHaveFocus();
|
|
310
315
|
|
|
@@ -338,6 +343,7 @@ describe( 'Tabs', () => {
|
|
|
338
343
|
// Tab to focus the tablist. Make sure Alpha is focused.
|
|
339
344
|
expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
|
|
340
345
|
expect( await getSelectedTab() ).not.toHaveFocus();
|
|
346
|
+
await sleep();
|
|
341
347
|
await press.Tab();
|
|
342
348
|
expect( await getSelectedTab() ).toHaveFocus();
|
|
343
349
|
|
|
@@ -373,6 +379,7 @@ describe( 'Tabs', () => {
|
|
|
373
379
|
// Tab to focus the tablist. Make sure alpha is focused.
|
|
374
380
|
expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
|
|
375
381
|
expect( await getSelectedTab() ).not.toHaveFocus();
|
|
382
|
+
await sleep();
|
|
376
383
|
await press.Tab();
|
|
377
384
|
expect( await getSelectedTab() ).toHaveFocus();
|
|
378
385
|
|
|
@@ -472,6 +479,7 @@ describe( 'Tabs', () => {
|
|
|
472
479
|
// Tab to focus the tablist. Make sure Alpha is focused.
|
|
473
480
|
expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
|
|
474
481
|
expect( await getSelectedTab() ).not.toHaveFocus();
|
|
482
|
+
await sleep();
|
|
475
483
|
await press.Tab();
|
|
476
484
|
expect( await getSelectedTab() ).toHaveFocus();
|
|
477
485
|
// Confirm onSelect has not been re-called
|
|
@@ -514,6 +522,7 @@ describe( 'Tabs', () => {
|
|
|
514
522
|
|
|
515
523
|
// Tab should initially focus the first tab in the tablist, which
|
|
516
524
|
// is Alpha.
|
|
525
|
+
await sleep();
|
|
517
526
|
await press.Tab();
|
|
518
527
|
expect(
|
|
519
528
|
await screen.findByRole( 'tab', { name: 'Alpha' } )
|
|
@@ -522,6 +531,7 @@ describe( 'Tabs', () => {
|
|
|
522
531
|
// Because all other tabs should have `tabindex=-1`, pressing Tab
|
|
523
532
|
// should NOT move the focus to the next tab, which is Beta.
|
|
524
533
|
// Instead, focus should go to the currently selected tabpanel (alpha).
|
|
534
|
+
await sleep();
|
|
525
535
|
await press.Tab();
|
|
526
536
|
expect(
|
|
527
537
|
await screen.findByRole( 'tabpanel', {
|
|
@@ -588,7 +598,7 @@ describe( 'Tabs', () => {
|
|
|
588
598
|
} );
|
|
589
599
|
} );
|
|
590
600
|
describe( 'Uncontrolled mode', () => {
|
|
591
|
-
describe( 'Without `
|
|
601
|
+
describe( 'Without `defaultTabId` prop', () => {
|
|
592
602
|
it( 'should render first tab', async () => {
|
|
593
603
|
render( <UncontrolledTabs tabs={ TABS } /> );
|
|
594
604
|
|
|
@@ -645,20 +655,20 @@ describe( 'Tabs', () => {
|
|
|
645
655
|
} );
|
|
646
656
|
} );
|
|
647
657
|
|
|
648
|
-
describe( 'With `
|
|
649
|
-
it( 'should render the tab set by `
|
|
658
|
+
describe( 'With `defaultTabId`', () => {
|
|
659
|
+
it( 'should render the tab set by `defaultTabId` prop', async () => {
|
|
650
660
|
render(
|
|
651
|
-
<UncontrolledTabs tabs={ TABS }
|
|
661
|
+
<UncontrolledTabs tabs={ TABS } defaultTabId="beta" />
|
|
652
662
|
);
|
|
653
663
|
|
|
654
664
|
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
|
|
655
665
|
} );
|
|
656
666
|
|
|
657
|
-
it( 'should not select a tab when `
|
|
667
|
+
it( 'should not select a tab when `defaultTabId` does not match any known tab', () => {
|
|
658
668
|
render(
|
|
659
669
|
<UncontrolledTabs
|
|
660
670
|
tabs={ TABS }
|
|
661
|
-
|
|
671
|
+
defaultTabId="does-not-exist"
|
|
662
672
|
/>
|
|
663
673
|
);
|
|
664
674
|
|
|
@@ -672,25 +682,25 @@ describe( 'Tabs', () => {
|
|
|
672
682
|
screen.queryByRole( 'tabpanel' )
|
|
673
683
|
).not.toBeInTheDocument();
|
|
674
684
|
} );
|
|
675
|
-
it( 'should not change tabs when
|
|
685
|
+
it( 'should not change tabs when defaultTabId is changed', async () => {
|
|
676
686
|
const { rerender } = render(
|
|
677
|
-
<UncontrolledTabs tabs={ TABS }
|
|
687
|
+
<UncontrolledTabs tabs={ TABS } defaultTabId="beta" />
|
|
678
688
|
);
|
|
679
689
|
|
|
680
690
|
rerender(
|
|
681
|
-
<UncontrolledTabs tabs={ TABS }
|
|
691
|
+
<UncontrolledTabs tabs={ TABS } defaultTabId="alpha" />
|
|
682
692
|
);
|
|
683
693
|
|
|
684
694
|
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
|
|
685
695
|
} );
|
|
686
696
|
|
|
687
|
-
it( 'should fall back to the tab associated to `
|
|
697
|
+
it( 'should fall back to the tab associated to `defaultTabId` if the currently active tab is removed', async () => {
|
|
688
698
|
const mockOnSelect = jest.fn();
|
|
689
699
|
|
|
690
700
|
const { rerender } = render(
|
|
691
701
|
<UncontrolledTabs
|
|
692
702
|
tabs={ TABS }
|
|
693
|
-
|
|
703
|
+
defaultTabId="gamma"
|
|
694
704
|
onSelect={ mockOnSelect }
|
|
695
705
|
/>
|
|
696
706
|
);
|
|
@@ -704,7 +714,7 @@ describe( 'Tabs', () => {
|
|
|
704
714
|
rerender(
|
|
705
715
|
<UncontrolledTabs
|
|
706
716
|
tabs={ TABS.slice( 1 ) }
|
|
707
|
-
|
|
717
|
+
defaultTabId="gamma"
|
|
708
718
|
onSelect={ mockOnSelect }
|
|
709
719
|
/>
|
|
710
720
|
);
|
|
@@ -712,13 +722,13 @@ describe( 'Tabs', () => {
|
|
|
712
722
|
expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
|
|
713
723
|
} );
|
|
714
724
|
|
|
715
|
-
it( 'should fall back to the tab associated to `
|
|
725
|
+
it( 'should fall back to the tab associated to `defaultTabId` if the currently active tab becomes disabled', async () => {
|
|
716
726
|
const mockOnSelect = jest.fn();
|
|
717
727
|
|
|
718
728
|
const { rerender } = render(
|
|
719
729
|
<UncontrolledTabs
|
|
720
730
|
tabs={ TABS }
|
|
721
|
-
|
|
731
|
+
defaultTabId="gamma"
|
|
722
732
|
onSelect={ mockOnSelect }
|
|
723
733
|
/>
|
|
724
734
|
);
|
|
@@ -744,7 +754,7 @@ describe( 'Tabs', () => {
|
|
|
744
754
|
rerender(
|
|
745
755
|
<UncontrolledTabs
|
|
746
756
|
tabs={ TABS_WITH_ALPHA_DISABLED }
|
|
747
|
-
|
|
757
|
+
defaultTabId="gamma"
|
|
748
758
|
onSelect={ mockOnSelect }
|
|
749
759
|
/>
|
|
750
760
|
);
|
|
@@ -752,9 +762,9 @@ describe( 'Tabs', () => {
|
|
|
752
762
|
expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
|
|
753
763
|
} );
|
|
754
764
|
|
|
755
|
-
it( 'should have no active tabs when the tab associated to `
|
|
765
|
+
it( 'should have no active tabs when the tab associated to `defaultTabId` is removed while being the active tab', async () => {
|
|
756
766
|
const { rerender } = render(
|
|
757
|
-
<UncontrolledTabs tabs={ TABS }
|
|
767
|
+
<UncontrolledTabs tabs={ TABS } defaultTabId="gamma" />
|
|
758
768
|
);
|
|
759
769
|
|
|
760
770
|
expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
|
|
@@ -763,7 +773,7 @@ describe( 'Tabs', () => {
|
|
|
763
773
|
rerender(
|
|
764
774
|
<UncontrolledTabs
|
|
765
775
|
tabs={ TABS.slice( 0, 2 ) }
|
|
766
|
-
|
|
776
|
+
defaultTabId="gamma"
|
|
767
777
|
/>
|
|
768
778
|
);
|
|
769
779
|
|
|
@@ -778,9 +788,9 @@ describe( 'Tabs', () => {
|
|
|
778
788
|
).not.toBeInTheDocument();
|
|
779
789
|
} );
|
|
780
790
|
|
|
781
|
-
it( 'waits for the tab with the `
|
|
791
|
+
it( 'waits for the tab with the `defaultTabId` to be present in the `tabs` array before selecting it', async () => {
|
|
782
792
|
const { rerender } = render(
|
|
783
|
-
<UncontrolledTabs tabs={ TABS }
|
|
793
|
+
<UncontrolledTabs tabs={ TABS } defaultTabId="delta" />
|
|
784
794
|
);
|
|
785
795
|
|
|
786
796
|
// There should be no selected tab yet.
|
|
@@ -791,7 +801,7 @@ describe( 'Tabs', () => {
|
|
|
791
801
|
rerender(
|
|
792
802
|
<UncontrolledTabs
|
|
793
803
|
tabs={ TABS_WITH_DELTA }
|
|
794
|
-
|
|
804
|
+
defaultTabId="delta"
|
|
795
805
|
/>
|
|
796
806
|
);
|
|
797
807
|
|
|
@@ -832,6 +842,7 @@ describe( 'Tabs', () => {
|
|
|
832
842
|
expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
|
|
833
843
|
|
|
834
844
|
// Move focus to the tablist, make sure alpha is focused.
|
|
845
|
+
await sleep();
|
|
835
846
|
await press.Tab();
|
|
836
847
|
expect(
|
|
837
848
|
screen.getByRole( 'tab', { name: 'Alpha' } )
|
|
@@ -880,7 +891,7 @@ describe( 'Tabs', () => {
|
|
|
880
891
|
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
|
|
881
892
|
} );
|
|
882
893
|
|
|
883
|
-
it( 'should select first enabled tab when the tab associated to `
|
|
894
|
+
it( 'should select first enabled tab when the tab associated to `defaultTabId` is disabled', async () => {
|
|
884
895
|
const TABS_ONLY_GAMMA_ENABLED = TABS.map( ( tabObj ) =>
|
|
885
896
|
tabObj.tabId !== 'gamma'
|
|
886
897
|
? {
|
|
@@ -895,7 +906,7 @@ describe( 'Tabs', () => {
|
|
|
895
906
|
const { rerender } = render(
|
|
896
907
|
<UncontrolledTabs
|
|
897
908
|
tabs={ TABS_ONLY_GAMMA_ENABLED }
|
|
898
|
-
|
|
909
|
+
defaultTabId="beta"
|
|
899
910
|
/>
|
|
900
911
|
);
|
|
901
912
|
|
|
@@ -905,7 +916,7 @@ describe( 'Tabs', () => {
|
|
|
905
916
|
|
|
906
917
|
// Re-enable all tabs
|
|
907
918
|
rerender(
|
|
908
|
-
<UncontrolledTabs tabs={ TABS }
|
|
919
|
+
<UncontrolledTabs tabs={ TABS } defaultTabId="beta" />
|
|
909
920
|
);
|
|
910
921
|
|
|
911
922
|
// Even if the initial tab becomes enabled again, the selected tab doesn't
|
|
@@ -957,14 +968,14 @@ describe( 'Tabs', () => {
|
|
|
957
968
|
expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' );
|
|
958
969
|
} );
|
|
959
970
|
|
|
960
|
-
it( 'should select the first enabled tab when the tab associated to `
|
|
971
|
+
it( 'should select the first enabled tab when the tab associated to `defaultTabId` becomes disabled while being the active tab', async () => {
|
|
961
972
|
const mockOnSelect = jest.fn();
|
|
962
973
|
|
|
963
974
|
const { rerender } = render(
|
|
964
975
|
<UncontrolledTabs
|
|
965
976
|
tabs={ TABS }
|
|
966
977
|
onSelect={ mockOnSelect }
|
|
967
|
-
|
|
978
|
+
defaultTabId="gamma"
|
|
968
979
|
/>
|
|
969
980
|
);
|
|
970
981
|
|
|
@@ -987,7 +998,7 @@ describe( 'Tabs', () => {
|
|
|
987
998
|
<UncontrolledTabs
|
|
988
999
|
tabs={ TABS_WITH_GAMMA_DISABLED }
|
|
989
1000
|
onSelect={ mockOnSelect }
|
|
990
|
-
|
|
1001
|
+
defaultTabId="gamma"
|
|
991
1002
|
/>
|
|
992
1003
|
);
|
|
993
1004
|
|
|
@@ -1000,7 +1011,7 @@ describe( 'Tabs', () => {
|
|
|
1000
1011
|
<UncontrolledTabs
|
|
1001
1012
|
tabs={ TABS }
|
|
1002
1013
|
onSelect={ mockOnSelect }
|
|
1003
|
-
|
|
1014
|
+
defaultTabId="gamma"
|
|
1004
1015
|
/>
|
|
1005
1016
|
);
|
|
1006
1017
|
|
|
@@ -1021,12 +1032,12 @@ describe( 'Tabs', () => {
|
|
|
1021
1032
|
await screen.findByRole( 'tabpanel', { name: 'Beta' } )
|
|
1022
1033
|
).toBeInTheDocument();
|
|
1023
1034
|
} );
|
|
1024
|
-
it( 'should render the specified `selectedTabId`, and ignore the `
|
|
1035
|
+
it( 'should render the specified `selectedTabId`, and ignore the `defaultTabId` prop', async () => {
|
|
1025
1036
|
render(
|
|
1026
1037
|
<ControlledTabs
|
|
1027
1038
|
tabs={ TABS }
|
|
1028
1039
|
selectedTabId="gamma"
|
|
1029
|
-
|
|
1040
|
+
defaultTabId="beta"
|
|
1030
1041
|
/>
|
|
1031
1042
|
);
|
|
1032
1043
|
|
|
@@ -1185,10 +1196,18 @@ describe( 'Tabs', () => {
|
|
|
1185
1196
|
/>
|
|
1186
1197
|
);
|
|
1187
1198
|
|
|
1199
|
+
// Due to the timing of the component re-rendering, we
|
|
1200
|
+
// need to force a delay to ensure the test doesn't run
|
|
1201
|
+
// the upcoming assertions too early.
|
|
1202
|
+
// see https://github.com/WordPress/gutenberg/pull/58629#issuecomment-1924875249
|
|
1203
|
+
await sleep();
|
|
1204
|
+
|
|
1188
1205
|
// Tab key should focus the currently selected tab, which is Beta.
|
|
1189
1206
|
await press.Tab();
|
|
1190
|
-
|
|
1191
|
-
|
|
1207
|
+
await waitFor( async () =>
|
|
1208
|
+
expect( await getSelectedTab() ).toHaveTextContent(
|
|
1209
|
+
'Beta'
|
|
1210
|
+
)
|
|
1192
1211
|
);
|
|
1193
1212
|
expect( await getSelectedTab() ).toHaveFocus();
|
|
1194
1213
|
|
|
@@ -1201,9 +1220,11 @@ describe( 'Tabs', () => {
|
|
|
1201
1220
|
);
|
|
1202
1221
|
|
|
1203
1222
|
// When the selected tab is changed, it should not automatically receive focus.
|
|
1223
|
+
|
|
1204
1224
|
expect( await getSelectedTab() ).toHaveTextContent(
|
|
1205
1225
|
'Gamma'
|
|
1206
1226
|
);
|
|
1227
|
+
|
|
1207
1228
|
expect(
|
|
1208
1229
|
screen.getByRole( 'tab', { name: 'Beta' } )
|
|
1209
1230
|
).toHaveFocus();
|
|
@@ -1228,7 +1249,9 @@ describe( 'Tabs', () => {
|
|
|
1228
1249
|
);
|
|
1229
1250
|
|
|
1230
1251
|
// Tab key should focus the currently selected tab, which is Beta.
|
|
1252
|
+
await sleep();
|
|
1231
1253
|
await press.Tab();
|
|
1254
|
+
await sleep();
|
|
1232
1255
|
await press.Tab();
|
|
1233
1256
|
expect( await getSelectedTab() ).toHaveTextContent(
|
|
1234
1257
|
'Beta'
|
|
@@ -1247,9 +1270,11 @@ describe( 'Tabs', () => {
|
|
|
1247
1270
|
);
|
|
1248
1271
|
|
|
1249
1272
|
// When the selected tab is changed, it should not automatically receive focus.
|
|
1273
|
+
|
|
1250
1274
|
expect( await getSelectedTab() ).toHaveTextContent(
|
|
1251
1275
|
'Gamma'
|
|
1252
1276
|
);
|
|
1277
|
+
|
|
1253
1278
|
expect(
|
|
1254
1279
|
screen.getByRole( 'tab', { name: 'Beta' } )
|
|
1255
1280
|
).toHaveFocus();
|
|
@@ -1261,6 +1286,7 @@ describe( 'Tabs', () => {
|
|
|
1261
1286
|
).toHaveFocus();
|
|
1262
1287
|
|
|
1263
1288
|
// Press tab, move focus back to the tablist
|
|
1289
|
+
await sleep();
|
|
1264
1290
|
await press.Tab();
|
|
1265
1291
|
|
|
1266
1292
|
const betaTab = screen.getByRole( 'tab', {
|
|
@@ -1282,6 +1308,7 @@ describe( 'Tabs', () => {
|
|
|
1282
1308
|
it( 'should automatically select a newly focused tab', async () => {
|
|
1283
1309
|
render( <ControlledTabs tabs={ TABS } selectedTabId="beta" /> );
|
|
1284
1310
|
|
|
1311
|
+
await sleep();
|
|
1285
1312
|
await press.Tab();
|
|
1286
1313
|
|
|
1287
1314
|
// Tab key should focus the currently selected tab, which is Beta.
|
|
@@ -1307,10 +1334,13 @@ describe( 'Tabs', () => {
|
|
|
1307
1334
|
expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
|
|
1308
1335
|
|
|
1309
1336
|
// Tab key should focus the currently selected tab, which is Beta.
|
|
1337
|
+
await sleep();
|
|
1310
1338
|
await press.Tab();
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1339
|
+
await waitFor( async () =>
|
|
1340
|
+
expect(
|
|
1341
|
+
await screen.findByRole( 'tab', { name: 'Beta' } )
|
|
1342
|
+
).toHaveFocus()
|
|
1343
|
+
);
|
|
1314
1344
|
|
|
1315
1345
|
// Arrow key should move focus but not automatically change the selected tab.
|
|
1316
1346
|
await press.ArrowRight();
|
package/src/tabs/types.ts
CHANGED
|
@@ -43,7 +43,7 @@ export type TabsProps = {
|
|
|
43
43
|
* Note: this prop will be overridden by the `selectedTabId` prop if it is
|
|
44
44
|
* provided. (Controlled Mode)
|
|
45
45
|
*/
|
|
46
|
-
|
|
46
|
+
defaultTabId?: string;
|
|
47
47
|
/**
|
|
48
48
|
* The function called when a tab has been selected.
|
|
49
49
|
* It is passed the id of the newly selected tab as an argument.
|
|
@@ -71,7 +71,7 @@ const optionsWithTooltip = (
|
|
|
71
71
|
value="gnocchi"
|
|
72
72
|
label="Delicious Gnocchi"
|
|
73
73
|
aria-label="Click for Delicious Gnocchi"
|
|
74
|
-
showTooltip
|
|
74
|
+
showTooltip
|
|
75
75
|
/>
|
|
76
76
|
<ToggleGroupControlOption
|
|
77
77
|
value="caponata"
|
|
@@ -334,9 +334,11 @@ describe.each( [
|
|
|
334
334
|
name: 'R',
|
|
335
335
|
} );
|
|
336
336
|
|
|
337
|
+
await sleep();
|
|
337
338
|
await press.Tab();
|
|
338
339
|
expect( rigas ).toHaveFocus();
|
|
339
340
|
|
|
341
|
+
await sleep();
|
|
340
342
|
await press.Tab();
|
|
341
343
|
|
|
342
344
|
// When in controlled mode, there is an additional "Reset" button.
|
|
@@ -392,6 +394,7 @@ describe.each( [
|
|
|
392
394
|
</Component>
|
|
393
395
|
);
|
|
394
396
|
|
|
397
|
+
await sleep();
|
|
395
398
|
await press.Tab();
|
|
396
399
|
expect(
|
|
397
400
|
screen.getByRole( 'button', {
|
|
@@ -400,6 +403,7 @@ describe.each( [
|
|
|
400
403
|
} )
|
|
401
404
|
).toHaveFocus();
|
|
402
405
|
|
|
406
|
+
await sleep();
|
|
403
407
|
await press.Tab();
|
|
404
408
|
expect(
|
|
405
409
|
screen.getByRole( 'button', {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
// Icons are 36px, as set by a 24px icon and 12px padding.
|
|
21
21
|
.components-button.components-button, // This needs specificity to override padding values inherited from the button component.
|
|
22
22
|
.components-button.has-icon.has-icon {
|
|
23
|
+
justify-content: center;
|
|
23
24
|
min-width: $block-toolbar-height - $grid-unit-15;
|
|
24
25
|
padding-left: $grid-unit-15 * 0.5; // 6px.
|
|
25
26
|
padding-right: $grid-unit-15 * 0.5;
|