@wordpress/components 25.14.0 → 25.15.1-next.79a6196f.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/CONTRIBUTING.md +57 -115
- package/LICENSE.md +1 -1
- package/build/base-control/index.js +17 -13
- package/build/base-control/index.js.map +1 -1
- package/build/border-box-control/border-box-control-linked-button/component.js +1 -1
- package/build/border-box-control/border-box-control-linked-button/component.js.map +1 -1
- package/build/border-control/border-control-style-picker/component.js +1 -1
- package/build/border-control/border-control-style-picker/component.js.map +1 -1
- package/build/box-control/index.js +1 -1
- package/build/box-control/index.js.map +1 -1
- package/build/box-control/linked-button.js +1 -1
- package/build/box-control/linked-button.js.map +1 -1
- package/build/button/index.js +1 -1
- package/build/button/index.js.map +1 -1
- package/build/color-palette/index.native.js +11 -7
- package/build/color-palette/index.native.js.map +1 -1
- package/build/color-picker/color-copy-button.js +1 -1
- package/build/color-picker/color-copy-button.js.map +1 -1
- package/build/context/wordpress-component.js.map +1 -1
- package/build/custom-select-control-v2/index.js +11 -10
- package/build/custom-select-control-v2/index.js.map +1 -1
- package/build/date-time/date/styles.js +8 -8
- package/build/date-time/date/styles.js.map +1 -1
- package/build/dropdown-menu-v2/index.js +205 -159
- package/build/dropdown-menu-v2/index.js.map +1 -1
- package/build/dropdown-menu-v2/styles.js +86 -77
- package/build/dropdown-menu-v2/styles.js.map +1 -1
- package/build/dropdown-menu-v2/types.js.map +1 -1
- package/build/duotone-picker/duotone-picker.js +4 -3
- package/build/duotone-picker/duotone-picker.js.map +1 -1
- package/build/font-size-picker/index.js +4 -2
- package/build/font-size-picker/index.js.map +1 -1
- package/build/font-size-picker/index.native.js +6 -3
- package/build/font-size-picker/index.native.js.map +1 -1
- package/build/form-token-field/index.js +10 -5
- package/build/form-token-field/index.js.map +1 -1
- package/build/form-token-field/token.js +1 -0
- package/build/form-token-field/token.js.map +1 -1
- package/build/gradient-picker/index.js +3 -2
- package/build/gradient-picker/index.js.map +1 -1
- package/build/index.native.js +20 -3
- package/build/index.native.js.map +1 -1
- package/build/input-control/styles/input-control-styles.js +32 -29
- package/build/input-control/styles/input-control-styles.js.map +1 -1
- package/build/input-control/types.js.map +1 -1
- package/build/lock-unlock.js +18 -0
- package/build/lock-unlock.js.map +1 -0
- package/build/mobile/bottom-sheet/index.native.js +8 -0
- package/build/mobile/bottom-sheet/index.native.js.map +1 -1
- package/build/mobile/color-settings/palette.screen.native.js +8 -4
- package/build/mobile/color-settings/palette.screen.native.js.map +1 -1
- package/build/mobile/global-styles-context/utils.native.js +26 -13
- package/build/mobile/global-styles-context/utils.native.js.map +1 -1
- package/build/mobile/image/constants.js +12 -0
- package/build/mobile/image/constants.js.map +1 -0
- package/build/mobile/image/index.native.js +26 -18
- package/build/mobile/image/index.native.js.map +1 -1
- package/build/mobile/keyboard-aware-flat-list/index.android.js +40 -8
- package/build/mobile/keyboard-aware-flat-list/index.android.js.map +1 -1
- package/build/mobile/keyboard-aware-flat-list/index.ios.js +44 -68
- package/build/mobile/keyboard-aware-flat-list/index.ios.js.map +1 -1
- package/build/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js +39 -0
- package/build/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js.map +1 -0
- package/build/mobile/keyboard-aware-flat-list/{use-scroll-to-text-input.native.js → use-scroll-to-section.native.js} +22 -29
- package/build/mobile/keyboard-aware-flat-list/use-scroll-to-section.native.js.map +1 -0
- package/build/mobile/keyboard-aware-flat-list/use-scroll.native.js +93 -0
- package/build/mobile/keyboard-aware-flat-list/use-scroll.native.js.map +1 -0
- package/build/mobile/utils/get-px-from-css-unit.native.js +302 -0
- package/build/mobile/utils/get-px-from-css-unit.native.js.map +1 -0
- package/build/modal/index.js +18 -13
- package/build/modal/index.js.map +1 -1
- package/build/navigation/menu/menu-title.js +1 -1
- package/build/navigation/menu/menu-title.js.map +1 -1
- package/build/navigator/navigator-provider/component.js +13 -15
- package/build/navigator/navigator-provider/component.js.map +1 -1
- package/build/navigator/navigator-screen/component.js +23 -63
- package/build/navigator/navigator-screen/component.js.map +1 -1
- package/build/navigator/styles.js +52 -0
- package/build/navigator/styles.js.map +1 -0
- package/build/number-control/index.js +4 -8
- package/build/number-control/index.js.map +1 -1
- package/build/number-control/types.js.map +1 -1
- package/build/palette-edit/index.js +15 -54
- package/build/palette-edit/index.js.map +1 -1
- package/build/private-apis.js +11 -26
- package/build/private-apis.js.map +1 -1
- package/build/private-apis.native.js +21 -0
- package/build/private-apis.native.js.map +1 -0
- package/build/radio-control/index.js +1 -0
- package/build/radio-control/index.js.map +1 -1
- package/build/range-control/index.js +1 -1
- package/build/range-control/index.js.map +1 -1
- package/build/select-control/styles/select-control-styles.js +15 -25
- package/build/select-control/styles/select-control-styles.js.map +1 -1
- package/build/slot-fill/index.js +3 -2
- package/build/slot-fill/index.js.map +1 -1
- package/build/slot-fill/types.js.map +1 -1
- package/build/snackbar/types.js.map +1 -1
- package/build/tabs/styles.js +3 -3
- package/build/tabs/styles.js.map +1 -1
- package/build/tabs/tabpanel.js +9 -7
- package/build/tabs/tabpanel.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control/component.js +4 -4
- package/build/toggle-group-control/toggle-group-control/component.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control/styles.js +29 -15
- package/build/toggle-group-control/toggle-group-control/styles.js.map +1 -1
- package/build/toggle-group-control/toggle-group-control-option-base/styles.js +9 -9
- package/build/toggle-group-control/toggle-group-control-option-base/styles.js.map +1 -1
- package/build/tools-panel/tools-panel/component.js +3 -1
- package/build/tools-panel/tools-panel/component.js.map +1 -1
- package/build/tools-panel/tools-panel-header/component.js +9 -8
- package/build/tools-panel/tools-panel-header/component.js.map +1 -1
- package/build/tools-panel/types.js.map +1 -1
- package/build/tooltip/index.js +34 -10
- package/build/tooltip/index.js.map +1 -1
- package/build/tooltip/types.js.map +1 -1
- package/build/truncate/hook.js +10 -4
- package/build/truncate/hook.js.map +1 -1
- package/build/truncate/types.js.map +1 -1
- package/build/unit-control/index.js +1 -1
- package/build/unit-control/index.js.map +1 -1
- package/build/utils/strings.js +34 -3
- package/build/utils/strings.js.map +1 -1
- package/build-module/base-control/index.js +16 -12
- package/build-module/base-control/index.js.map +1 -1
- package/build-module/border-box-control/border-box-control-linked-button/component.js +1 -1
- package/build-module/border-box-control/border-box-control-linked-button/component.js.map +1 -1
- package/build-module/border-control/border-control-style-picker/component.js +1 -1
- package/build-module/border-control/border-control-style-picker/component.js.map +1 -1
- package/build-module/box-control/index.js +1 -1
- package/build-module/box-control/index.js.map +1 -1
- package/build-module/box-control/linked-button.js +1 -1
- package/build-module/box-control/linked-button.js.map +1 -1
- package/build-module/button/index.js +1 -1
- package/build-module/button/index.js.map +1 -1
- package/build-module/color-palette/index.native.js +11 -7
- package/build-module/color-palette/index.native.js.map +1 -1
- package/build-module/color-picker/color-copy-button.js +1 -1
- package/build-module/color-picker/color-copy-button.js.map +1 -1
- package/build-module/context/wordpress-component.js.map +1 -1
- package/build-module/custom-select-control-v2/index.js +11 -10
- package/build-module/custom-select-control-v2/index.js.map +1 -1
- package/build-module/date-time/date/styles.js +8 -8
- package/build-module/date-time/date/styles.js.map +1 -1
- package/build-module/dropdown-menu-v2/index.js +201 -154
- package/build-module/dropdown-menu-v2/index.js.map +1 -1
- package/build-module/dropdown-menu-v2/styles.js +68 -61
- package/build-module/dropdown-menu-v2/styles.js.map +1 -1
- package/build-module/dropdown-menu-v2/types.js.map +1 -1
- package/build-module/duotone-picker/duotone-picker.js +4 -3
- package/build-module/duotone-picker/duotone-picker.js.map +1 -1
- package/build-module/font-size-picker/index.js +4 -2
- package/build-module/font-size-picker/index.js.map +1 -1
- package/build-module/font-size-picker/index.native.js +5 -2
- package/build-module/font-size-picker/index.native.js.map +1 -1
- package/build-module/form-token-field/index.js +10 -5
- package/build-module/form-token-field/index.js.map +1 -1
- package/build-module/form-token-field/token.js +1 -0
- package/build-module/form-token-field/token.js.map +1 -1
- package/build-module/gradient-picker/index.js +3 -2
- package/build-module/gradient-picker/index.js.map +1 -1
- package/build-module/index.native.js +6 -1
- package/build-module/index.native.js.map +1 -1
- package/build-module/input-control/styles/input-control-styles.js +31 -29
- package/build-module/input-control/styles/input-control-styles.js.map +1 -1
- package/build-module/input-control/types.js.map +1 -1
- package/build-module/lock-unlock.js +9 -0
- package/build-module/lock-unlock.js.map +1 -0
- package/build-module/mobile/bottom-sheet/index.native.js +9 -1
- package/build-module/mobile/bottom-sheet/index.native.js.map +1 -1
- package/build-module/mobile/color-settings/palette.screen.native.js +8 -4
- package/build-module/mobile/color-settings/palette.screen.native.js.map +1 -1
- package/build-module/mobile/global-styles-context/utils.native.js +25 -13
- package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
- package/build-module/mobile/image/constants.js +5 -0
- package/build-module/mobile/image/constants.js.map +1 -0
- package/build-module/mobile/image/index.native.js +25 -16
- package/build-module/mobile/image/index.native.js.map +1 -1
- package/build-module/mobile/keyboard-aware-flat-list/index.android.js +40 -6
- package/build-module/mobile/keyboard-aware-flat-list/index.android.js.map +1 -1
- package/build-module/mobile/keyboard-aware-flat-list/index.ios.js +46 -68
- package/build-module/mobile/keyboard-aware-flat-list/index.ios.js.map +1 -1
- package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js +33 -0
- package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js.map +1 -0
- package/build-module/mobile/keyboard-aware-flat-list/{use-scroll-to-text-input.native.js → use-scroll-to-section.native.js} +21 -27
- package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-section.native.js.map +1 -0
- package/build-module/mobile/keyboard-aware-flat-list/use-scroll.native.js +86 -0
- package/build-module/mobile/keyboard-aware-flat-list/use-scroll.native.js.map +1 -0
- package/build-module/mobile/utils/get-px-from-css-unit.native.js +294 -0
- package/build-module/mobile/utils/get-px-from-css-unit.native.js.map +1 -0
- package/build-module/modal/index.js +18 -13
- package/build-module/modal/index.js.map +1 -1
- package/build-module/navigation/menu/menu-title.js +1 -1
- package/build-module/navigation/menu/menu-title.js.map +1 -1
- package/build-module/navigator/navigator-provider/component.js +3 -16
- package/build-module/navigator/navigator-provider/component.js.map +1 -1
- package/build-module/navigator/navigator-screen/component.js +16 -70
- package/build-module/navigator/navigator-screen/component.js.map +1 -1
- package/build-module/navigator/styles.js +47 -0
- package/build-module/navigator/styles.js.map +1 -0
- package/build-module/number-control/index.js +4 -8
- package/build-module/number-control/index.js.map +1 -1
- package/build-module/number-control/types.js.map +1 -1
- package/build-module/palette-edit/index.js +15 -51
- package/build-module/palette-edit/index.js.map +1 -1
- package/build-module/private-apis.js +10 -23
- package/build-module/private-apis.js.map +1 -1
- package/build-module/private-apis.native.js +14 -0
- package/build-module/private-apis.native.js.map +1 -0
- package/build-module/radio-control/index.js +1 -0
- package/build-module/radio-control/index.js.map +1 -1
- package/build-module/range-control/index.js +1 -1
- package/build-module/range-control/index.js.map +1 -1
- package/build-module/select-control/styles/select-control-styles.js +15 -25
- package/build-module/select-control/styles/select-control-styles.js.map +1 -1
- package/build-module/slot-fill/index.js +3 -2
- package/build-module/slot-fill/index.js.map +1 -1
- package/build-module/slot-fill/types.js.map +1 -1
- package/build-module/snackbar/types.js.map +1 -1
- package/build-module/tabs/styles.js +3 -3
- package/build-module/tabs/styles.js.map +1 -1
- package/build-module/tabs/tabpanel.js +9 -7
- package/build-module/tabs/tabpanel.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control/component.js +4 -4
- package/build-module/toggle-group-control/toggle-group-control/component.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control/styles.js +29 -15
- package/build-module/toggle-group-control/toggle-group-control/styles.js.map +1 -1
- package/build-module/toggle-group-control/toggle-group-control-option-base/styles.js +9 -9
- package/build-module/toggle-group-control/toggle-group-control-option-base/styles.js.map +1 -1
- package/build-module/tools-panel/tools-panel/component.js +3 -1
- package/build-module/tools-panel/tools-panel/component.js.map +1 -1
- package/build-module/tools-panel/tools-panel-header/component.js +9 -8
- package/build-module/tools-panel/tools-panel-header/component.js.map +1 -1
- package/build-module/tools-panel/types.js.map +1 -1
- package/build-module/tooltip/index.js +34 -12
- package/build-module/tooltip/index.js.map +1 -1
- package/build-module/tooltip/types.js.map +1 -1
- package/build-module/truncate/hook.js +10 -4
- package/build-module/truncate/hook.js.map +1 -1
- package/build-module/truncate/types.js.map +1 -1
- package/build-module/unit-control/index.js +1 -1
- package/build-module/unit-control/index.js.map +1 -1
- package/build-module/utils/strings.js +32 -2
- package/build-module/utils/strings.js.map +1 -1
- package/build-style/style-rtl.css +29 -5
- package/build-style/style.css +29 -5
- package/build-types/base-control/index.d.ts +3 -27
- package/build-types/base-control/index.d.ts.map +1 -1
- package/build-types/base-control/stories/index.story.d.ts +4 -1
- package/build-types/base-control/stories/index.story.d.ts.map +1 -1
- package/build-types/border-box-control/border-box-control/hook.d.ts +4 -4
- package/build-types/border-box-control/border-box-control-linked-button/hook.d.ts +6 -6
- package/build-types/border-box-control/border-box-control-split-controls/hook.d.ts +4 -4
- package/build-types/border-box-control/border-box-control-visualizer/hook.d.ts +4 -4
- package/build-types/border-box-control/stories/index.story.d.ts +1 -1
- package/build-types/border-control/border-control/hook.d.ts +4 -4
- package/build-types/border-control/border-control-dropdown/hook.d.ts +4 -4
- package/build-types/border-control/border-control-style-picker/hook.d.ts +4 -4
- package/build-types/border-control/stories/index.story.d.ts +6 -6
- package/build-types/box-control/stories/index.story.d.ts +42 -42
- package/build-types/box-control/styles/box-control-styles.d.ts +1 -1
- package/build-types/button/deprecated.d.ts +3 -3
- package/build-types/card/card/hook.d.ts +4 -4
- package/build-types/card/card-body/hook.d.ts +4 -4
- package/build-types/card/card-divider/hook.d.ts +4 -4
- package/build-types/card/card-footer/hook.d.ts +4 -4
- package/build-types/card/card-header/hook.d.ts +4 -4
- package/build-types/card/card-media/hook.d.ts +4 -4
- package/build-types/color-palette/styles.d.ts +2 -2
- package/build-types/color-picker/component.d.ts +2 -2
- package/build-types/color-picker/stories/index.story.d.ts +1 -1
- package/build-types/color-picker/stories/index.story.d.ts.map +1 -1
- package/build-types/color-picker/styles.d.ts +3 -3
- package/build-types/composite/test/index.d.ts.map +1 -0
- package/build-types/context/wordpress-component.d.ts +3 -3
- package/build-types/context/wordpress-component.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/index.d.ts +3 -2
- package/build-types/custom-select-control-v2/index.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/stories/index.story.d.ts +4 -3
- package/build-types/custom-select-control-v2/stories/index.story.d.ts.map +1 -1
- package/build-types/date-time/date/styles.d.ts +3 -3
- package/build-types/date-time/date-time/styles.d.ts +1 -1
- package/build-types/date-time/time/styles.d.ts +4 -4
- package/build-types/dropdown/index.d.ts +1 -1
- package/build-types/dropdown/index.d.ts.map +1 -1
- package/build-types/dropdown/stories/index.story.d.ts +3 -3
- package/build-types/dropdown/stories/index.story.d.ts.map +1 -1
- package/build-types/dropdown-menu/index.d.ts +1 -1
- package/build-types/dropdown-menu/index.d.ts.map +1 -1
- package/build-types/dropdown-menu/stories/index.story.d.ts +2 -2
- package/build-types/dropdown-menu/stories/index.story.d.ts.map +1 -1
- package/build-types/dropdown-menu-v2/index.d.ts +18 -15
- package/build-types/dropdown-menu-v2/index.d.ts.map +1 -1
- package/build-types/dropdown-menu-v2/stories/index.story.d.ts +7 -2
- package/build-types/dropdown-menu-v2/stories/index.story.d.ts.map +1 -1
- package/build-types/dropdown-menu-v2/styles.d.ts +77 -23
- package/build-types/dropdown-menu-v2/styles.d.ts.map +1 -1
- package/build-types/dropdown-menu-v2/types.d.ts +89 -173
- package/build-types/dropdown-menu-v2/types.d.ts.map +1 -1
- package/build-types/duotone-picker/duotone-picker.d.ts.map +1 -1
- package/build-types/elevation/hook.d.ts +4 -4
- package/build-types/flex/flex/hook.d.ts +4 -4
- package/build-types/flex/flex-block/hook.d.ts +4 -4
- package/build-types/flex/flex-item/hook.d.ts +4 -4
- package/build-types/focal-point-picker/stories/index.story.d.ts +4 -4
- package/build-types/focal-point-picker/styles/focal-point-picker-style.d.ts +1 -1
- package/build-types/font-size-picker/index.d.ts.map +1 -1
- package/build-types/font-size-picker/styles.d.ts +1 -1
- package/build-types/form-token-field/index.d.ts.map +1 -1
- package/build-types/form-token-field/token.d.ts.map +1 -1
- package/build-types/grid/hook.d.ts +4 -4
- package/build-types/h-stack/hook.d.ts +4 -4
- package/build-types/heading/component.d.ts +1 -1
- package/build-types/heading/hook.d.ts +4 -4
- package/build-types/input-control/styles/input-control-styles.d.ts +11 -0
- package/build-types/input-control/styles/input-control-styles.d.ts.map +1 -1
- package/build-types/input-control/types.d.ts +1 -1
- package/build-types/input-control/types.d.ts.map +1 -1
- package/build-types/item-group/item/hook.d.ts +4 -4
- package/build-types/item-group/item-group/hook.d.ts +4 -4
- package/build-types/lock-unlock.d.ts +3 -0
- package/build-types/lock-unlock.d.ts.map +1 -0
- package/build-types/menu-item/index.d.ts +1 -1
- package/build-types/menu-item/stories/index.story.d.ts +4 -4
- package/build-types/mobile/image/constants.d.ts +5 -0
- package/build-types/mobile/image/constants.d.ts.map +1 -0
- package/build-types/modal/index.d.ts.map +1 -1
- package/build-types/navigation/styles/navigation-styles.d.ts +3 -3
- package/build-types/navigator/navigator-back-button/hook.d.ts +6 -6
- package/build-types/navigator/navigator-button/hook.d.ts +6 -6
- package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
- package/build-types/navigator/navigator-screen/component.d.ts +1 -7
- package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
- package/build-types/navigator/styles.d.ts +9 -0
- package/build-types/navigator/styles.d.ts.map +1 -0
- package/build-types/number-control/index.d.ts +1 -1
- package/build-types/number-control/index.d.ts.map +1 -1
- package/build-types/number-control/stories/index.story.d.ts +1 -1
- package/build-types/number-control/types.d.ts +1 -1
- package/build-types/palette-edit/index.d.ts +3 -8
- package/build-types/palette-edit/index.d.ts.map +1 -1
- package/build-types/palette-edit/styles.d.ts +3 -3
- package/build-types/popover/index.d.ts +1 -1
- package/build-types/popover/index.d.ts.map +1 -1
- package/build-types/popover/stories/e2e/index.story.d.ts +1 -1
- package/build-types/private-apis.d.ts +0 -1
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/radio-control/index.d.ts.map +1 -1
- package/build-types/range-control/index.d.ts +1 -1
- package/build-types/range-control/styles/range-control-styles.d.ts +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/resizable-box/stories/index.story.d.ts +2 -2
- package/build-types/scrollable/hook.d.ts +4 -4
- package/build-types/search-control/index.d.ts +1 -1
- package/build-types/search-control/stories/index.story.d.ts +2 -2
- package/build-types/select-control/styles/select-control-styles.d.ts.map +1 -1
- package/build-types/slot-fill/index.d.ts +1 -1
- package/build-types/slot-fill/index.d.ts.map +1 -1
- package/build-types/slot-fill/types.d.ts +4 -0
- package/build-types/slot-fill/types.d.ts.map +1 -1
- package/build-types/snackbar/index.d.ts +2 -2
- package/build-types/snackbar/stories/index.story.d.ts +0 -3
- package/build-types/snackbar/stories/index.story.d.ts.map +1 -1
- package/build-types/snackbar/types.d.ts +1 -1
- package/build-types/snackbar/types.d.ts.map +1 -1
- package/build-types/spacer/hook.d.ts +4 -4
- package/build-types/surface/hook.d.ts +4 -4
- package/build-types/tabs/styles.d.ts.map +1 -1
- package/build-types/tabs/tabpanel.d.ts +1 -1
- package/build-types/tabs/tabpanel.d.ts.map +1 -1
- package/build-types/text/hook.d.ts +4 -4
- package/build-types/text-control/index.d.ts +1 -1
- package/build-types/textarea-control/index.d.ts +1 -1
- package/build-types/toggle-control/stories/index.story.d.ts +2 -2
- package/build-types/toggle-group-control/toggle-group-control/as-button-group.d.ts +1 -1
- package/build-types/toggle-group-control/toggle-group-control/as-radio-group.d.ts +1 -1
- package/build-types/toggle-group-control/toggle-group-control/component.d.ts.map +1 -1
- package/build-types/toggle-group-control/toggle-group-control/styles.d.ts +2 -2
- package/build-types/toggle-group-control/toggle-group-control/styles.d.ts.map +1 -1
- package/build-types/toggle-group-control/toggle-group-control-option/component.d.ts +1 -1
- package/build-types/toggle-group-control/toggle-group-control-option-base/component.d.ts +1 -1
- package/build-types/toggle-group-control/toggle-group-control-option-base/component.d.ts.map +1 -1
- package/build-types/toggle-group-control/toggle-group-control-option-base/styles.d.ts.map +1 -1
- package/build-types/toggle-group-control/toggle-group-control-option-icon/component.d.ts +1 -1
- package/build-types/toolbar/toolbar-button/index.d.ts +3 -3
- package/build-types/tools-panel/tools-panel/component.d.ts.map +1 -1
- package/build-types/tools-panel/tools-panel/hook.d.ts +5 -4
- package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
- package/build-types/tools-panel/tools-panel-header/component.d.ts.map +1 -1
- package/build-types/tools-panel/tools-panel-header/hook.d.ts +5 -4
- package/build-types/tools-panel/tools-panel-header/hook.d.ts.map +1 -1
- package/build-types/tools-panel/tools-panel-item/hook.d.ts +4 -4
- package/build-types/tools-panel/types.d.ts +9 -0
- package/build-types/tools-panel/types.d.ts.map +1 -1
- package/build-types/tooltip/index.d.ts +1 -1
- package/build-types/tooltip/index.d.ts.map +1 -1
- package/build-types/tooltip/stories/index.story.d.ts +10 -1
- package/build-types/tooltip/stories/index.story.d.ts.map +1 -1
- package/build-types/tooltip/types.d.ts +3 -0
- package/build-types/tooltip/types.d.ts.map +1 -1
- package/build-types/truncate/hook.d.ts +5 -5
- package/build-types/truncate/hook.d.ts.map +1 -1
- package/build-types/truncate/types.d.ts +4 -0
- package/build-types/truncate/types.d.ts.map +1 -1
- package/build-types/unit-control/index.d.ts +1 -1
- package/build-types/unit-control/styles/unit-control-styles.d.ts +1 -1
- package/build-types/utils/strings.d.ts +14 -2
- package/build-types/utils/strings.d.ts.map +1 -1
- package/build-types/v-stack/hook.d.ts +4 -4
- package/build-types/v-stack/stories/index.story.d.ts +1 -1
- package/package.json +20 -21
- package/src/alignment-matrix-control/test/index.tsx +10 -16
- package/src/base-control/index.tsx +21 -16
- package/src/border-box-control/border-box-control-linked-button/component.tsx +1 -1
- package/src/border-control/border-control-style-picker/component.tsx +1 -1
- package/src/box-control/index.tsx +1 -1
- package/src/box-control/linked-button.tsx +1 -1
- package/src/button/README.md +32 -6
- package/src/button/index.tsx +1 -1
- package/src/button-group/README.md +0 -6
- package/src/card/card/README.md +1 -1
- package/src/checkbox-control/README.md +1 -9
- package/src/color-palette/index.native.js +18 -7
- package/src/color-picker/color-copy-button.tsx +1 -1
- package/src/combobox-control/README.md +0 -6
- package/src/composite/test/index.tsx +576 -0
- package/src/context/wordpress-component.ts +11 -6
- package/src/custom-select-control/README.md +0 -6
- package/src/custom-select-control-v2/index.tsx +13 -12
- package/src/date-time/date/styles.ts +3 -3
- package/src/dropdown-menu/README.md +0 -5
- package/src/dropdown-menu-v2/README.md +75 -136
- package/src/dropdown-menu-v2/index.tsx +321 -231
- package/src/dropdown-menu-v2/stories/index.story.tsx +522 -126
- package/src/dropdown-menu-v2/styles.ts +226 -151
- package/src/dropdown-menu-v2/test/index.tsx +480 -188
- package/src/dropdown-menu-v2/types.ts +98 -184
- package/src/duotone-picker/duotone-picker.tsx +7 -3
- package/src/font-size-picker/index.native.js +8 -2
- package/src/font-size-picker/index.tsx +4 -2
- package/src/form-toggle/README.md +0 -6
- package/src/form-token-field/index.tsx +11 -7
- package/src/form-token-field/test/index.tsx +97 -0
- package/src/form-token-field/token.tsx +1 -0
- package/src/gradient-picker/index.tsx +2 -2
- package/src/index.native.js +6 -1
- package/src/input-control/styles/input-control-styles.tsx +10 -8
- package/src/input-control/types.ts +1 -1
- package/src/lock-unlock.js +10 -0
- package/src/menu-group/README.md +0 -8
- package/src/menu-items-choice/README.md +0 -7
- package/src/mobile/bottom-sheet/index.native.js +15 -1
- package/src/mobile/color-settings/palette.screen.native.js +7 -5
- package/src/mobile/global-styles-context/test/fixtures/theme.native.js +0 -20
- package/src/mobile/global-styles-context/utils.native.js +28 -19
- package/src/mobile/image/constants.js +1 -0
- package/src/mobile/image/index.native.js +55 -18
- package/src/mobile/image/style.native.scss +35 -9
- package/src/mobile/keyboard-aware-flat-list/index.android.js +50 -5
- package/src/mobile/keyboard-aware-flat-list/index.ios.js +65 -91
- package/src/mobile/keyboard-aware-flat-list/test/{use-scroll-to-text-input.native.js → use-scroll-to-section.native.js} +27 -25
- package/src/mobile/keyboard-aware-flat-list/test/use-scroll.native.js +71 -0
- package/src/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js +41 -0
- package/src/mobile/keyboard-aware-flat-list/{use-scroll-to-text-input.native.js → use-scroll-to-section.native.js} +22 -27
- package/src/mobile/keyboard-aware-flat-list/use-scroll.native.js +100 -0
- package/src/mobile/utils/get-px-from-css-unit.native.js +329 -0
- package/src/mobile/utils/test/get-px-from-css-unit.native.js +172 -0
- package/src/modal/README.md +0 -6
- package/src/modal/index.tsx +18 -16
- package/src/modal/test/index.tsx +90 -1
- package/src/navigation/menu/menu-title.tsx +1 -1
- package/src/navigator/navigator-provider/component.tsx +3 -4
- package/src/navigator/navigator-screen/component.tsx +15 -93
- package/src/navigator/styles.ts +71 -0
- package/src/navigator/test/index.tsx +0 -64
- package/src/notice/README.md +0 -6
- package/src/number-control/README.md +2 -2
- package/src/number-control/index.tsx +4 -8
- package/src/number-control/types.ts +1 -1
- package/src/palette-edit/index.tsx +15 -58
- package/src/palette-edit/test/index.tsx +1 -75
- package/src/panel/README.md +0 -6
- package/src/private-apis.native.js +13 -0
- package/src/private-apis.ts +12 -37
- package/src/radio-control/README.md +0 -6
- package/src/radio-control/index.tsx +4 -1
- package/src/radio-control/style.scss +29 -2
- package/src/radio-group/README.md +0 -6
- package/src/range-control/README.md +1 -9
- package/src/range-control/index.tsx +1 -1
- package/src/search-control/README.md +0 -6
- package/src/select-control/README.md +0 -6
- package/src/select-control/styles/select-control-styles.ts +10 -28
- package/src/slot-fill/index.tsx +5 -2
- package/src/slot-fill/types.ts +5 -0
- package/src/snackbar/README.md +0 -6
- package/src/snackbar/stories/index.story.tsx +7 -5
- package/src/snackbar/style.scss +4 -3
- package/src/snackbar/types.ts +2 -1
- package/src/spacer/README.md +0 -2
- package/src/tab-panel/README.md +0 -5
- package/src/tab-panel/test/index.tsx +39 -56
- package/src/tabs/styles.ts +7 -1
- package/src/tabs/tabpanel.tsx +7 -6
- package/src/tabs/test/index.tsx +56 -0
- package/src/text-control/README.md +0 -6
- package/src/textarea-control/README.md +0 -6
- package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +12 -16
- package/src/toggle-group-control/test/index.tsx +58 -45
- package/src/toggle-group-control/toggle-group-control/component.tsx +5 -4
- package/src/toggle-group-control/toggle-group-control/styles.ts +13 -19
- package/src/toggle-group-control/toggle-group-control-option/README.md +1 -1
- package/src/toggle-group-control/toggle-group-control-option-base/README.md +1 -1
- package/src/toggle-group-control/toggle-group-control-option-base/styles.ts +3 -2
- package/src/toggle-group-control/toggle-group-control-option-icon/README.md +1 -1
- package/src/toolbar/toolbar/README.md +0 -6
- package/src/tools-panel/test/index.tsx +12 -20
- package/src/tools-panel/tools-panel/README.md +7 -0
- package/src/tools-panel/tools-panel/component.tsx +2 -0
- package/src/tools-panel/tools-panel-header/README.md +7 -0
- package/src/tools-panel/tools-panel-header/component.tsx +20 -13
- package/src/tools-panel/types.ts +9 -0
- package/src/tooltip/README.md +4 -0
- package/src/tooltip/index.tsx +48 -10
- package/src/tooltip/stories/index.story.tsx +18 -1
- package/src/tooltip/test/index.tsx +404 -254
- package/src/tooltip/types.ts +4 -0
- package/src/tree-grid/README.md +0 -4
- package/src/truncate/README.md +8 -0
- package/src/truncate/hook.ts +17 -10
- package/src/truncate/test/index.tsx +54 -27
- package/src/truncate/types.ts +4 -0
- package/src/unit-control/index.tsx +1 -1
- package/src/utils/strings.ts +30 -2
- package/src/utils/test/strings.js +96 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/build/dropdown-menu-v2-ariakit/index.js +0 -256
- package/build/dropdown-menu-v2-ariakit/index.js.map +0 -1
- package/build/dropdown-menu-v2-ariakit/styles.js +0 -180
- package/build/dropdown-menu-v2-ariakit/styles.js.map +0 -1
- package/build/dropdown-menu-v2-ariakit/types.js +0 -6
- package/build/dropdown-menu-v2-ariakit/types.js.map +0 -1
- package/build/mobile/keyboard-aware-flat-list/use-scroll-to-text-input.native.js.map +0 -1
- package/build-module/dropdown-menu-v2-ariakit/index.js +0 -237
- package/build-module/dropdown-menu-v2-ariakit/index.js.map +0 -1
- package/build-module/dropdown-menu-v2-ariakit/styles.js +0 -165
- package/build-module/dropdown-menu-v2-ariakit/styles.js.map +0 -1
- package/build-module/dropdown-menu-v2-ariakit/types.js +0 -2
- package/build-module/dropdown-menu-v2-ariakit/types.js.map +0 -1
- package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-text-input.native.js.map +0 -1
- package/build-types/dropdown-menu-v2-ariakit/index.d.ts +0 -20
- package/build-types/dropdown-menu-v2-ariakit/index.d.ts.map +0 -1
- package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts +0 -16
- package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts.map +0 -1
- package/build-types/dropdown-menu-v2-ariakit/styles.d.ts +0 -96
- package/build-types/dropdown-menu-v2-ariakit/styles.d.ts.map +0 -1
- package/build-types/dropdown-menu-v2-ariakit/test/index.d.ts.map +0 -1
- package/build-types/dropdown-menu-v2-ariakit/types.d.ts +0 -168
- package/build-types/dropdown-menu-v2-ariakit/types.d.ts.map +0 -1
- package/src/dropdown-menu-v2-ariakit/README.md +0 -331
- package/src/dropdown-menu-v2-ariakit/index.tsx +0 -383
- package/src/dropdown-menu-v2-ariakit/stories/index.story.tsx +0 -617
- package/src/dropdown-menu-v2-ariakit/styles.ts +0 -345
- package/src/dropdown-menu-v2-ariakit/test/index.tsx +0 -1108
- package/src/dropdown-menu-v2-ariakit/types.ts +0 -179
- /package/build-types/{dropdown-menu-v2-ariakit → composite}/test/index.d.ts +0 -0
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
5
|
-
import {
|
|
6
|
-
default as userEvent,
|
|
7
|
-
PointerEventsCheckLevel,
|
|
8
|
-
} from '@testing-library/user-event';
|
|
5
|
+
import { press, click, hover, type } from '@ariakit/test';
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* WordPress dependencies
|
|
@@ -19,12 +16,9 @@ import {
|
|
|
19
16
|
DropdownMenu,
|
|
20
17
|
DropdownMenuCheckboxItem,
|
|
21
18
|
DropdownMenuItem,
|
|
22
|
-
DropdownMenuLabel,
|
|
23
|
-
DropdownMenuRadioGroup,
|
|
24
19
|
DropdownMenuRadioItem,
|
|
25
20
|
DropdownMenuSeparator,
|
|
26
|
-
|
|
27
|
-
DropdownSubMenuTrigger,
|
|
21
|
+
DropdownMenuGroup,
|
|
28
22
|
} from '..';
|
|
29
23
|
|
|
30
24
|
const delay = ( delayInMs: number ) => {
|
|
@@ -34,23 +28,18 @@ const delay = ( delayInMs: number ) => {
|
|
|
34
28
|
describe( 'DropdownMenu', () => {
|
|
35
29
|
// See https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/
|
|
36
30
|
it( 'should follow the WAI-ARIA spec', async () => {
|
|
37
|
-
// Radio and Checkbox items'
|
|
38
|
-
const user = userEvent.setup();
|
|
39
|
-
|
|
40
31
|
render(
|
|
41
32
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
42
33
|
<DropdownMenuItem>Dropdown menu item</DropdownMenuItem>
|
|
43
34
|
<DropdownMenuSeparator />
|
|
44
|
-
<
|
|
35
|
+
<DropdownMenu
|
|
45
36
|
trigger={
|
|
46
|
-
<
|
|
47
|
-
Dropdown submenu
|
|
48
|
-
</DropdownSubMenuTrigger>
|
|
37
|
+
<DropdownMenuItem>Dropdown submenu</DropdownMenuItem>
|
|
49
38
|
}
|
|
50
39
|
>
|
|
51
40
|
<DropdownMenuItem>Dropdown submenu item 1</DropdownMenuItem>
|
|
52
41
|
<DropdownMenuItem>Dropdown submenu item 2</DropdownMenuItem>
|
|
53
|
-
</
|
|
42
|
+
</DropdownMenu>
|
|
54
43
|
</DropdownMenu>
|
|
55
44
|
);
|
|
56
45
|
|
|
@@ -61,11 +50,13 @@ describe( 'DropdownMenu', () => {
|
|
|
61
50
|
expect( toggleButton ).toHaveAttribute( 'aria-haspopup', 'menu' );
|
|
62
51
|
expect( toggleButton ).toHaveAttribute( 'aria-expanded', 'false' );
|
|
63
52
|
|
|
64
|
-
await
|
|
53
|
+
await click( toggleButton );
|
|
65
54
|
|
|
66
55
|
expect( toggleButton ).toHaveAttribute( 'aria-expanded', 'true' );
|
|
67
56
|
|
|
68
|
-
expect(
|
|
57
|
+
expect(
|
|
58
|
+
screen.getByRole( 'menu', { name: toggleButton.textContent ?? '' } )
|
|
59
|
+
).toHaveFocus();
|
|
69
60
|
expect( screen.getByRole( 'separator' ) ).toHaveAttribute(
|
|
70
61
|
'aria-orientation',
|
|
71
62
|
'horizontal'
|
|
@@ -78,11 +69,15 @@ describe( 'DropdownMenu', () => {
|
|
|
78
69
|
expect( submenuTrigger ).toHaveAttribute( 'aria-haspopup', 'menu' );
|
|
79
70
|
expect( submenuTrigger ).toHaveAttribute( 'aria-expanded', 'false' );
|
|
80
71
|
|
|
81
|
-
await
|
|
72
|
+
await hover( submenuTrigger );
|
|
82
73
|
|
|
83
74
|
// Wait for the open animation after hovering
|
|
84
75
|
await waitFor( () =>
|
|
85
|
-
expect(
|
|
76
|
+
expect(
|
|
77
|
+
screen.getByRole( 'menu', {
|
|
78
|
+
name: submenuTrigger.textContent ?? '',
|
|
79
|
+
} )
|
|
80
|
+
).toBeVisible()
|
|
86
81
|
);
|
|
87
82
|
|
|
88
83
|
expect( submenuTrigger ).toHaveAttribute( 'aria-expanded', 'true' );
|
|
@@ -93,9 +88,7 @@ describe( 'DropdownMenu', () => {
|
|
|
93
88
|
} );
|
|
94
89
|
|
|
95
90
|
describe( 'pointer and keyboard interactions', () => {
|
|
96
|
-
it( 'should open when clicking the trigger', async () => {
|
|
97
|
-
const user = userEvent.setup();
|
|
98
|
-
|
|
91
|
+
it( 'should open and focus the menu when clicking the trigger', async () => {
|
|
99
92
|
render(
|
|
100
93
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
101
94
|
<DropdownMenuItem>Dropdown menu item</DropdownMenuItem>
|
|
@@ -106,24 +99,52 @@ describe( 'DropdownMenu', () => {
|
|
|
106
99
|
name: 'Open dropdown',
|
|
107
100
|
} );
|
|
108
101
|
|
|
109
|
-
// DropdownMenu closed
|
|
102
|
+
// DropdownMenu closed
|
|
110
103
|
expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
|
|
111
|
-
expect( screen.queryByRole( 'menuitem' ) ).not.toBeInTheDocument();
|
|
112
104
|
|
|
113
105
|
// Click to open the menu
|
|
114
|
-
await
|
|
106
|
+
await click( toggleButton );
|
|
115
107
|
|
|
116
|
-
// DropdownMenu open, the
|
|
117
|
-
expect( screen.getByRole( 'menu' ) ).
|
|
118
|
-
expect( screen.getByRole( 'menuitem' ) ).toBeInTheDocument();
|
|
108
|
+
// DropdownMenu open, focus is on the menu wrapper
|
|
109
|
+
expect( screen.getByRole( 'menu' ) ).toHaveFocus();
|
|
119
110
|
} );
|
|
120
111
|
|
|
121
|
-
it( 'should open when pressing the arrow down key on the trigger', async () => {
|
|
122
|
-
|
|
112
|
+
it( 'should open and focus the first item when pressing the arrow down key on the trigger', async () => {
|
|
113
|
+
render(
|
|
114
|
+
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
115
|
+
<DropdownMenuItem disabled>First item</DropdownMenuItem>
|
|
116
|
+
<DropdownMenuItem>Second item</DropdownMenuItem>
|
|
117
|
+
<DropdownMenuItem>Third item</DropdownMenuItem>
|
|
118
|
+
</DropdownMenu>
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const toggleButton = screen.getByRole( 'button', {
|
|
122
|
+
name: 'Open dropdown',
|
|
123
|
+
} );
|
|
124
|
+
|
|
125
|
+
// Move focus on the toggle
|
|
126
|
+
await press.Tab();
|
|
127
|
+
|
|
128
|
+
expect( toggleButton ).toHaveFocus();
|
|
129
|
+
|
|
130
|
+
// DropdownMenu closed
|
|
131
|
+
expect( screen.queryByRole( 'menuitem' ) ).not.toBeInTheDocument();
|
|
132
|
+
|
|
133
|
+
await press.ArrowDown();
|
|
134
|
+
|
|
135
|
+
// DropdownMenu open, focus is on the first focusable item
|
|
136
|
+
// (disabled items are still focusable and accessible)
|
|
137
|
+
expect(
|
|
138
|
+
screen.getByRole( 'menuitem', { name: 'First item' } )
|
|
139
|
+
).toHaveFocus();
|
|
140
|
+
} );
|
|
123
141
|
|
|
142
|
+
it( 'should open and focus the first item when pressing the space key on the trigger', async () => {
|
|
124
143
|
render(
|
|
125
144
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
126
|
-
<DropdownMenuItem>
|
|
145
|
+
<DropdownMenuItem disabled>First item</DropdownMenuItem>
|
|
146
|
+
<DropdownMenuItem>Second item</DropdownMenuItem>
|
|
147
|
+
<DropdownMenuItem>Third item</DropdownMenuItem>
|
|
127
148
|
</DropdownMenu>
|
|
128
149
|
);
|
|
129
150
|
|
|
@@ -132,50 +153,52 @@ describe( 'DropdownMenu', () => {
|
|
|
132
153
|
} );
|
|
133
154
|
|
|
134
155
|
// Move focus on the toggle
|
|
135
|
-
await
|
|
156
|
+
await press.Tab();
|
|
136
157
|
|
|
137
158
|
expect( toggleButton ).toHaveFocus();
|
|
138
159
|
|
|
139
|
-
// DropdownMenu closed
|
|
160
|
+
// DropdownMenu closed
|
|
140
161
|
expect( screen.queryByRole( 'menuitem' ) ).not.toBeInTheDocument();
|
|
141
162
|
|
|
142
|
-
await
|
|
163
|
+
await press.Space();
|
|
143
164
|
|
|
144
|
-
// DropdownMenu open, the
|
|
145
|
-
|
|
165
|
+
// DropdownMenu open, focus is on the first focusable item
|
|
166
|
+
// (disabled items are still focusable and accessible
|
|
167
|
+
expect(
|
|
168
|
+
screen.getByRole( 'menuitem', { name: 'First item' } )
|
|
169
|
+
).toHaveFocus();
|
|
146
170
|
} );
|
|
147
171
|
|
|
148
172
|
it( 'should close when pressing the escape key', async () => {
|
|
149
|
-
const user = userEvent.setup();
|
|
150
|
-
|
|
151
173
|
render(
|
|
152
|
-
<DropdownMenu
|
|
153
|
-
defaultOpen
|
|
154
|
-
trigger={ <button>Open dropdown</button> }
|
|
155
|
-
>
|
|
174
|
+
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
156
175
|
<DropdownMenuItem>Dropdown menu item</DropdownMenuItem>
|
|
157
176
|
</DropdownMenu>
|
|
158
177
|
);
|
|
159
178
|
|
|
160
|
-
|
|
179
|
+
const trigger = screen.getByRole( 'button', {
|
|
180
|
+
name: 'Open dropdown',
|
|
181
|
+
} );
|
|
182
|
+
|
|
183
|
+
await click( trigger );
|
|
184
|
+
|
|
185
|
+
// Focuses menu on mouse click, focuses first item on keyboard press
|
|
186
|
+
// Can be changed with a custom useEffect
|
|
161
187
|
expect( screen.getByRole( 'menu' ) ).toHaveFocus();
|
|
162
188
|
|
|
163
189
|
// Pressing esc will close the menu and move focus to the toggle
|
|
164
|
-
await
|
|
190
|
+
await press.Escape();
|
|
165
191
|
|
|
166
192
|
expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
193
|
+
|
|
194
|
+
await waitFor( () =>
|
|
195
|
+
expect(
|
|
196
|
+
screen.getByRole( 'button', { name: 'Open dropdown' } )
|
|
197
|
+
).toHaveFocus()
|
|
198
|
+
);
|
|
170
199
|
} );
|
|
171
200
|
|
|
172
201
|
it( 'should close when clicking outside of the content', async () => {
|
|
173
|
-
const user = userEvent.setup( {
|
|
174
|
-
// Disabling this check otherwise testing-library would complain
|
|
175
|
-
// when clicking on document.body to close the dropdown menu.
|
|
176
|
-
pointerEventsCheck: PointerEventsCheckLevel.Never,
|
|
177
|
-
} );
|
|
178
|
-
|
|
179
202
|
render(
|
|
180
203
|
<DropdownMenu
|
|
181
204
|
defaultOpen
|
|
@@ -188,14 +211,12 @@ describe( 'DropdownMenu', () => {
|
|
|
188
211
|
expect( screen.getByRole( 'menu' ) ).toBeInTheDocument();
|
|
189
212
|
|
|
190
213
|
// Click on the body (ie. outside of the dropdown menu)
|
|
191
|
-
await
|
|
214
|
+
await click( document.body );
|
|
192
215
|
|
|
193
216
|
expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
|
|
194
217
|
} );
|
|
195
218
|
|
|
196
219
|
it( 'should close when clicking on a menu item', async () => {
|
|
197
|
-
const user = userEvent.setup();
|
|
198
|
-
|
|
199
220
|
render(
|
|
200
221
|
<DropdownMenu
|
|
201
222
|
defaultOpen
|
|
@@ -208,18 +229,32 @@ describe( 'DropdownMenu', () => {
|
|
|
208
229
|
expect( screen.getByRole( 'menu' ) ).toBeInTheDocument();
|
|
209
230
|
|
|
210
231
|
// Clicking a menu item will close the menu
|
|
211
|
-
await
|
|
232
|
+
await click( screen.getByRole( 'menuitem' ) );
|
|
212
233
|
|
|
213
234
|
expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
|
|
214
235
|
} );
|
|
215
236
|
|
|
216
|
-
it( 'should not close when clicking on a
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
237
|
+
it( 'should not close when clicking on a menu item when the `hideOnClick` prop is set to `false`', async () => {
|
|
238
|
+
render(
|
|
239
|
+
<DropdownMenu
|
|
240
|
+
defaultOpen
|
|
241
|
+
trigger={ <button>Open dropdown</button> }
|
|
242
|
+
>
|
|
243
|
+
<DropdownMenuItem hideOnClick={ false }>
|
|
244
|
+
Dropdown menu item
|
|
245
|
+
</DropdownMenuItem>
|
|
246
|
+
</DropdownMenu>
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
expect( screen.getByRole( 'menu' ) ).toBeVisible();
|
|
250
|
+
|
|
251
|
+
// Clicking a menu item will close the menu
|
|
252
|
+
await click( screen.getByRole( 'menuitem' ) );
|
|
253
|
+
|
|
254
|
+
expect( screen.getByRole( 'menu' ) ).toBeVisible();
|
|
255
|
+
} );
|
|
222
256
|
|
|
257
|
+
it( 'should not close when clicking on a disabled menu item', async () => {
|
|
223
258
|
render(
|
|
224
259
|
<DropdownMenu
|
|
225
260
|
defaultOpen
|
|
@@ -234,14 +269,12 @@ describe( 'DropdownMenu', () => {
|
|
|
234
269
|
expect( screen.getByRole( 'menu' ) ).toBeInTheDocument();
|
|
235
270
|
|
|
236
271
|
// Clicking a disabled menu item won't close the menu
|
|
237
|
-
await
|
|
272
|
+
await click( screen.getByRole( 'menuitem' ) );
|
|
238
273
|
|
|
239
274
|
expect( screen.getByRole( 'menu' ) ).toBeInTheDocument();
|
|
240
275
|
} );
|
|
241
276
|
|
|
242
277
|
it( 'should reveal submenu content when hovering over the submenu trigger', async () => {
|
|
243
|
-
const user = userEvent.setup();
|
|
244
|
-
|
|
245
278
|
render(
|
|
246
279
|
<DropdownMenu
|
|
247
280
|
defaultOpen
|
|
@@ -249,11 +282,11 @@ describe( 'DropdownMenu', () => {
|
|
|
249
282
|
>
|
|
250
283
|
<DropdownMenuItem>Dropdown menu item 1</DropdownMenuItem>
|
|
251
284
|
<DropdownMenuItem>Dropdown menu item 2</DropdownMenuItem>
|
|
252
|
-
<
|
|
285
|
+
<DropdownMenu
|
|
253
286
|
trigger={
|
|
254
|
-
<
|
|
287
|
+
<DropdownMenuItem>
|
|
255
288
|
Dropdown submenu
|
|
256
|
-
</
|
|
289
|
+
</DropdownMenuItem>
|
|
257
290
|
}
|
|
258
291
|
>
|
|
259
292
|
<DropdownMenuItem>
|
|
@@ -262,7 +295,7 @@ describe( 'DropdownMenu', () => {
|
|
|
262
295
|
<DropdownMenuItem>
|
|
263
296
|
Dropdown submenu item 2
|
|
264
297
|
</DropdownMenuItem>
|
|
265
|
-
</
|
|
298
|
+
</DropdownMenu>
|
|
266
299
|
<DropdownMenuItem>Dropdown menu item 3</DropdownMenuItem>
|
|
267
300
|
</DropdownMenu>
|
|
268
301
|
);
|
|
@@ -274,7 +307,7 @@ describe( 'DropdownMenu', () => {
|
|
|
274
307
|
} )
|
|
275
308
|
).not.toBeInTheDocument();
|
|
276
309
|
|
|
277
|
-
await
|
|
310
|
+
await hover(
|
|
278
311
|
screen.getByRole( 'menuitem', { name: 'Dropdown submenu' } )
|
|
279
312
|
);
|
|
280
313
|
|
|
@@ -287,8 +320,6 @@ describe( 'DropdownMenu', () => {
|
|
|
287
320
|
} );
|
|
288
321
|
|
|
289
322
|
it( 'should navigate menu items and subitems using the arrow, spacebar and enter keys', async () => {
|
|
290
|
-
const user = userEvent.setup();
|
|
291
|
-
|
|
292
323
|
render(
|
|
293
324
|
<DropdownMenu
|
|
294
325
|
defaultOpen
|
|
@@ -296,11 +327,11 @@ describe( 'DropdownMenu', () => {
|
|
|
296
327
|
>
|
|
297
328
|
<DropdownMenuItem>Dropdown menu item 1</DropdownMenuItem>
|
|
298
329
|
<DropdownMenuItem>Dropdown menu item 2</DropdownMenuItem>
|
|
299
|
-
<
|
|
330
|
+
<DropdownMenu
|
|
300
331
|
trigger={
|
|
301
|
-
<
|
|
332
|
+
<DropdownMenuItem>
|
|
302
333
|
Dropdown submenu
|
|
303
|
-
</
|
|
334
|
+
</DropdownMenuItem>
|
|
304
335
|
}
|
|
305
336
|
>
|
|
306
337
|
<DropdownMenuItem>
|
|
@@ -309,67 +340,69 @@ describe( 'DropdownMenu', () => {
|
|
|
309
340
|
<DropdownMenuItem>
|
|
310
341
|
Dropdown submenu item 2
|
|
311
342
|
</DropdownMenuItem>
|
|
312
|
-
</
|
|
343
|
+
</DropdownMenu>
|
|
313
344
|
<DropdownMenuItem>Dropdown menu item 3</DropdownMenuItem>
|
|
314
345
|
</DropdownMenu>
|
|
315
346
|
);
|
|
316
347
|
|
|
317
348
|
// The menu is focused automatically when `defaultOpen` is set.
|
|
318
|
-
|
|
349
|
+
await waitFor( () =>
|
|
350
|
+
expect( screen.getByRole( 'menu' ) ).toHaveFocus()
|
|
351
|
+
);
|
|
319
352
|
|
|
320
353
|
// Arrow up/down selects menu items
|
|
321
354
|
// The selection wraps around from last to first and viceversa
|
|
322
|
-
await
|
|
355
|
+
await press.ArrowDown();
|
|
323
356
|
expect(
|
|
324
357
|
screen.getByRole( 'menuitem', { name: 'Dropdown menu item 1' } )
|
|
325
358
|
).toHaveFocus();
|
|
326
359
|
|
|
327
|
-
await
|
|
360
|
+
await press.ArrowDown();
|
|
328
361
|
expect(
|
|
329
362
|
screen.getByRole( 'menuitem', { name: 'Dropdown menu item 2' } )
|
|
330
363
|
).toHaveFocus();
|
|
331
364
|
|
|
332
|
-
await
|
|
365
|
+
await press.ArrowDown();
|
|
333
366
|
expect(
|
|
334
367
|
screen.getByRole( 'menuitem', { name: 'Dropdown submenu' } )
|
|
335
368
|
).toHaveFocus();
|
|
336
369
|
|
|
337
|
-
await
|
|
370
|
+
await press.ArrowDown();
|
|
338
371
|
expect(
|
|
339
372
|
screen.getByRole( 'menuitem', { name: 'Dropdown menu item 3' } )
|
|
340
373
|
).toHaveFocus();
|
|
341
374
|
|
|
342
|
-
await
|
|
375
|
+
await press.ArrowDown();
|
|
343
376
|
expect(
|
|
344
377
|
screen.getByRole( 'menuitem', { name: 'Dropdown menu item 1' } )
|
|
345
378
|
).toHaveFocus();
|
|
346
379
|
|
|
347
|
-
await
|
|
380
|
+
await press.ArrowUp();
|
|
348
381
|
expect(
|
|
349
382
|
screen.getByRole( 'menuitem', { name: 'Dropdown menu item 3' } )
|
|
350
383
|
).toHaveFocus();
|
|
351
384
|
|
|
352
|
-
await
|
|
385
|
+
await press.ArrowUp();
|
|
353
386
|
expect(
|
|
354
387
|
screen.getByRole( 'menuitem', { name: 'Dropdown submenu' } )
|
|
355
388
|
).toHaveFocus();
|
|
356
389
|
|
|
357
390
|
// Arrow right/left can be used to enter/leave submenus
|
|
358
|
-
await
|
|
391
|
+
await press.ArrowRight();
|
|
359
392
|
expect(
|
|
360
393
|
screen.getByRole( 'menuitem', {
|
|
361
394
|
name: 'Dropdown submenu item 1',
|
|
362
395
|
} )
|
|
363
396
|
).toHaveFocus();
|
|
364
397
|
|
|
365
|
-
await
|
|
398
|
+
await press.ArrowDown();
|
|
366
399
|
expect(
|
|
367
400
|
screen.getByRole( 'menuitem', {
|
|
368
401
|
name: 'Dropdown submenu item 2',
|
|
369
402
|
} )
|
|
370
403
|
).toHaveFocus();
|
|
371
404
|
|
|
372
|
-
await
|
|
405
|
+
await press.ArrowLeft();
|
|
373
406
|
expect(
|
|
374
407
|
screen.getByRole( 'menuitem', {
|
|
375
408
|
name: 'Dropdown submenu',
|
|
@@ -377,28 +410,28 @@ describe( 'DropdownMenu', () => {
|
|
|
377
410
|
).toHaveFocus();
|
|
378
411
|
|
|
379
412
|
// Spacebar or enter key can also be used to enter a submenu
|
|
380
|
-
await
|
|
413
|
+
await press.Enter();
|
|
381
414
|
expect(
|
|
382
415
|
screen.getByRole( 'menuitem', {
|
|
383
416
|
name: 'Dropdown submenu item 1',
|
|
384
417
|
} )
|
|
385
418
|
).toHaveFocus();
|
|
386
419
|
|
|
387
|
-
await
|
|
420
|
+
await press.ArrowLeft();
|
|
388
421
|
expect(
|
|
389
422
|
screen.getByRole( 'menuitem', {
|
|
390
423
|
name: 'Dropdown submenu',
|
|
391
424
|
} )
|
|
392
425
|
).toHaveFocus();
|
|
393
426
|
|
|
394
|
-
await
|
|
427
|
+
await press.Space();
|
|
395
428
|
expect(
|
|
396
429
|
screen.getByRole( 'menuitem', {
|
|
397
430
|
name: 'Dropdown submenu item 1',
|
|
398
431
|
} )
|
|
399
432
|
).toHaveFocus();
|
|
400
433
|
|
|
401
|
-
await
|
|
434
|
+
await press.ArrowLeft();
|
|
402
435
|
expect(
|
|
403
436
|
screen.getByRole( 'menuitem', {
|
|
404
437
|
name: 'Dropdown submenu',
|
|
@@ -406,32 +439,37 @@ describe( 'DropdownMenu', () => {
|
|
|
406
439
|
).toHaveFocus();
|
|
407
440
|
} );
|
|
408
441
|
|
|
409
|
-
it( 'should check menu
|
|
410
|
-
const user = userEvent.setup();
|
|
411
|
-
|
|
442
|
+
it( 'should check radio items and keep the menu open when clicking (controlled)', async () => {
|
|
412
443
|
const onRadioValueChangeSpy = jest.fn();
|
|
413
444
|
|
|
414
445
|
const ControlledRadioGroup = () => {
|
|
415
|
-
const [ radioValue, setRadioValue ] = useState
|
|
446
|
+
const [ radioValue, setRadioValue ] = useState( 'two' );
|
|
447
|
+
const onRadioChange: React.ComponentProps<
|
|
448
|
+
typeof DropdownMenuRadioItem
|
|
449
|
+
>[ 'onChange' ] = ( e ) => {
|
|
450
|
+
onRadioValueChangeSpy( e.target.value );
|
|
451
|
+
setRadioValue( e.target.value );
|
|
452
|
+
};
|
|
416
453
|
return (
|
|
417
454
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
418
|
-
<
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
<DropdownMenuLabel>
|
|
426
|
-
Radio group label
|
|
427
|
-
</DropdownMenuLabel>
|
|
428
|
-
<DropdownMenuRadioItem value="radio-one">
|
|
455
|
+
<DropdownMenuGroup>
|
|
456
|
+
<DropdownMenuRadioItem
|
|
457
|
+
name="radio-test"
|
|
458
|
+
value="radio-one"
|
|
459
|
+
checked={ radioValue === 'radio-one' }
|
|
460
|
+
onChange={ onRadioChange }
|
|
461
|
+
>
|
|
429
462
|
Radio item one
|
|
430
463
|
</DropdownMenuRadioItem>
|
|
431
|
-
<DropdownMenuRadioItem
|
|
464
|
+
<DropdownMenuRadioItem
|
|
465
|
+
name="radio-test"
|
|
466
|
+
value="radio-two"
|
|
467
|
+
checked={ radioValue === 'radio-two' }
|
|
468
|
+
onChange={ onRadioChange }
|
|
469
|
+
>
|
|
432
470
|
Radio item two
|
|
433
471
|
</DropdownMenuRadioItem>
|
|
434
|
-
</
|
|
472
|
+
</DropdownMenuGroup>
|
|
435
473
|
</DropdownMenu>
|
|
436
474
|
);
|
|
437
475
|
};
|
|
@@ -439,7 +477,7 @@ describe( 'DropdownMenu', () => {
|
|
|
439
477
|
render( <ControlledRadioGroup /> );
|
|
440
478
|
|
|
441
479
|
// Open dropdown
|
|
442
|
-
await
|
|
480
|
+
await click(
|
|
443
481
|
screen.getByRole( 'button', { name: 'Open dropdown' } )
|
|
444
482
|
);
|
|
445
483
|
|
|
@@ -453,7 +491,7 @@ describe( 'DropdownMenu', () => {
|
|
|
453
491
|
).not.toBeChecked();
|
|
454
492
|
|
|
455
493
|
// Click first radio item, make sure that the callback fires
|
|
456
|
-
await
|
|
494
|
+
await click(
|
|
457
495
|
screen.getByRole( 'menuitemradio', { name: 'Radio item one' } )
|
|
458
496
|
);
|
|
459
497
|
expect( onRadioValueChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
@@ -461,11 +499,6 @@ describe( 'DropdownMenu', () => {
|
|
|
461
499
|
'radio-one'
|
|
462
500
|
);
|
|
463
501
|
|
|
464
|
-
// Open dropdown
|
|
465
|
-
await user.click(
|
|
466
|
-
screen.getByRole( 'button', { name: 'Open dropdown' } )
|
|
467
|
-
);
|
|
468
|
-
|
|
469
502
|
// Make sure that first radio is checked
|
|
470
503
|
expect(
|
|
471
504
|
screen.getByRole( 'menuitemradio', { name: 'Radio item one' } )
|
|
@@ -475,7 +508,7 @@ describe( 'DropdownMenu', () => {
|
|
|
475
508
|
).not.toBeChecked();
|
|
476
509
|
|
|
477
510
|
// Click second radio item, make sure that the callback fires
|
|
478
|
-
await
|
|
511
|
+
await click(
|
|
479
512
|
screen.getByRole( 'menuitemradio', { name: 'Radio item two' } )
|
|
480
513
|
);
|
|
481
514
|
expect( onRadioValueChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
@@ -483,11 +516,83 @@ describe( 'DropdownMenu', () => {
|
|
|
483
516
|
'radio-two'
|
|
484
517
|
);
|
|
485
518
|
|
|
519
|
+
// Make sure that second radio is selected
|
|
520
|
+
expect(
|
|
521
|
+
screen.getByRole( 'menuitemradio', { name: 'Radio item one' } )
|
|
522
|
+
).not.toBeChecked();
|
|
523
|
+
expect(
|
|
524
|
+
screen.getByRole( 'menuitemradio', { name: 'Radio item two' } )
|
|
525
|
+
).toBeChecked();
|
|
526
|
+
} );
|
|
527
|
+
|
|
528
|
+
it( 'should check radio items and keep the menu open when clicking (uncontrolled)', async () => {
|
|
529
|
+
const onRadioValueChangeSpy = jest.fn();
|
|
530
|
+
render(
|
|
531
|
+
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
532
|
+
<DropdownMenuGroup>
|
|
533
|
+
<DropdownMenuRadioItem
|
|
534
|
+
name="radio-test"
|
|
535
|
+
value="radio-one"
|
|
536
|
+
onChange={ ( e ) =>
|
|
537
|
+
onRadioValueChangeSpy( e.target.value )
|
|
538
|
+
}
|
|
539
|
+
>
|
|
540
|
+
Radio item one
|
|
541
|
+
</DropdownMenuRadioItem>
|
|
542
|
+
<DropdownMenuRadioItem
|
|
543
|
+
name="radio-test"
|
|
544
|
+
value="radio-two"
|
|
545
|
+
defaultChecked
|
|
546
|
+
onChange={ ( e ) =>
|
|
547
|
+
onRadioValueChangeSpy( e.target.value )
|
|
548
|
+
}
|
|
549
|
+
>
|
|
550
|
+
Radio item two
|
|
551
|
+
</DropdownMenuRadioItem>
|
|
552
|
+
</DropdownMenuGroup>
|
|
553
|
+
</DropdownMenu>
|
|
554
|
+
);
|
|
555
|
+
|
|
486
556
|
// Open dropdown
|
|
487
|
-
await
|
|
557
|
+
await click(
|
|
488
558
|
screen.getByRole( 'button', { name: 'Open dropdown' } )
|
|
489
559
|
);
|
|
490
560
|
|
|
561
|
+
// Radio item two should be checked (`defaultChecked` prop)
|
|
562
|
+
expect( screen.getAllByRole( 'menuitemradio' ) ).toHaveLength( 2 );
|
|
563
|
+
expect(
|
|
564
|
+
screen.getByRole( 'menuitemradio', { name: 'Radio item one' } )
|
|
565
|
+
).not.toBeChecked();
|
|
566
|
+
expect(
|
|
567
|
+
screen.getByRole( 'menuitemradio', { name: 'Radio item two' } )
|
|
568
|
+
).toBeChecked();
|
|
569
|
+
|
|
570
|
+
// Click first radio item, make sure that the callback fires
|
|
571
|
+
await click(
|
|
572
|
+
screen.getByRole( 'menuitemradio', { name: 'Radio item one' } )
|
|
573
|
+
);
|
|
574
|
+
expect( onRadioValueChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
575
|
+
expect( onRadioValueChangeSpy ).toHaveBeenLastCalledWith(
|
|
576
|
+
'radio-one'
|
|
577
|
+
);
|
|
578
|
+
|
|
579
|
+
// Make sure that first radio is checked
|
|
580
|
+
expect(
|
|
581
|
+
screen.getByRole( 'menuitemradio', { name: 'Radio item one' } )
|
|
582
|
+
).toBeChecked();
|
|
583
|
+
expect(
|
|
584
|
+
screen.getByRole( 'menuitemradio', { name: 'Radio item two' } )
|
|
585
|
+
).not.toBeChecked();
|
|
586
|
+
|
|
587
|
+
// Click second radio item, make sure that the callback fires
|
|
588
|
+
await click(
|
|
589
|
+
screen.getByRole( 'menuitemradio', { name: 'Radio item two' } )
|
|
590
|
+
);
|
|
591
|
+
expect( onRadioValueChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
592
|
+
expect( onRadioValueChangeSpy ).toHaveBeenLastCalledWith(
|
|
593
|
+
'radio-two'
|
|
594
|
+
);
|
|
595
|
+
|
|
491
596
|
// Make sure that second radio is selected
|
|
492
597
|
expect(
|
|
493
598
|
screen.getByRole( 'menuitemradio', { name: 'Radio item one' } )
|
|
@@ -497,9 +602,7 @@ describe( 'DropdownMenu', () => {
|
|
|
497
602
|
).toBeChecked();
|
|
498
603
|
} );
|
|
499
604
|
|
|
500
|
-
it( 'should check menu
|
|
501
|
-
const user = userEvent.setup();
|
|
502
|
-
|
|
605
|
+
it( 'should check checkbox items and keep the menu open when clicking (controlled)', async () => {
|
|
503
606
|
const onCheckboxValueChangeSpy = jest.fn();
|
|
504
607
|
|
|
505
608
|
const ControlledRadioGroup = () => {
|
|
@@ -507,26 +610,36 @@ describe( 'DropdownMenu', () => {
|
|
|
507
610
|
useState< boolean >();
|
|
508
611
|
const [ itemTwoChecked, setItemTwoChecked ] =
|
|
509
612
|
useState< boolean >();
|
|
613
|
+
|
|
510
614
|
return (
|
|
511
615
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
512
|
-
<DropdownMenuLabel>
|
|
513
|
-
Checkbox group label
|
|
514
|
-
</DropdownMenuLabel>
|
|
515
616
|
<DropdownMenuCheckboxItem
|
|
617
|
+
name="item-one"
|
|
618
|
+
value="item-one-value"
|
|
516
619
|
checked={ itemOneChecked }
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
620
|
+
onChange={ ( e ) => {
|
|
621
|
+
onCheckboxValueChangeSpy(
|
|
622
|
+
e.target.name,
|
|
623
|
+
e.target.value,
|
|
624
|
+
e.target.checked
|
|
625
|
+
);
|
|
626
|
+
setItemOneChecked( e.target.checked );
|
|
520
627
|
} }
|
|
521
628
|
>
|
|
522
629
|
Checkbox item one
|
|
523
630
|
</DropdownMenuCheckboxItem>
|
|
524
631
|
|
|
525
632
|
<DropdownMenuCheckboxItem
|
|
633
|
+
name="item-two"
|
|
634
|
+
value="item-two-value"
|
|
526
635
|
checked={ itemTwoChecked }
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
636
|
+
onChange={ ( e ) => {
|
|
637
|
+
onCheckboxValueChangeSpy(
|
|
638
|
+
e.target.name,
|
|
639
|
+
e.target.value,
|
|
640
|
+
e.target.checked
|
|
641
|
+
);
|
|
642
|
+
setItemTwoChecked( e.target.checked );
|
|
530
643
|
} }
|
|
531
644
|
>
|
|
532
645
|
Checkbox item two
|
|
@@ -538,7 +651,7 @@ describe( 'DropdownMenu', () => {
|
|
|
538
651
|
render( <ControlledRadioGroup /> );
|
|
539
652
|
|
|
540
653
|
// Open dropdown
|
|
541
|
-
await
|
|
654
|
+
await click(
|
|
542
655
|
screen.getByRole( 'button', { name: 'Open dropdown' } )
|
|
543
656
|
);
|
|
544
657
|
|
|
@@ -558,7 +671,7 @@ describe( 'DropdownMenu', () => {
|
|
|
558
671
|
).not.toBeChecked();
|
|
559
672
|
|
|
560
673
|
// Click first checkbox item, make sure that the callback fires
|
|
561
|
-
await
|
|
674
|
+
await click(
|
|
562
675
|
screen.getByRole( 'menuitemcheckbox', {
|
|
563
676
|
name: 'Checkbox item one',
|
|
564
677
|
} )
|
|
@@ -566,14 +679,10 @@ describe( 'DropdownMenu', () => {
|
|
|
566
679
|
expect( onCheckboxValueChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
567
680
|
expect( onCheckboxValueChangeSpy ).toHaveBeenLastCalledWith(
|
|
568
681
|
'item-one',
|
|
682
|
+
'item-one-value',
|
|
569
683
|
true
|
|
570
684
|
);
|
|
571
685
|
|
|
572
|
-
// Open dropdown
|
|
573
|
-
await user.click(
|
|
574
|
-
screen.getByRole( 'button', { name: 'Open dropdown' } )
|
|
575
|
-
);
|
|
576
|
-
|
|
577
686
|
// Make sure that first checkbox is checked
|
|
578
687
|
expect(
|
|
579
688
|
screen.getByRole( 'menuitemcheckbox', {
|
|
@@ -582,7 +691,7 @@ describe( 'DropdownMenu', () => {
|
|
|
582
691
|
).toBeChecked();
|
|
583
692
|
|
|
584
693
|
// Click second checkbox item, make sure that the callback fires
|
|
585
|
-
await
|
|
694
|
+
await click(
|
|
586
695
|
screen.getByRole( 'menuitemcheckbox', {
|
|
587
696
|
name: 'Checkbox item two',
|
|
588
697
|
} )
|
|
@@ -590,14 +699,10 @@ describe( 'DropdownMenu', () => {
|
|
|
590
699
|
expect( onCheckboxValueChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
591
700
|
expect( onCheckboxValueChangeSpy ).toHaveBeenLastCalledWith(
|
|
592
701
|
'item-two',
|
|
702
|
+
'item-two-value',
|
|
593
703
|
true
|
|
594
704
|
);
|
|
595
705
|
|
|
596
|
-
// Open dropdown
|
|
597
|
-
await user.click(
|
|
598
|
-
screen.getByRole( 'button', { name: 'Open dropdown' } )
|
|
599
|
-
);
|
|
600
|
-
|
|
601
706
|
// Make sure that second checkbox is selected
|
|
602
707
|
expect(
|
|
603
708
|
screen.getByRole( 'menuitemcheckbox', {
|
|
@@ -606,7 +711,7 @@ describe( 'DropdownMenu', () => {
|
|
|
606
711
|
).toBeChecked();
|
|
607
712
|
|
|
608
713
|
// Click second checkbox item, make sure that the callback fires
|
|
609
|
-
await
|
|
714
|
+
await click(
|
|
610
715
|
screen.getByRole( 'menuitemcheckbox', {
|
|
611
716
|
name: 'Checkbox item two',
|
|
612
717
|
} )
|
|
@@ -614,27 +719,203 @@ describe( 'DropdownMenu', () => {
|
|
|
614
719
|
expect( onCheckboxValueChangeSpy ).toHaveBeenCalledTimes( 3 );
|
|
615
720
|
expect( onCheckboxValueChangeSpy ).toHaveBeenLastCalledWith(
|
|
616
721
|
'item-two',
|
|
722
|
+
'item-two-value',
|
|
617
723
|
false
|
|
618
724
|
);
|
|
619
725
|
|
|
726
|
+
// Make sure that second checkbox is unselected
|
|
727
|
+
expect(
|
|
728
|
+
screen.getByRole( 'menuitemcheckbox', {
|
|
729
|
+
name: 'Checkbox item two',
|
|
730
|
+
} )
|
|
731
|
+
).not.toBeChecked();
|
|
732
|
+
} );
|
|
733
|
+
|
|
734
|
+
it( 'should check checkbox items and keep the menu open when clicking (uncontrolled)', async () => {
|
|
735
|
+
const onCheckboxValueChangeSpy = jest.fn();
|
|
736
|
+
|
|
737
|
+
render(
|
|
738
|
+
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
739
|
+
<DropdownMenuCheckboxItem
|
|
740
|
+
name="item-one"
|
|
741
|
+
value="item-one-value"
|
|
742
|
+
onChange={ ( e ) => {
|
|
743
|
+
onCheckboxValueChangeSpy(
|
|
744
|
+
e.target.name,
|
|
745
|
+
e.target.value,
|
|
746
|
+
e.target.checked
|
|
747
|
+
);
|
|
748
|
+
} }
|
|
749
|
+
>
|
|
750
|
+
Checkbox item one
|
|
751
|
+
</DropdownMenuCheckboxItem>
|
|
752
|
+
|
|
753
|
+
<DropdownMenuCheckboxItem
|
|
754
|
+
name="item-two"
|
|
755
|
+
value="item-two-value"
|
|
756
|
+
defaultChecked
|
|
757
|
+
onChange={ ( e ) => {
|
|
758
|
+
onCheckboxValueChangeSpy(
|
|
759
|
+
e.target.name,
|
|
760
|
+
e.target.value,
|
|
761
|
+
e.target.checked
|
|
762
|
+
);
|
|
763
|
+
} }
|
|
764
|
+
>
|
|
765
|
+
Checkbox item two
|
|
766
|
+
</DropdownMenuCheckboxItem>
|
|
767
|
+
</DropdownMenu>
|
|
768
|
+
);
|
|
769
|
+
|
|
620
770
|
// Open dropdown
|
|
621
|
-
await
|
|
771
|
+
await click(
|
|
622
772
|
screen.getByRole( 'button', { name: 'Open dropdown' } )
|
|
623
773
|
);
|
|
624
774
|
|
|
625
|
-
//
|
|
775
|
+
// Checkbox item two should be checked (`defaultChecked`)
|
|
776
|
+
expect( screen.getAllByRole( 'menuitemcheckbox' ) ).toHaveLength(
|
|
777
|
+
2
|
|
778
|
+
);
|
|
779
|
+
expect(
|
|
780
|
+
screen.getByRole( 'menuitemcheckbox', {
|
|
781
|
+
name: 'Checkbox item one',
|
|
782
|
+
} )
|
|
783
|
+
).not.toBeChecked();
|
|
784
|
+
expect(
|
|
785
|
+
screen.getByRole( 'menuitemcheckbox', {
|
|
786
|
+
name: 'Checkbox item two',
|
|
787
|
+
} )
|
|
788
|
+
).toBeChecked();
|
|
789
|
+
|
|
790
|
+
// Click first checkbox item, make sure that the callback fires
|
|
791
|
+
await click(
|
|
792
|
+
screen.getByRole( 'menuitemcheckbox', {
|
|
793
|
+
name: 'Checkbox item one',
|
|
794
|
+
} )
|
|
795
|
+
);
|
|
796
|
+
expect( onCheckboxValueChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
797
|
+
expect( onCheckboxValueChangeSpy ).toHaveBeenLastCalledWith(
|
|
798
|
+
'item-one',
|
|
799
|
+
'item-one-value',
|
|
800
|
+
true
|
|
801
|
+
);
|
|
802
|
+
|
|
803
|
+
// Make sure that first checkbox is checked
|
|
804
|
+
expect(
|
|
805
|
+
screen.getByRole( 'menuitemcheckbox', {
|
|
806
|
+
name: 'Checkbox item one',
|
|
807
|
+
} )
|
|
808
|
+
).toBeChecked();
|
|
809
|
+
|
|
810
|
+
// Click second checkbox item, make sure that the callback fires
|
|
811
|
+
await click(
|
|
812
|
+
screen.getByRole( 'menuitemcheckbox', {
|
|
813
|
+
name: 'Checkbox item two',
|
|
814
|
+
} )
|
|
815
|
+
);
|
|
816
|
+
expect( onCheckboxValueChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
817
|
+
expect( onCheckboxValueChangeSpy ).toHaveBeenLastCalledWith(
|
|
818
|
+
'item-two',
|
|
819
|
+
'item-two-value',
|
|
820
|
+
false
|
|
821
|
+
);
|
|
822
|
+
|
|
823
|
+
// Make sure that second checkbox is unchecked
|
|
626
824
|
expect(
|
|
627
825
|
screen.getByRole( 'menuitemcheckbox', {
|
|
628
826
|
name: 'Checkbox item two',
|
|
629
827
|
} )
|
|
630
828
|
).not.toBeChecked();
|
|
829
|
+
|
|
830
|
+
// Click second checkbox item, make sure that the callback fires
|
|
831
|
+
await click(
|
|
832
|
+
screen.getByRole( 'menuitemcheckbox', {
|
|
833
|
+
name: 'Checkbox item two',
|
|
834
|
+
} )
|
|
835
|
+
);
|
|
836
|
+
expect( onCheckboxValueChangeSpy ).toHaveBeenCalledTimes( 3 );
|
|
837
|
+
expect( onCheckboxValueChangeSpy ).toHaveBeenLastCalledWith(
|
|
838
|
+
'item-two',
|
|
839
|
+
'item-two-value',
|
|
840
|
+
true
|
|
841
|
+
);
|
|
842
|
+
|
|
843
|
+
// Make sure that second checkbox is unselected
|
|
844
|
+
expect(
|
|
845
|
+
screen.getByRole( 'menuitemcheckbox', {
|
|
846
|
+
name: 'Checkbox item two',
|
|
847
|
+
} )
|
|
848
|
+
).toBeChecked();
|
|
849
|
+
} );
|
|
850
|
+
} );
|
|
851
|
+
|
|
852
|
+
describe( 'modality', () => {
|
|
853
|
+
it( 'should be modal by default', async () => {
|
|
854
|
+
render(
|
|
855
|
+
<>
|
|
856
|
+
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
857
|
+
<DropdownMenuItem>Dropdown menu item</DropdownMenuItem>
|
|
858
|
+
</DropdownMenu>
|
|
859
|
+
<button>Button outside of dropdown</button>
|
|
860
|
+
</>
|
|
861
|
+
);
|
|
862
|
+
|
|
863
|
+
// Click to open the menu
|
|
864
|
+
await click(
|
|
865
|
+
screen.getByRole( 'button', {
|
|
866
|
+
name: 'Open dropdown',
|
|
867
|
+
} )
|
|
868
|
+
);
|
|
869
|
+
|
|
870
|
+
// DropdownMenu open, focus is on the menu wrapper
|
|
871
|
+
expect( screen.getByRole( 'menu' ) ).toHaveFocus();
|
|
872
|
+
|
|
873
|
+
expect(
|
|
874
|
+
screen.queryByRole( 'button', {
|
|
875
|
+
name: 'Button outside of dropdown',
|
|
876
|
+
} )
|
|
877
|
+
).not.toBeInTheDocument();
|
|
878
|
+
} );
|
|
879
|
+
|
|
880
|
+
it( 'should not be modal when the `modal` prop is set to `false`', async () => {
|
|
881
|
+
render(
|
|
882
|
+
<>
|
|
883
|
+
<DropdownMenu
|
|
884
|
+
trigger={ <button>Open dropdown</button> }
|
|
885
|
+
modal={ false }
|
|
886
|
+
>
|
|
887
|
+
<DropdownMenuItem>Dropdown menu item</DropdownMenuItem>
|
|
888
|
+
</DropdownMenu>
|
|
889
|
+
<button>Button outside of dropdown</button>
|
|
890
|
+
</>
|
|
891
|
+
);
|
|
892
|
+
|
|
893
|
+
// Click to open the menu
|
|
894
|
+
await click(
|
|
895
|
+
screen.getByRole( 'button', {
|
|
896
|
+
name: 'Open dropdown',
|
|
897
|
+
} )
|
|
898
|
+
);
|
|
899
|
+
|
|
900
|
+
// DropdownMenu open, focus is on the menu wrapper
|
|
901
|
+
expect( screen.getByRole( 'menu' ) ).toHaveFocus();
|
|
902
|
+
|
|
903
|
+
// DropdownMenu is not modal, therefore the outer button is part of the
|
|
904
|
+
// accessibility tree and can be found.
|
|
905
|
+
const outerButton = screen.getByRole( 'button', {
|
|
906
|
+
name: 'Button outside of dropdown',
|
|
907
|
+
} );
|
|
908
|
+
|
|
909
|
+
// The outer button can be focused by pressing tab. Doing so will cause
|
|
910
|
+
// the DropdownMenu to close.
|
|
911
|
+
await press.Tab();
|
|
912
|
+
expect( outerButton ).toBeInTheDocument();
|
|
913
|
+
expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
|
|
631
914
|
} );
|
|
632
915
|
} );
|
|
633
916
|
|
|
634
917
|
describe( 'items prefix and suffix', () => {
|
|
635
918
|
it( 'should display a prefix on regular items', async () => {
|
|
636
|
-
const user = userEvent.setup();
|
|
637
|
-
|
|
638
919
|
render(
|
|
639
920
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
640
921
|
<DropdownMenuItem prefix={ <>Item prefix</> }>
|
|
@@ -644,7 +925,7 @@ describe( 'DropdownMenu', () => {
|
|
|
644
925
|
);
|
|
645
926
|
|
|
646
927
|
// Click to open the menu
|
|
647
|
-
await
|
|
928
|
+
await click(
|
|
648
929
|
screen.getByRole( 'button', {
|
|
649
930
|
name: 'Open dropdown',
|
|
650
931
|
} )
|
|
@@ -659,8 +940,6 @@ describe( 'DropdownMenu', () => {
|
|
|
659
940
|
} );
|
|
660
941
|
|
|
661
942
|
it( 'should display a suffix on regular items', async () => {
|
|
662
|
-
const user = userEvent.setup();
|
|
663
|
-
|
|
664
943
|
render(
|
|
665
944
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
666
945
|
<DropdownMenuItem suffix={ <>Item suffix</> }>
|
|
@@ -670,7 +949,7 @@ describe( 'DropdownMenu', () => {
|
|
|
670
949
|
);
|
|
671
950
|
|
|
672
951
|
// Click to open the menu
|
|
673
|
-
await
|
|
952
|
+
await click(
|
|
674
953
|
screen.getByRole( 'button', {
|
|
675
954
|
name: 'Open dropdown',
|
|
676
955
|
} )
|
|
@@ -685,23 +964,20 @@ describe( 'DropdownMenu', () => {
|
|
|
685
964
|
} );
|
|
686
965
|
|
|
687
966
|
it( 'should display a suffix on radio items', async () => {
|
|
688
|
-
const user = userEvent.setup();
|
|
689
|
-
|
|
690
967
|
render(
|
|
691
968
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
692
|
-
<
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
</DropdownMenuRadioGroup>
|
|
969
|
+
<DropdownMenuRadioItem
|
|
970
|
+
name="radio-test"
|
|
971
|
+
value="radio-one"
|
|
972
|
+
suffix="Radio suffix"
|
|
973
|
+
>
|
|
974
|
+
Radio item one
|
|
975
|
+
</DropdownMenuRadioItem>
|
|
700
976
|
</DropdownMenu>
|
|
701
977
|
);
|
|
702
978
|
|
|
703
979
|
// Click to open the menu
|
|
704
|
-
await
|
|
980
|
+
await click(
|
|
705
981
|
screen.getByRole( 'button', {
|
|
706
982
|
name: 'Open dropdown',
|
|
707
983
|
} )
|
|
@@ -716,18 +992,20 @@ describe( 'DropdownMenu', () => {
|
|
|
716
992
|
} );
|
|
717
993
|
|
|
718
994
|
it( 'should display a suffix on checkbox items', async () => {
|
|
719
|
-
const user = userEvent.setup();
|
|
720
|
-
|
|
721
995
|
render(
|
|
722
996
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
723
|
-
<DropdownMenuCheckboxItem
|
|
997
|
+
<DropdownMenuCheckboxItem
|
|
998
|
+
name="checkbox-test"
|
|
999
|
+
value="checkbox-one"
|
|
1000
|
+
suffix="Checkbox suffix"
|
|
1001
|
+
>
|
|
724
1002
|
Checkbox item one
|
|
725
1003
|
</DropdownMenuCheckboxItem>
|
|
726
1004
|
</DropdownMenu>
|
|
727
1005
|
);
|
|
728
1006
|
|
|
729
1007
|
// Click to open the menu
|
|
730
|
-
await
|
|
1008
|
+
await click(
|
|
731
1009
|
screen.getByRole( 'button', {
|
|
732
1010
|
name: 'Open dropdown',
|
|
733
1011
|
} )
|
|
@@ -744,8 +1022,6 @@ describe( 'DropdownMenu', () => {
|
|
|
744
1022
|
|
|
745
1023
|
describe( 'typeahead', () => {
|
|
746
1024
|
it( 'should highlight matching item', async () => {
|
|
747
|
-
const user = userEvent.setup();
|
|
748
|
-
|
|
749
1025
|
render(
|
|
750
1026
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
751
1027
|
<DropdownMenuItem>One</DropdownMenuItem>
|
|
@@ -754,60 +1030,76 @@ describe( 'DropdownMenu', () => {
|
|
|
754
1030
|
);
|
|
755
1031
|
|
|
756
1032
|
// Click to open the menu
|
|
757
|
-
await
|
|
1033
|
+
await click(
|
|
758
1034
|
screen.getByRole( 'button', {
|
|
759
1035
|
name: 'Open dropdown',
|
|
760
1036
|
} )
|
|
761
1037
|
);
|
|
762
|
-
expect( screen.getByRole( 'menu' ) ).
|
|
1038
|
+
expect( screen.getByRole( 'menu' ) ).toHaveFocus();
|
|
763
1039
|
|
|
764
1040
|
// Type "tw", it should match and focus the item with content "Two"
|
|
765
|
-
await
|
|
1041
|
+
await type( 'tw' );
|
|
766
1042
|
expect(
|
|
767
1043
|
screen.getByRole( 'menuitem', { name: 'Two' } )
|
|
768
1044
|
).toHaveFocus();
|
|
769
1045
|
|
|
770
1046
|
// Wait for the typeahead timer to reset and interpret
|
|
771
1047
|
// the next keystrokes as a new search
|
|
772
|
-
await delay(
|
|
1048
|
+
await delay( 500 );
|
|
773
1049
|
|
|
774
1050
|
// Type "on", it should match and focus the item with content "One"
|
|
775
|
-
await
|
|
1051
|
+
await type( 'on' );
|
|
776
1052
|
expect(
|
|
777
1053
|
screen.getByRole( 'menuitem', { name: 'One' } )
|
|
778
1054
|
).toHaveFocus();
|
|
779
1055
|
} );
|
|
780
1056
|
|
|
781
|
-
it( 'should
|
|
782
|
-
const user = userEvent.setup();
|
|
783
|
-
|
|
1057
|
+
it( 'should keep previous focus when no matches are found', async () => {
|
|
784
1058
|
render(
|
|
785
1059
|
<DropdownMenu trigger={ <button>Open dropdown</button> }>
|
|
786
1060
|
<DropdownMenuItem>One</DropdownMenuItem>
|
|
787
|
-
<DropdownMenuItem
|
|
1061
|
+
<DropdownMenuItem>Two</DropdownMenuItem>
|
|
788
1062
|
</DropdownMenu>
|
|
789
1063
|
);
|
|
790
1064
|
|
|
791
1065
|
// Click to open the menu
|
|
792
|
-
await
|
|
1066
|
+
await click(
|
|
793
1067
|
screen.getByRole( 'button', {
|
|
794
1068
|
name: 'Open dropdown',
|
|
795
1069
|
} )
|
|
796
1070
|
);
|
|
797
|
-
expect( screen.getByRole( 'menu' ) ).
|
|
1071
|
+
expect( screen.getByRole( 'menu' ) ).toHaveFocus();
|
|
798
1072
|
|
|
799
|
-
// Type
|
|
800
|
-
|
|
801
|
-
// retains focus.
|
|
802
|
-
await user.keyboard( 'tw' );
|
|
1073
|
+
// Type a string that doesn't match any items. Focus shouldn't move.
|
|
1074
|
+
await type( 'abc' );
|
|
803
1075
|
expect( screen.getByRole( 'menu' ) ).toHaveFocus();
|
|
804
1076
|
|
|
805
1077
|
// Wait for the typeahead timer to reset and interpret
|
|
806
1078
|
// the next keystrokes as a new search
|
|
807
|
-
await delay(
|
|
1079
|
+
await delay( 500 );
|
|
1080
|
+
|
|
1081
|
+
// Type "on", it should match and focus the item with content "One"
|
|
1082
|
+
await type( 'on' );
|
|
1083
|
+
expect(
|
|
1084
|
+
screen.getByRole( 'menuitem', { name: 'One' } )
|
|
1085
|
+
).toHaveFocus();
|
|
1086
|
+
|
|
1087
|
+
// Wait for the typeahead timer to reset and interpret
|
|
1088
|
+
// the next keystrokes as a new search
|
|
1089
|
+
await delay( 500 );
|
|
1090
|
+
|
|
1091
|
+
// Type a string that doesn't match any items. Focus shouldn't move.
|
|
1092
|
+
await type( 'abc' );
|
|
1093
|
+
expect(
|
|
1094
|
+
screen.getByRole( 'menuitem', { name: 'One' } )
|
|
1095
|
+
).toHaveFocus();
|
|
808
1096
|
|
|
809
|
-
//
|
|
810
|
-
|
|
1097
|
+
// Wait for the typeahead timer to reset and interpret
|
|
1098
|
+
// the next keystrokes as a new search
|
|
1099
|
+
await delay( 500 );
|
|
1100
|
+
|
|
1101
|
+
// Type "tw", it should match and focus the item with content "Two"
|
|
1102
|
+
await type( 'tw' );
|
|
811
1103
|
expect(
|
|
812
1104
|
screen.getByRole( 'menuitem', { name: 'Two' } )
|
|
813
1105
|
).toHaveFocus();
|