@oxy.so/bloom 4.5.0 → 4.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/docs/adoption-matrix.mdx +12 -12
- package/docs/code.mdx +12 -0
- package/docs/context-menu.mdx +2 -0
- package/docs/dropdown-menu.mdx +21 -0
- package/docs/icons.mdx +2 -2
- package/docs/menubar.mdx +6 -2
- package/docs/popover.mdx +4 -2
- package/docs/segmented-control.mdx +12 -0
- package/docs/select.mdx +19 -0
- package/docs/tabs.mdx +12 -0
- package/lib/commonjs/agent-chat/index.web.js.map +1 -1
- package/lib/commonjs/ai-chat/index.web.js.map +1 -1
- package/lib/commonjs/alert-dialog/index.web.js +10 -1
- package/lib/commonjs/alert-dialog/index.web.js.map +1 -1
- package/lib/commonjs/avatar-group/index.web.js.map +1 -1
- package/lib/commonjs/bottom-sheet/index.web.js.map +1 -1
- package/lib/commonjs/code/index.js +13 -0
- package/lib/commonjs/code/index.js.map +1 -1
- package/lib/commonjs/command/index.web.js +5 -0
- package/lib/commonjs/command/index.web.js.map +1 -1
- package/lib/commonjs/composer-loader/ComposerLoader.web.js +9 -0
- package/lib/commonjs/composer-loader/ComposerLoader.web.js.map +1 -1
- package/lib/commonjs/composer-loader/index.web.js.map +1 -1
- package/lib/commonjs/composer-panel/index.web.js.map +1 -1
- package/lib/commonjs/connection-dots/index.web.js.map +1 -1
- package/lib/commonjs/connection-status/index.web.js.map +1 -1
- package/lib/commonjs/content-panel/index.web.js.map +1 -1
- package/lib/commonjs/context-menu/ContextMenu.web.js +22 -4
- package/lib/commonjs/context-menu/ContextMenu.web.js.map +1 -1
- package/lib/commonjs/context-menu/context.js.map +1 -1
- package/lib/commonjs/context-menu/index.web.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +14 -0
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/dialog/index.web.js.map +1 -1
- package/lib/commonjs/dropdown-menu/DropdownMenu.web.js +22 -2
- package/lib/commonjs/dropdown-menu/DropdownMenu.web.js.map +1 -1
- package/lib/commonjs/dropdown-menu/index.web.js.map +1 -1
- package/lib/commonjs/floating/FloatingPanel.js +42 -33
- package/lib/commonjs/floating/FloatingPanel.js.map +1 -1
- package/lib/commonjs/floating/escape-stack.js +90 -0
- package/lib/commonjs/floating/escape-stack.js.map +1 -0
- package/lib/commonjs/floating/menu-keyboard.js +238 -0
- package/lib/commonjs/floating/menu-keyboard.js.map +1 -0
- package/lib/commonjs/floating/menu-sub-flyout.js +28 -16
- package/lib/commonjs/floating/menu-sub-flyout.js.map +1 -1
- package/lib/commonjs/fonts/index.web.js.map +1 -1
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js +10 -0
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js.map +1 -1
- package/lib/commonjs/frosted-icon-button/index.web.js.map +1 -1
- package/lib/commonjs/hooks/roving-focus.js +192 -0
- package/lib/commonjs/hooks/roving-focus.js.map +1 -0
- package/lib/commonjs/hover-card/index.web.js.map +1 -1
- package/lib/commonjs/icons/remix/RiBookReadLine.js +12 -0
- package/lib/commonjs/icons/remix/RiBookReadLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiBugLine.js +12 -0
- package/lib/commonjs/icons/remix/RiBugLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiChat1Line.js +12 -0
- package/lib/commonjs/icons/remix/RiChat1Line.js.map +1 -0
- package/lib/commonjs/icons/remix/RiCloudLine.js +12 -0
- package/lib/commonjs/icons/remix/RiCloudLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiCodeLine.js +12 -0
- package/lib/commonjs/icons/remix/RiCodeLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiCpuLine.js +12 -0
- package/lib/commonjs/icons/remix/RiCpuLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiFloodLine.js +12 -0
- package/lib/commonjs/icons/remix/RiFloodLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiLockUnlockLine.js +12 -0
- package/lib/commonjs/icons/remix/RiLockUnlockLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiMoneyDollarCircleLine.js +12 -0
- package/lib/commonjs/icons/remix/RiMoneyDollarCircleLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiPlayCircleLine.js +12 -0
- package/lib/commonjs/icons/remix/RiPlayCircleLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiRocket2Line.js +12 -0
- package/lib/commonjs/icons/remix/RiRocket2Line.js.map +1 -0
- package/lib/commonjs/icons/remix/RiServerLine.js +12 -0
- package/lib/commonjs/icons/remix/RiServerLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiShareBoxLine.js +12 -0
- package/lib/commonjs/icons/remix/RiShareBoxLine.js.map +1 -0
- package/lib/commonjs/icons/remix/RiTv2Line.js +12 -0
- package/lib/commonjs/icons/remix/RiTv2Line.js.map +1 -0
- package/lib/commonjs/icons/remix/index.js +98 -0
- package/lib/commonjs/icons/remix/index.js.map +1 -1
- package/lib/commonjs/list/index.web.js.map +1 -1
- package/lib/commonjs/loading/Loading.js +21 -157
- package/lib/commonjs/loading/Loading.js.map +1 -1
- package/lib/commonjs/loading/Loading.web.js +23 -157
- package/lib/commonjs/loading/Loading.web.js.map +1 -1
- package/lib/commonjs/loading/LoadingBase.js +202 -0
- package/lib/commonjs/loading/LoadingBase.js.map +1 -0
- package/lib/commonjs/loading/index.web.js.map +1 -1
- package/lib/commonjs/media-flight/index.web.js.map +1 -1
- package/lib/commonjs/menubar/Menubar.js +31 -123
- package/lib/commonjs/menubar/Menubar.js.map +1 -1
- package/lib/commonjs/menubar/Menubar.web.js +33 -114
- package/lib/commonjs/menubar/Menubar.web.js.map +1 -1
- package/lib/commonjs/menubar/MenubarBase.js +154 -0
- package/lib/commonjs/menubar/MenubarBase.js.map +1 -0
- package/lib/commonjs/menubar/index.web.js.map +1 -1
- package/lib/commonjs/popover/index.web.js.map +1 -1
- package/lib/commonjs/popover/parts.js +69 -11
- package/lib/commonjs/popover/parts.js.map +1 -1
- package/lib/commonjs/popover/surface.js +39 -13
- package/lib/commonjs/popover/surface.js.map +1 -1
- package/lib/commonjs/portal/index.web.js.map +1 -1
- package/lib/commonjs/progressive-blur/index.web.js.map +1 -1
- package/lib/commonjs/scroll/index.web.js.map +1 -1
- package/lib/commonjs/segmented-control/SegmentedControl.js +36 -1
- package/lib/commonjs/segmented-control/SegmentedControl.js.map +1 -1
- package/lib/commonjs/select/Select.js +6 -81
- package/lib/commonjs/select/Select.js.map +1 -1
- package/lib/commonjs/select/Select.web.js +147 -85
- package/lib/commonjs/select/Select.web.js.map +1 -1
- package/lib/commonjs/select/index.js +4 -4
- package/lib/commonjs/select/index.js.map +1 -1
- package/lib/commonjs/select/index.web.js +4 -4
- package/lib/commonjs/select/index.web.js.map +1 -1
- package/lib/commonjs/select/shared.js +110 -5
- package/lib/commonjs/select/shared.js.map +1 -1
- package/lib/commonjs/sidebar/SidebarTeamMenu.js +1 -1
- package/lib/commonjs/sidebar/SidebarTeamMenu.js.map +1 -1
- package/lib/commonjs/sidebar/SidebarUserMenu.js +1 -1
- package/lib/commonjs/sidebar/SidebarUserMenu.js.map +1 -1
- package/lib/commonjs/sidebar/parts.js +9 -9
- package/lib/commonjs/sidebar/parts.js.map +1 -1
- package/lib/commonjs/surfaces/SurfaceHost.js +6 -0
- package/lib/commonjs/surfaces/SurfaceHost.js.map +1 -1
- package/lib/commonjs/surfaces/index.web.js +14 -4
- package/lib/commonjs/surfaces/index.web.js.map +1 -1
- package/lib/commonjs/tab-bar/index.web.js +13 -10
- package/lib/commonjs/tab-bar/index.web.js.map +1 -1
- package/lib/commonjs/tabs/Tabs.js +49 -2
- package/lib/commonjs/tabs/Tabs.js.map +1 -1
- package/lib/commonjs/theme/color-scope/index.web.js.map +1 -1
- package/lib/commonjs/theme/persistence.js +12 -1
- package/lib/commonjs/theme/persistence.js.map +1 -1
- package/lib/commonjs/theme/seed-scope/index.web.js.map +1 -1
- package/lib/commonjs/tooltip/index.web.js.map +1 -1
- package/lib/module/agent-chat/index.web.js +5 -3
- package/lib/module/agent-chat/index.web.js.map +1 -1
- package/lib/module/ai-chat/index.web.js +5 -2
- package/lib/module/ai-chat/index.web.js.map +1 -1
- package/lib/module/alert-dialog/index.web.js +10 -1
- package/lib/module/alert-dialog/index.web.js.map +1 -1
- package/lib/module/avatar-group/index.web.js +5 -0
- package/lib/module/avatar-group/index.web.js.map +1 -1
- package/lib/module/bottom-sheet/index.web.js +5 -0
- package/lib/module/bottom-sheet/index.web.js.map +1 -1
- package/lib/module/code/index.js +1 -0
- package/lib/module/code/index.js.map +1 -1
- package/lib/module/command/index.web.js +5 -0
- package/lib/module/command/index.web.js.map +1 -1
- package/lib/module/composer-loader/ComposerLoader.web.js +8 -0
- package/lib/module/composer-loader/ComposerLoader.web.js.map +1 -1
- package/lib/module/composer-loader/index.web.js +5 -2
- package/lib/module/composer-loader/index.web.js.map +1 -1
- package/lib/module/composer-panel/index.web.js +5 -3
- package/lib/module/composer-panel/index.web.js.map +1 -1
- package/lib/module/connection-dots/index.web.js +5 -0
- package/lib/module/connection-dots/index.web.js.map +1 -1
- package/lib/module/connection-status/index.web.js +5 -0
- package/lib/module/connection-status/index.web.js.map +1 -1
- package/lib/module/content-panel/index.web.js +5 -0
- package/lib/module/content-panel/index.web.js.map +1 -1
- package/lib/module/context-menu/ContextMenu.web.js +22 -4
- package/lib/module/context-menu/ContextMenu.web.js.map +1 -1
- package/lib/module/context-menu/context.js.map +1 -1
- package/lib/module/context-menu/index.web.js +5 -0
- package/lib/module/context-menu/index.web.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +13 -0
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/dialog/index.web.js +7 -11
- package/lib/module/dialog/index.web.js.map +1 -1
- package/lib/module/dropdown-menu/DropdownMenu.web.js +23 -3
- package/lib/module/dropdown-menu/DropdownMenu.web.js.map +1 -1
- package/lib/module/dropdown-menu/index.web.js +5 -0
- package/lib/module/dropdown-menu/index.web.js.map +1 -1
- package/lib/module/floating/FloatingPanel.js +42 -33
- package/lib/module/floating/FloatingPanel.js.map +1 -1
- package/lib/module/floating/escape-stack.js +85 -0
- package/lib/module/floating/escape-stack.js.map +1 -0
- package/lib/module/floating/menu-keyboard.js +227 -0
- package/lib/module/floating/menu-keyboard.js.map +1 -0
- package/lib/module/floating/menu-sub-flyout.js +28 -16
- package/lib/module/floating/menu-sub-flyout.js.map +1 -1
- package/lib/module/fonts/index.web.js +5 -20
- package/lib/module/fonts/index.web.js.map +1 -1
- package/lib/module/frosted-icon-button/FrostedIconButton.web.js +9 -0
- package/lib/module/frosted-icon-button/FrostedIconButton.web.js.map +1 -1
- package/lib/module/frosted-icon-button/index.web.js +5 -7
- package/lib/module/frosted-icon-button/index.web.js.map +1 -1
- package/lib/module/hooks/roving-focus.js +181 -0
- package/lib/module/hooks/roving-focus.js.map +1 -0
- package/lib/module/hover-card/index.web.js +5 -0
- package/lib/module/hover-card/index.web.js.map +1 -1
- package/lib/module/icons/remix/RiBookReadLine.js +9 -0
- package/lib/module/icons/remix/RiBookReadLine.js.map +1 -0
- package/lib/module/icons/remix/RiBugLine.js +9 -0
- package/lib/module/icons/remix/RiBugLine.js.map +1 -0
- package/lib/module/icons/remix/RiChat1Line.js +9 -0
- package/lib/module/icons/remix/RiChat1Line.js.map +1 -0
- package/lib/module/icons/remix/RiCloudLine.js +9 -0
- package/lib/module/icons/remix/RiCloudLine.js.map +1 -0
- package/lib/module/icons/remix/RiCodeLine.js +9 -0
- package/lib/module/icons/remix/RiCodeLine.js.map +1 -0
- package/lib/module/icons/remix/RiCpuLine.js +9 -0
- package/lib/module/icons/remix/RiCpuLine.js.map +1 -0
- package/lib/module/icons/remix/RiFloodLine.js +9 -0
- package/lib/module/icons/remix/RiFloodLine.js.map +1 -0
- package/lib/module/icons/remix/RiLockUnlockLine.js +9 -0
- package/lib/module/icons/remix/RiLockUnlockLine.js.map +1 -0
- package/lib/module/icons/remix/RiMoneyDollarCircleLine.js +9 -0
- package/lib/module/icons/remix/RiMoneyDollarCircleLine.js.map +1 -0
- package/lib/module/icons/remix/RiPlayCircleLine.js +9 -0
- package/lib/module/icons/remix/RiPlayCircleLine.js.map +1 -0
- package/lib/module/icons/remix/RiRocket2Line.js +9 -0
- package/lib/module/icons/remix/RiRocket2Line.js.map +1 -0
- package/lib/module/icons/remix/RiServerLine.js +9 -0
- package/lib/module/icons/remix/RiServerLine.js.map +1 -0
- package/lib/module/icons/remix/RiShareBoxLine.js +9 -0
- package/lib/module/icons/remix/RiShareBoxLine.js.map +1 -0
- package/lib/module/icons/remix/RiTv2Line.js +9 -0
- package/lib/module/icons/remix/RiTv2Line.js.map +1 -0
- package/lib/module/icons/remix/index.js +14 -0
- package/lib/module/icons/remix/index.js.map +1 -1
- package/lib/module/list/index.web.js +5 -0
- package/lib/module/list/index.web.js.map +1 -1
- package/lib/module/loading/Loading.js +17 -155
- package/lib/module/loading/Loading.js.map +1 -1
- package/lib/module/loading/Loading.web.js +19 -155
- package/lib/module/loading/Loading.web.js.map +1 -1
- package/lib/module/loading/LoadingBase.js +194 -0
- package/lib/module/loading/LoadingBase.js.map +1 -0
- package/lib/module/loading/index.web.js +5 -13
- package/lib/module/loading/index.web.js.map +1 -1
- package/lib/module/media-flight/index.web.js +5 -9
- package/lib/module/media-flight/index.web.js.map +1 -1
- package/lib/module/menubar/Menubar.js +15 -122
- package/lib/module/menubar/Menubar.js.map +1 -1
- package/lib/module/menubar/Menubar.web.js +18 -114
- package/lib/module/menubar/Menubar.web.js.map +1 -1
- package/lib/module/menubar/MenubarBase.js +146 -0
- package/lib/module/menubar/MenubarBase.js.map +1 -0
- package/lib/module/menubar/index.web.js +5 -0
- package/lib/module/menubar/index.web.js.map +1 -1
- package/lib/module/motion/index.web.js +5 -5
- package/lib/module/motion/index.web.js.map +1 -1
- package/lib/module/popover/index.web.js +5 -0
- package/lib/module/popover/index.web.js.map +1 -1
- package/lib/module/popover/parts.js +70 -12
- package/lib/module/popover/parts.js.map +1 -1
- package/lib/module/popover/surface.js +39 -13
- package/lib/module/popover/surface.js.map +1 -1
- package/lib/module/portal/index.web.js +6 -1
- package/lib/module/portal/index.web.js.map +1 -1
- package/lib/module/progressive-blur/index.web.js +5 -0
- package/lib/module/progressive-blur/index.web.js.map +1 -1
- package/lib/module/scroll/index.web.js +5 -0
- package/lib/module/scroll/index.web.js.map +1 -1
- package/lib/module/segmented-control/SegmentedControl.js +36 -1
- package/lib/module/segmented-control/SegmentedControl.js.map +1 -1
- package/lib/module/select/Select.js +5 -77
- package/lib/module/select/Select.js.map +1 -1
- package/lib/module/select/Select.web.js +147 -82
- package/lib/module/select/Select.web.js.map +1 -1
- package/lib/module/select/index.js +2 -2
- package/lib/module/select/index.js.map +1 -1
- package/lib/module/select/index.web.js +7 -2
- package/lib/module/select/index.web.js.map +1 -1
- package/lib/module/select/shared.js +106 -6
- package/lib/module/select/shared.js.map +1 -1
- package/lib/module/sidebar/SidebarTeamMenu.js +2 -2
- package/lib/module/sidebar/SidebarTeamMenu.js.map +1 -1
- package/lib/module/sidebar/SidebarUserMenu.js +2 -2
- package/lib/module/sidebar/SidebarUserMenu.js.map +1 -1
- package/lib/module/sidebar/parts.js +8 -8
- package/lib/module/sidebar/parts.js.map +1 -1
- package/lib/module/surfaces/SurfaceHost.js +6 -0
- package/lib/module/surfaces/SurfaceHost.js.map +1 -1
- package/lib/module/surfaces/index.web.js +14 -4
- package/lib/module/surfaces/index.web.js.map +1 -1
- package/lib/module/tab-bar/index.web.js +13 -10
- package/lib/module/tab-bar/index.web.js.map +1 -1
- package/lib/module/tabs/Tabs.js +49 -2
- package/lib/module/tabs/Tabs.js.map +1 -1
- package/lib/module/theme/color-scope/index.web.js +5 -0
- package/lib/module/theme/color-scope/index.web.js.map +1 -1
- package/lib/module/theme/persistence.js +12 -1
- package/lib/module/theme/persistence.js.map +1 -1
- package/lib/module/theme/seed-scope/index.web.js +5 -0
- package/lib/module/theme/seed-scope/index.web.js.map +1 -1
- package/lib/module/tooltip/index.web.js +5 -0
- package/lib/module/tooltip/index.web.js.map +1 -1
- package/lib/typescript/commonjs/agent-chat/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/ai-chat/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/alert-dialog/index.web.d.ts +5 -1
- package/lib/typescript/commonjs/alert-dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/avatar-group/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/bottom-sheet/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/code/index.d.ts +2 -0
- package/lib/typescript/commonjs/code/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/command/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/composer-loader/ComposerLoader.web.d.ts +8 -0
- package/lib/typescript/commonjs/composer-loader/ComposerLoader.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/composer-loader/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/composer-panel/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/connection-dots/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/connection-status/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/content-panel/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/context-menu/ContextMenu.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/context-menu/context.d.ts +3 -0
- package/lib/typescript/commonjs/context-menu/context.d.ts.map +1 -1
- package/lib/typescript/commonjs/context-menu/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/index.web.d.ts +2 -1
- package/lib/typescript/commonjs/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dropdown-menu/DropdownMenu.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dropdown-menu/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/FloatingPanel.d.ts +1 -1
- package/lib/typescript/commonjs/floating/FloatingPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/escape-stack.d.ts +55 -0
- package/lib/typescript/commonjs/floating/escape-stack.d.ts.map +1 -0
- package/lib/typescript/commonjs/floating/menu-keyboard.d.ts +57 -0
- package/lib/typescript/commonjs/floating/menu-keyboard.d.ts.map +1 -0
- package/lib/typescript/commonjs/floating/menu-sub-flyout.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/types.d.ts +11 -0
- package/lib/typescript/commonjs/floating/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/fonts/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/frosted-icon-button/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/roving-focus.d.ts +66 -0
- package/lib/typescript/commonjs/hooks/roving-focus.d.ts.map +1 -0
- package/lib/typescript/commonjs/hover-card/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/icons/remix/RiBookReadLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiBookReadLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiBugLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiBugLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiChat1Line.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiChat1Line.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiCloudLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiCloudLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiCodeLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiCodeLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiCpuLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiCpuLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiFloodLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiFloodLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiLockUnlockLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiLockUnlockLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiMoneyDollarCircleLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiMoneyDollarCircleLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiPlayCircleLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiPlayCircleLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiRocket2Line.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiRocket2Line.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiServerLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiServerLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiShareBoxLine.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiShareBoxLine.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/RiTv2Line.d.ts +8 -0
- package/lib/typescript/commonjs/icons/remix/RiTv2Line.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/remix/index.d.ts +14 -0
- package/lib/typescript/commonjs/icons/remix/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/list/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/loading/Loading.d.ts +8 -2
- package/lib/typescript/commonjs/loading/Loading.d.ts.map +1 -1
- package/lib/typescript/commonjs/loading/Loading.web.d.ts +10 -2
- package/lib/typescript/commonjs/loading/Loading.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/loading/LoadingBase.d.ts +64 -0
- package/lib/typescript/commonjs/loading/LoadingBase.d.ts.map +1 -0
- package/lib/typescript/commonjs/loading/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/media-flight/index.web.d.ts +0 -9
- package/lib/typescript/commonjs/media-flight/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/menubar/Menubar.d.ts +14 -9
- package/lib/typescript/commonjs/menubar/Menubar.d.ts.map +1 -1
- package/lib/typescript/commonjs/menubar/Menubar.web.d.ts +8 -6
- package/lib/typescript/commonjs/menubar/Menubar.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/menubar/MenubarBase.d.ts +5 -0
- package/lib/typescript/commonjs/menubar/MenubarBase.d.ts.map +1 -0
- package/lib/typescript/commonjs/menubar/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/motion/index.web.d.ts +0 -5
- package/lib/typescript/commonjs/motion/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/popover/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/popover/parts.d.ts.map +1 -1
- package/lib/typescript/commonjs/popover/surface.d.ts +15 -5
- package/lib/typescript/commonjs/popover/surface.d.ts.map +1 -1
- package/lib/typescript/commonjs/portal/index.web.d.ts +1 -1
- package/lib/typescript/commonjs/portal/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/progressive-blur/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/scroll/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/segmented-control/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/commonjs/select/Select.d.ts +2 -4
- package/lib/typescript/commonjs/select/Select.d.ts.map +1 -1
- package/lib/typescript/commonjs/select/Select.web.d.ts +2 -4
- package/lib/typescript/commonjs/select/Select.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/select/index.d.ts +2 -2
- package/lib/typescript/commonjs/select/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/select/index.web.d.ts +2 -2
- package/lib/typescript/commonjs/select/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/select/shared.d.ts +52 -5
- package/lib/typescript/commonjs/select/shared.d.ts.map +1 -1
- package/lib/typescript/commonjs/select/types.d.ts +6 -0
- package/lib/typescript/commonjs/select/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/sidebar/parts.d.ts +8 -2
- package/lib/typescript/commonjs/sidebar/parts.d.ts.map +1 -1
- package/lib/typescript/commonjs/surfaces/SurfaceHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/surfaces/index.web.d.ts +9 -4
- package/lib/typescript/commonjs/surfaces/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/tab-bar/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/tabs/Tabs.d.ts.map +1 -1
- package/lib/typescript/commonjs/tabs/types.d.ts +6 -0
- package/lib/typescript/commonjs/tabs/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-scope/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/persistence.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/seed-scope/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/tooltip/index.web.d.ts.map +1 -1
- package/lib/typescript/module/agent-chat/index.web.d.ts.map +1 -1
- package/lib/typescript/module/ai-chat/index.web.d.ts.map +1 -1
- package/lib/typescript/module/alert-dialog/index.web.d.ts +5 -1
- package/lib/typescript/module/alert-dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/module/avatar-group/index.web.d.ts.map +1 -1
- package/lib/typescript/module/bottom-sheet/index.web.d.ts.map +1 -1
- package/lib/typescript/module/code/index.d.ts +2 -0
- package/lib/typescript/module/code/index.d.ts.map +1 -1
- package/lib/typescript/module/command/index.web.d.ts.map +1 -1
- package/lib/typescript/module/composer-loader/ComposerLoader.web.d.ts +8 -0
- package/lib/typescript/module/composer-loader/ComposerLoader.web.d.ts.map +1 -1
- package/lib/typescript/module/composer-loader/index.web.d.ts.map +1 -1
- package/lib/typescript/module/composer-panel/index.web.d.ts.map +1 -1
- package/lib/typescript/module/connection-dots/index.web.d.ts.map +1 -1
- package/lib/typescript/module/connection-status/index.web.d.ts.map +1 -1
- package/lib/typescript/module/content-panel/index.web.d.ts.map +1 -1
- package/lib/typescript/module/context-menu/ContextMenu.web.d.ts.map +1 -1
- package/lib/typescript/module/context-menu/context.d.ts +3 -0
- package/lib/typescript/module/context-menu/context.d.ts.map +1 -1
- package/lib/typescript/module/context-menu/index.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/index.web.d.ts +2 -1
- package/lib/typescript/module/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/module/dropdown-menu/DropdownMenu.web.d.ts.map +1 -1
- package/lib/typescript/module/dropdown-menu/index.web.d.ts.map +1 -1
- package/lib/typescript/module/floating/FloatingPanel.d.ts +1 -1
- package/lib/typescript/module/floating/FloatingPanel.d.ts.map +1 -1
- package/lib/typescript/module/floating/escape-stack.d.ts +55 -0
- package/lib/typescript/module/floating/escape-stack.d.ts.map +1 -0
- package/lib/typescript/module/floating/menu-keyboard.d.ts +57 -0
- package/lib/typescript/module/floating/menu-keyboard.d.ts.map +1 -0
- package/lib/typescript/module/floating/menu-sub-flyout.d.ts.map +1 -1
- package/lib/typescript/module/floating/types.d.ts +11 -0
- package/lib/typescript/module/floating/types.d.ts.map +1 -1
- package/lib/typescript/module/fonts/index.web.d.ts.map +1 -1
- package/lib/typescript/module/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -1
- package/lib/typescript/module/frosted-icon-button/index.web.d.ts.map +1 -1
- package/lib/typescript/module/hooks/roving-focus.d.ts +66 -0
- package/lib/typescript/module/hooks/roving-focus.d.ts.map +1 -0
- package/lib/typescript/module/hover-card/index.web.d.ts.map +1 -1
- package/lib/typescript/module/icons/remix/RiBookReadLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiBookReadLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiBugLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiBugLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiChat1Line.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiChat1Line.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiCloudLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiCloudLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiCodeLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiCodeLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiCpuLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiCpuLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiFloodLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiFloodLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiLockUnlockLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiLockUnlockLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiMoneyDollarCircleLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiMoneyDollarCircleLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiPlayCircleLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiPlayCircleLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiRocket2Line.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiRocket2Line.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiServerLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiServerLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiShareBoxLine.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiShareBoxLine.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/RiTv2Line.d.ts +8 -0
- package/lib/typescript/module/icons/remix/RiTv2Line.d.ts.map +1 -0
- package/lib/typescript/module/icons/remix/index.d.ts +14 -0
- package/lib/typescript/module/icons/remix/index.d.ts.map +1 -1
- package/lib/typescript/module/list/index.web.d.ts.map +1 -1
- package/lib/typescript/module/loading/Loading.d.ts +8 -2
- package/lib/typescript/module/loading/Loading.d.ts.map +1 -1
- package/lib/typescript/module/loading/Loading.web.d.ts +10 -2
- package/lib/typescript/module/loading/Loading.web.d.ts.map +1 -1
- package/lib/typescript/module/loading/LoadingBase.d.ts +64 -0
- package/lib/typescript/module/loading/LoadingBase.d.ts.map +1 -0
- package/lib/typescript/module/loading/index.web.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/index.web.d.ts +0 -9
- package/lib/typescript/module/media-flight/index.web.d.ts.map +1 -1
- package/lib/typescript/module/menubar/Menubar.d.ts +14 -9
- package/lib/typescript/module/menubar/Menubar.d.ts.map +1 -1
- package/lib/typescript/module/menubar/Menubar.web.d.ts +8 -6
- package/lib/typescript/module/menubar/Menubar.web.d.ts.map +1 -1
- package/lib/typescript/module/menubar/MenubarBase.d.ts +5 -0
- package/lib/typescript/module/menubar/MenubarBase.d.ts.map +1 -0
- package/lib/typescript/module/menubar/index.web.d.ts.map +1 -1
- package/lib/typescript/module/motion/index.web.d.ts +0 -5
- package/lib/typescript/module/motion/index.web.d.ts.map +1 -1
- package/lib/typescript/module/popover/index.web.d.ts.map +1 -1
- package/lib/typescript/module/popover/parts.d.ts.map +1 -1
- package/lib/typescript/module/popover/surface.d.ts +15 -5
- package/lib/typescript/module/popover/surface.d.ts.map +1 -1
- package/lib/typescript/module/portal/index.web.d.ts +1 -1
- package/lib/typescript/module/portal/index.web.d.ts.map +1 -1
- package/lib/typescript/module/progressive-blur/index.web.d.ts.map +1 -1
- package/lib/typescript/module/scroll/index.web.d.ts.map +1 -1
- package/lib/typescript/module/segmented-control/SegmentedControl.d.ts.map +1 -1
- package/lib/typescript/module/select/Select.d.ts +2 -4
- package/lib/typescript/module/select/Select.d.ts.map +1 -1
- package/lib/typescript/module/select/Select.web.d.ts +2 -4
- package/lib/typescript/module/select/Select.web.d.ts.map +1 -1
- package/lib/typescript/module/select/index.d.ts +2 -2
- package/lib/typescript/module/select/index.d.ts.map +1 -1
- package/lib/typescript/module/select/index.web.d.ts +2 -2
- package/lib/typescript/module/select/index.web.d.ts.map +1 -1
- package/lib/typescript/module/select/shared.d.ts +52 -5
- package/lib/typescript/module/select/shared.d.ts.map +1 -1
- package/lib/typescript/module/select/types.d.ts +6 -0
- package/lib/typescript/module/select/types.d.ts.map +1 -1
- package/lib/typescript/module/sidebar/parts.d.ts +8 -2
- package/lib/typescript/module/sidebar/parts.d.ts.map +1 -1
- package/lib/typescript/module/surfaces/SurfaceHost.d.ts.map +1 -1
- package/lib/typescript/module/surfaces/index.web.d.ts +9 -4
- package/lib/typescript/module/surfaces/index.web.d.ts.map +1 -1
- package/lib/typescript/module/tab-bar/index.web.d.ts.map +1 -1
- package/lib/typescript/module/tabs/Tabs.d.ts.map +1 -1
- package/lib/typescript/module/tabs/types.d.ts +6 -0
- package/lib/typescript/module/tabs/types.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-scope/index.web.d.ts.map +1 -1
- package/lib/typescript/module/theme/persistence.d.ts.map +1 -1
- package/lib/typescript/module/theme/seed-scope/index.web.d.ts.map +1 -1
- package/lib/typescript/module/tooltip/index.web.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/agent-chat/index.web.ts +5 -3
- package/src/ai-chat/index.web.ts +5 -2
- package/src/alert-dialog/index.web.ts +10 -1
- package/src/avatar-group/index.web.ts +5 -0
- package/src/bottom-sheet/index.web.ts +5 -0
- package/src/code/index.ts +2 -0
- package/src/command/index.web.ts +5 -0
- package/src/composer-loader/ComposerLoader.web.tsx +8 -0
- package/src/composer-loader/index.web.ts +5 -2
- package/src/composer-panel/index.web.ts +5 -3
- package/src/connection-dots/index.web.ts +5 -0
- package/src/connection-status/index.web.ts +5 -0
- package/src/content-panel/index.web.ts +5 -0
- package/src/context-menu/ContextMenu.web.tsx +26 -3
- package/src/context-menu/context.ts +3 -0
- package/src/context-menu/index.web.ts +5 -0
- package/src/dialog/Dialog.web.tsx +13 -0
- package/src/dialog/index.web.ts +7 -11
- package/src/dropdown-menu/DropdownMenu.web.tsx +25 -2
- package/src/dropdown-menu/index.web.ts +5 -0
- package/src/floating/FloatingPanel.tsx +37 -38
- package/src/floating/escape-stack.ts +92 -0
- package/src/floating/menu-keyboard.ts +242 -0
- package/src/floating/menu-sub-flyout.tsx +22 -17
- package/src/floating/types.ts +11 -0
- package/src/fonts/index.web.ts +5 -20
- package/src/frosted-icon-button/FrostedIconButton.web.tsx +9 -0
- package/src/frosted-icon-button/index.web.ts +5 -7
- package/src/hooks/roving-focus.ts +204 -0
- package/src/hover-card/index.web.ts +5 -0
- package/src/icons/remix/RiBookReadLine.tsx +6 -0
- package/src/icons/remix/RiBugLine.tsx +6 -0
- package/src/icons/remix/RiChat1Line.tsx +6 -0
- package/src/icons/remix/RiCloudLine.tsx +6 -0
- package/src/icons/remix/RiCodeLine.tsx +6 -0
- package/src/icons/remix/RiCpuLine.tsx +6 -0
- package/src/icons/remix/RiFloodLine.tsx +6 -0
- package/src/icons/remix/RiLockUnlockLine.tsx +6 -0
- package/src/icons/remix/RiMoneyDollarCircleLine.tsx +6 -0
- package/src/icons/remix/RiPlayCircleLine.tsx +6 -0
- package/src/icons/remix/RiRocket2Line.tsx +6 -0
- package/src/icons/remix/RiServerLine.tsx +6 -0
- package/src/icons/remix/RiShareBoxLine.tsx +6 -0
- package/src/icons/remix/RiTv2Line.tsx +6 -0
- package/src/icons/remix/index.ts +14 -0
- package/src/list/index.web.ts +5 -0
- package/src/loading/Loading.tsx +15 -135
- package/src/loading/Loading.web.tsx +16 -134
- package/src/loading/LoadingBase.tsx +170 -0
- package/src/loading/index.web.ts +5 -13
- package/src/media-flight/index.web.ts +5 -9
- package/src/menubar/Menubar.tsx +16 -147
- package/src/menubar/Menubar.web.tsx +15 -138
- package/src/menubar/MenubarBase.tsx +170 -0
- package/src/menubar/index.web.ts +5 -0
- package/src/motion/index.web.ts +5 -5
- package/src/popover/index.web.ts +5 -0
- package/src/popover/parts.tsx +76 -12
- package/src/popover/surface.ts +68 -15
- package/src/portal/index.web.ts +6 -1
- package/src/progressive-blur/index.web.ts +5 -0
- package/src/scroll/index.web.ts +5 -0
- package/src/segmented-control/SegmentedControl.tsx +45 -1
- package/src/select/Select.tsx +4 -67
- package/src/select/Select.web.tsx +133 -69
- package/src/select/index.ts +3 -3
- package/src/select/index.web.ts +8 -3
- package/src/select/shared.tsx +107 -5
- package/src/select/types.ts +6 -0
- package/src/sidebar/SidebarTeamMenu.tsx +2 -2
- package/src/sidebar/SidebarUserMenu.tsx +2 -2
- package/src/sidebar/parts.tsx +8 -9
- package/src/surfaces/SurfaceHost.tsx +6 -0
- package/src/surfaces/index.web.ts +14 -4
- package/src/tab-bar/index.web.ts +13 -10
- package/src/tabs/Tabs.tsx +65 -1
- package/src/tabs/types.ts +6 -0
- package/src/theme/color-scope/index.web.ts +5 -0
- package/src/theme/persistence.ts +11 -1
- package/src/theme/seed-scope/index.web.ts +5 -0
- package/src/tooltip/index.web.ts +5 -0
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
// AUTO-GENERATED by scripts/generate-platform-exports.mjs — DO NOT EDIT.
|
|
2
|
+
// Source of truth: src/dropdown-menu/index.ts.
|
|
3
|
+
// Re-run `bun run generate:exports` (or any `bun run build`) after
|
|
4
|
+
// changing that barrel or the set of web-forked subpaths.
|
|
5
|
+
|
|
1
6
|
export {
|
|
2
7
|
DropdownMenu,
|
|
3
8
|
DropdownMenuTrigger,
|
|
@@ -89,6 +89,7 @@ import {
|
|
|
89
89
|
VIEWPORT_GUTTER,
|
|
90
90
|
} from './constants';
|
|
91
91
|
import { useMenuPalette } from './menu-palette';
|
|
92
|
+
import { pushFloatingEscape } from './escape-stack';
|
|
92
93
|
import { cx } from './shared';
|
|
93
94
|
import type { FloatingPanelProps, FloatingSide } from './types';
|
|
94
95
|
import { useFrameThrottle } from './use-frame-throttle';
|
|
@@ -105,36 +106,31 @@ const AnimatedPanel = Animated.createAnimatedComponent(StyledView);
|
|
|
105
106
|
const MENU_EASING = Easing.bezier(...MENU_MOTION_EASING);
|
|
106
107
|
|
|
107
108
|
/**
|
|
108
|
-
* The
|
|
109
|
-
* `
|
|
110
|
-
*
|
|
111
|
-
*
|
|
109
|
+
* The ONE motion every anchored surface runs: 150ms `ease-out`, fade +
|
|
110
|
+
* `scale-95` + 2px blur, no slide, scaling from the corner nearest the
|
|
111
|
+
* trigger, and the same shape reversed on the way out. It was written out
|
|
112
|
+
* three times, once per surface, with only the chrome differing — three
|
|
113
|
+
* spellings of one decision, any of which could be edited alone.
|
|
114
|
+
*/
|
|
115
|
+
const MENU_MOTION = {
|
|
116
|
+
duration: MENU_MOTION_DURATION,
|
|
117
|
+
easing: MENU_EASING,
|
|
118
|
+
scaleFrom: MENU_MOTION_SCALE_FROM,
|
|
119
|
+
slide: 0,
|
|
120
|
+
blur: MENU_MOTION_BLUR,
|
|
121
|
+
} as const;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The per-surface chrome. `menu` and `listbox` use the menu recipe
|
|
125
|
+
* (`constants.ts`'s `MENU_PANEL_CLASS` / `LISTBOX_PANEL_CLASS`) with colours
|
|
126
|
+
* from `menu-palette.ts`; `popover` carries NO chrome of its own here, because
|
|
127
|
+
* `popover/surface.ts` resolves the whole panel inline and hands it over as
|
|
128
|
+
* `style` so a caller's `className` can still override any one piece of it.
|
|
112
129
|
*/
|
|
113
130
|
const SURFACE = {
|
|
114
|
-
popover: {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
easing: MENU_EASING,
|
|
118
|
-
scaleFrom: MENU_MOTION_SCALE_FROM,
|
|
119
|
-
slide: 0,
|
|
120
|
-
blur: MENU_MOTION_BLUR,
|
|
121
|
-
},
|
|
122
|
-
menu: {
|
|
123
|
-
className: MENU_PANEL_CLASS,
|
|
124
|
-
duration: MENU_MOTION_DURATION,
|
|
125
|
-
easing: MENU_EASING,
|
|
126
|
-
scaleFrom: MENU_MOTION_SCALE_FROM,
|
|
127
|
-
slide: 0,
|
|
128
|
-
blur: MENU_MOTION_BLUR,
|
|
129
|
-
},
|
|
130
|
-
listbox: {
|
|
131
|
-
className: LISTBOX_PANEL_CLASS,
|
|
132
|
-
duration: MENU_MOTION_DURATION,
|
|
133
|
-
easing: MENU_EASING,
|
|
134
|
-
scaleFrom: MENU_MOTION_SCALE_FROM,
|
|
135
|
-
slide: 0,
|
|
136
|
-
blur: MENU_MOTION_BLUR,
|
|
137
|
-
},
|
|
131
|
+
popover: { ...MENU_MOTION, className: '' },
|
|
132
|
+
menu: { ...MENU_MOTION, className: MENU_PANEL_CLASS },
|
|
133
|
+
listbox: { ...MENU_MOTION, className: LISTBOX_PANEL_CLASS },
|
|
138
134
|
} as const;
|
|
139
135
|
|
|
140
136
|
/**
|
|
@@ -203,6 +199,7 @@ export function FloatingPanel({
|
|
|
203
199
|
testID,
|
|
204
200
|
children,
|
|
205
201
|
surface = 'popover',
|
|
202
|
+
panelRef,
|
|
206
203
|
}: FloatingPanelProps) {
|
|
207
204
|
const chrome = SURFACE[surface];
|
|
208
205
|
const isMenuSurface = surface !== 'popover';
|
|
@@ -224,8 +221,11 @@ export function FloatingPanel({
|
|
|
224
221
|
const reducedMotion = useReducedMotion();
|
|
225
222
|
const progress = useSharedValue(0);
|
|
226
223
|
|
|
224
|
+
const panelRefRef = useRef(panelRef);
|
|
225
|
+
panelRefRef.current = panelRef;
|
|
227
226
|
const attach = useCallback((node: View | null) => {
|
|
228
227
|
setPanelNode(node);
|
|
228
|
+
panelRefRef.current?.(node);
|
|
229
229
|
}, []);
|
|
230
230
|
|
|
231
231
|
const store = useCallback((next: DropdownPlacement | null) => {
|
|
@@ -438,18 +438,17 @@ export function FloatingPanel({
|
|
|
438
438
|
[progress, slideX, slideY, scaleFrom, blurFrom],
|
|
439
439
|
);
|
|
440
440
|
|
|
441
|
+
// Escape dismisses the INNERMOST open surface and nothing under it — a Select
|
|
442
|
+
// inside a Dialog closes its list, not the dialog (`escape-stack.ts`). The
|
|
443
|
+
// entry is taken once per open and calls the CURRENT `onDismiss` through a
|
|
444
|
+
// ref: re-pushing it whenever the callback's identity changed would move a
|
|
445
|
+
// re-rendered parent menu above its own open submenu.
|
|
446
|
+
const onDismissRef = useRef(onDismiss);
|
|
447
|
+
onDismissRef.current = onDismiss;
|
|
441
448
|
useEffect(() => {
|
|
442
449
|
if (phase !== 'open' || !dismissible || typeof document === 'undefined') return;
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
// Stop the key reaching a Dialog underneath: the innermost open surface is
|
|
446
|
-
// the one Escape dismisses.
|
|
447
|
-
event.stopPropagation();
|
|
448
|
-
onDismiss();
|
|
449
|
-
};
|
|
450
|
-
document.addEventListener('keydown', onKeyDown);
|
|
451
|
-
return () => document.removeEventListener('keydown', onKeyDown);
|
|
452
|
-
}, [phase, dismissible, onDismiss]);
|
|
450
|
+
return pushFloatingEscape(() => onDismissRef.current());
|
|
451
|
+
}, [phase, dismissible]);
|
|
453
452
|
|
|
454
453
|
// The NON-modal outside press. Deliberately `pointerdown` in the CAPTURE
|
|
455
454
|
// phase and never `preventDefault`: the surface has to be gone before the
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escape for the anchored surfaces — WEB. One listener for every open
|
|
3
|
+
* `FloatingPanel`, dismissing only the INNERMOST (most recently opened) one and
|
|
4
|
+
* keeping the key from every enclosing surface.
|
|
5
|
+
*
|
|
6
|
+
* THE DEFECT IT REPLACES. Each panel added its own bubble-phase `keydown`
|
|
7
|
+
* listener on `document` and called `stopPropagation()`. A `Dialog` listens on
|
|
8
|
+
* `document` too, and `stopPropagation` does not stop a SIBLING listener on the
|
|
9
|
+
* same node: listeners on one node run in registration order, and the dialog —
|
|
10
|
+
* open first — registered first. So Escape on a `Select` inside a `Dialog`
|
|
11
|
+
* closed the DIALOG, and the list with it. Two panels open at once (a select
|
|
12
|
+
* inside a popover) had the same shape: the outer one registered first and
|
|
13
|
+
* closed first.
|
|
14
|
+
*
|
|
15
|
+
* THE MECHANISM.
|
|
16
|
+
*
|
|
17
|
+
* - The listener sits on `document.documentElement` in the BUBBLE phase. That
|
|
18
|
+
* is one node BELOW `document`, so it runs before any `document` listener —
|
|
19
|
+
* the Dialog's included — and its `stopPropagation()` keeps the key from
|
|
20
|
+
* ever reaching them. It is also ABOVE React's roots (the app root and every
|
|
21
|
+
* portal container sit inside `<body>`), so a control inside a panel still
|
|
22
|
+
* sees Escape first and can keep it — the composer's model-picker search
|
|
23
|
+
* clears its query on Escape and stops the key, exactly as it did when the
|
|
24
|
+
* panel listened on `document`.
|
|
25
|
+
* - Entries form a stack: the panel opened LAST is dismissed, whatever order
|
|
26
|
+
* the listeners happen to be in.
|
|
27
|
+
* - `hasOpenFloatingSurface()` lets the surface host's window-capture Escape
|
|
28
|
+
* router (`surfaces/SurfaceHost.tsx`) stand aside while a panel is open. It
|
|
29
|
+
* runs before anything here, so without the check it would dismiss the
|
|
30
|
+
* stacked dialog UNDER the open list.
|
|
31
|
+
*
|
|
32
|
+
* `globalThis`-anchored for the same reason as `overlay/stack.ts`: the families
|
|
33
|
+
* that open panels are imported through different subpaths, and a bundler can
|
|
34
|
+
* resolve two physical copies of this module.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
interface EscapeEntry {
|
|
38
|
+
dismiss: () => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface EscapeRegistry {
|
|
42
|
+
stack: EscapeEntry[];
|
|
43
|
+
listener: ((event: KeyboardEvent) => void) | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
declare global {
|
|
47
|
+
// eslint-disable-next-line no-var
|
|
48
|
+
var __oxy_so_bloom_floating_escape__: EscapeRegistry | undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function registry(): EscapeRegistry {
|
|
52
|
+
globalThis.__oxy_so_bloom_floating_escape__ ??= { stack: [], listener: null };
|
|
53
|
+
return globalThis.__oxy_so_bloom_floating_escape__;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function onKeyDown(event: KeyboardEvent): void {
|
|
57
|
+
if (event.key !== 'Escape') return;
|
|
58
|
+
const stack = registry().stack;
|
|
59
|
+
const top = stack[stack.length - 1];
|
|
60
|
+
if (!top) return;
|
|
61
|
+
event.stopPropagation();
|
|
62
|
+
top.dismiss();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Put an open surface on top of the Escape stack. Returns the release, which
|
|
67
|
+
* removes exactly this entry wherever it now sits — a parent can close before
|
|
68
|
+
* its submenu's effect cleanup runs.
|
|
69
|
+
*/
|
|
70
|
+
export function pushFloatingEscape(dismiss: () => void): () => void {
|
|
71
|
+
const reg = registry();
|
|
72
|
+
const entry: EscapeEntry = { dismiss };
|
|
73
|
+
reg.stack.push(entry);
|
|
74
|
+
if (!reg.listener && typeof document !== 'undefined') {
|
|
75
|
+
reg.listener = onKeyDown;
|
|
76
|
+
document.documentElement.addEventListener('keydown', onKeyDown);
|
|
77
|
+
}
|
|
78
|
+
return () => {
|
|
79
|
+
const current = registry();
|
|
80
|
+
const index = current.stack.indexOf(entry);
|
|
81
|
+
if (index >= 0) current.stack.splice(index, 1);
|
|
82
|
+
if (current.stack.length === 0 && current.listener && typeof document !== 'undefined') {
|
|
83
|
+
document.documentElement.removeEventListener('keydown', current.listener);
|
|
84
|
+
current.listener = null;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Whether an anchored surface is open and will take the next Escape. */
|
|
90
|
+
export function hasOpenFloatingSurface(): boolean {
|
|
91
|
+
return registry().stack.length > 0;
|
|
92
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keyboard half of the ARIA menu-button pattern for the anchored menus —
|
|
3
|
+
* `DropdownMenu`, `ContextMenu`, `Menubar` and their flyout sub-menus — on WEB.
|
|
4
|
+
*
|
|
5
|
+
* What shipped: the trigger opened the menu on Enter/Space (it is a real
|
|
6
|
+
* `<button>`) and focus STAYED on it. The rows are portaled to the end of
|
|
7
|
+
* `<body>`, so the arrow keys had nothing to move, Tab walked on through the
|
|
8
|
+
* page BEHIND the open menu, and a keyboard user could open a menu and choose
|
|
9
|
+
* nothing. The markup was right throughout (`role="menu"`, `menuitem`,
|
|
10
|
+
* `aria-checked`), which is why nothing flagged it.
|
|
11
|
+
*
|
|
12
|
+
* The contract now:
|
|
13
|
+
*
|
|
14
|
+
* - Opening from the keyboard moves focus INTO the menu: Enter, Space and
|
|
15
|
+
* ArrowDown land on the first enabled row, ArrowUp on the last. A pointer
|
|
16
|
+
* open leaves focus where the pointer put it; an arrow on the trigger of an
|
|
17
|
+
* already-open menu then moves it in.
|
|
18
|
+
* - In the menu: ArrowDown/ArrowUp move between enabled rows and WRAP;
|
|
19
|
+
* Home/End jump to the ends; Enter and Space activate the row — a checkbox
|
|
20
|
+
* row toggles, a radio row selects, and a row's `keepOpen` still decides
|
|
21
|
+
* whether the menu closes. react-native-web presses a `menuitem`, `checkbox`
|
|
22
|
+
* or `radio` on Enter only (`PressResponder.isValidKeyPress` limits Space to
|
|
23
|
+
* `role="button"`), so Space is supplied here.
|
|
24
|
+
* - Tab closes the menu and returns focus to the trigger — a menu is not in
|
|
25
|
+
* the page's tab sequence. Escape closes the innermost surface
|
|
26
|
+
* (`escape-stack.ts`) and focus returns the same way.
|
|
27
|
+
* - The sub-menu keys stay `menu-sub-flyout.tsx`'s: → on a sub trigger opens
|
|
28
|
+
* the flyout and focuses its first row, ← inside it closes it and refocuses
|
|
29
|
+
* the trigger row.
|
|
30
|
+
*
|
|
31
|
+
* DOM listeners rather than props, like the sub-menu's: a row is
|
|
32
|
+
* `shared.tsx`'s `MenuRowShell`, the trigger may be the caller's own element
|
|
33
|
+
* under `asChild`, and the order of rows is whatever the caller rendered —
|
|
34
|
+
* the DOM already holds all of it. Every entry point is inert without a DOM
|
|
35
|
+
* node, so native (the menu is a bottom sheet there) is untouched.
|
|
36
|
+
*/
|
|
37
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
38
|
+
|
|
39
|
+
import { isSpaceKey, rovingItems, rovingMove, rovingTarget } from '../hooks/roving-focus';
|
|
40
|
+
import { MENU_MOTION_DURATION } from './constants';
|
|
41
|
+
|
|
42
|
+
/** Every role a menu ROW can carry — the rows a pointer or a key can land on. */
|
|
43
|
+
export const MENU_ROW_SELECTOR =
|
|
44
|
+
'[role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="checkbox"], [role="radio"]';
|
|
45
|
+
|
|
46
|
+
/** A panel, so a nested panel's rows are never counted as this one's. */
|
|
47
|
+
const MENU_PANEL_SELECTOR = '[role="menu"]';
|
|
48
|
+
|
|
49
|
+
export type MenuFocusEdge = 'first' | 'last';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Where focus should land the next time the menu's panel is ready — set by a
|
|
53
|
+
* key on the trigger, consumed by the panel. Owned by the family ROOT, which is
|
|
54
|
+
* the one component both the trigger and the content can reach.
|
|
55
|
+
*/
|
|
56
|
+
export interface MenuFocusIntent {
|
|
57
|
+
/** The pending edge, or `null` for "leave focus alone" (a pointer open). */
|
|
58
|
+
edge: React.MutableRefObject<MenuFocusEdge | null>;
|
|
59
|
+
/** Bumped to ask an ALREADY-open panel to take focus. */
|
|
60
|
+
tick: number;
|
|
61
|
+
request: (edge: MenuFocusEdge) => void;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function useMenuFocusIntent(): MenuFocusIntent {
|
|
65
|
+
const edge = useRef<MenuFocusEdge | null>(null);
|
|
66
|
+
const [tick, setTick] = useState(0);
|
|
67
|
+
const request = useCallback((next: MenuFocusEdge) => {
|
|
68
|
+
edge.current = next;
|
|
69
|
+
setTick((count) => count + 1);
|
|
70
|
+
}, []);
|
|
71
|
+
return useMemo(() => ({ edge, tick, request }), [tick, request]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** A react-native-web host ref, read as the DOM element it is on web. */
|
|
75
|
+
export function hostElement(node: unknown): HTMLElement | null {
|
|
76
|
+
if (!node || typeof node !== 'object') return null;
|
|
77
|
+
const scrollable = (node as { getScrollableNode?: () => unknown }).getScrollableNode?.();
|
|
78
|
+
const element = (scrollable ?? node) as Partial<HTMLElement>;
|
|
79
|
+
return typeof element.querySelector === 'function' &&
|
|
80
|
+
typeof element.addEventListener === 'function'
|
|
81
|
+
? (element as HTMLElement)
|
|
82
|
+
: null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The trigger's own focusable control inside its anchor wrapper. */
|
|
86
|
+
export function triggerControl(anchor: unknown): HTMLElement | null {
|
|
87
|
+
const wrapper = hostElement(anchor);
|
|
88
|
+
return (
|
|
89
|
+
wrapper?.querySelector<HTMLElement>('[aria-haspopup]') ??
|
|
90
|
+
wrapper?.querySelector<HTMLElement>('[tabindex]') ??
|
|
91
|
+
null
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Hand focus back to the trigger when a surface closes with focus inside it.
|
|
97
|
+
*
|
|
98
|
+
* `isInside` says whether an element belongs to the surface. Checked AT the
|
|
99
|
+
* close, when the panel is still mounted for its exit animation, so a row that
|
|
100
|
+
* was just activated still counts. Focus that has already gone somewhere real
|
|
101
|
+
* — a dialog the row opened, a field the pointer clicked — is left alone. The
|
|
102
|
+
* one deferred case is focus left on a node the exit is about to UNMOUNT (the
|
|
103
|
+
* outside-press backdrop): once the exit has run and focus has fallen to
|
|
104
|
+
* `<body>`, it goes back to the trigger too.
|
|
105
|
+
*/
|
|
106
|
+
export function useReturnFocusOnClose(
|
|
107
|
+
anchorRef: React.RefObject<unknown>,
|
|
108
|
+
open: boolean,
|
|
109
|
+
isInside: (element: Element) => boolean,
|
|
110
|
+
): void {
|
|
111
|
+
const wasOpen = useRef(open);
|
|
112
|
+
const isInsideRef = useRef(isInside);
|
|
113
|
+
isInsideRef.current = isInside;
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
const closed = wasOpen.current && !open;
|
|
116
|
+
wasOpen.current = open;
|
|
117
|
+
if (!closed || typeof document === 'undefined') return undefined;
|
|
118
|
+
const active = document.activeElement;
|
|
119
|
+
if (!active || active === document.body || isInsideRef.current(active)) {
|
|
120
|
+
triggerControl(anchorRef.current)?.focus({ preventScroll: true });
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
const timer = setTimeout(() => {
|
|
124
|
+
if (document.activeElement === document.body && !active.isConnected) {
|
|
125
|
+
triggerControl(anchorRef.current)?.focus({ preventScroll: true });
|
|
126
|
+
}
|
|
127
|
+
}, MENU_MOTION_DURATION + 50);
|
|
128
|
+
return () => clearTimeout(timer);
|
|
129
|
+
}, [open, anchorRef]);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Whether an element is one of the menu surfaces — any panel, any depth. */
|
|
133
|
+
export function isInMenuSurface(element: Element): boolean {
|
|
134
|
+
return element.closest(MENU_PANEL_SELECTOR) !== null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The menu trigger's keys, on its anchor wrapper: Enter/Space mark a closed
|
|
139
|
+
* menu's open as a keyboard one (the press itself is the button's own);
|
|
140
|
+
* ArrowDown/ArrowUp open it — or, open already, move focus in — landing on the
|
|
141
|
+
* first/last row. Plus the focus return on close.
|
|
142
|
+
*/
|
|
143
|
+
export function useMenuTriggerKeys(
|
|
144
|
+
anchorRef: React.RefObject<unknown>,
|
|
145
|
+
{
|
|
146
|
+
open,
|
|
147
|
+
setOpen,
|
|
148
|
+
disabled,
|
|
149
|
+
intent,
|
|
150
|
+
}: {
|
|
151
|
+
open: boolean;
|
|
152
|
+
setOpen: (next: boolean) => void;
|
|
153
|
+
disabled?: boolean;
|
|
154
|
+
intent: MenuFocusIntent | undefined;
|
|
155
|
+
},
|
|
156
|
+
): void {
|
|
157
|
+
const edge = intent?.edge;
|
|
158
|
+
const request = intent?.request;
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
const wrapper = hostElement(anchorRef.current);
|
|
161
|
+
if (!wrapper || disabled || !edge || !request) return undefined;
|
|
162
|
+
const onKeyDown = (event: KeyboardEvent) => {
|
|
163
|
+
if (event.defaultPrevented) return;
|
|
164
|
+
if (event.key === 'Enter' || isSpaceKey(event.key)) {
|
|
165
|
+
if (!open) edge.current = 'first';
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;
|
|
169
|
+
event.preventDefault();
|
|
170
|
+
if (!open) setOpen(true);
|
|
171
|
+
request(event.key === 'ArrowDown' ? 'first' : 'last');
|
|
172
|
+
};
|
|
173
|
+
wrapper.addEventListener('keydown', onKeyDown);
|
|
174
|
+
return () => wrapper.removeEventListener('keydown', onKeyDown);
|
|
175
|
+
}, [anchorRef, disabled, open, setOpen, edge, request]);
|
|
176
|
+
|
|
177
|
+
// A pointer open must not inherit a stale keyboard intent from a key that
|
|
178
|
+
// did not open anything (a disabled row, a prevented press).
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
if (!open && edge) edge.current = null;
|
|
181
|
+
}, [open, edge]);
|
|
182
|
+
|
|
183
|
+
useReturnFocusOnClose(anchorRef, open, isInMenuSurface);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** The enabled rows that belong to `panel`, in document order. */
|
|
187
|
+
function menuRows(panel: Element): HTMLElement[] {
|
|
188
|
+
// The owner is the nearest `role="menu"` — the panel itself, or (for a sub
|
|
189
|
+
// panel, whose rows sit in an inner scroller) the panel around it.
|
|
190
|
+
const owner = panel.closest(MENU_PANEL_SELECTOR) ?? panel;
|
|
191
|
+
return rovingItems(owner, MENU_ROW_SELECTOR, { owner: MENU_PANEL_SELECTOR });
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* The keys inside an open menu panel: arrows (wrapping), Home/End, Space, Tab.
|
|
196
|
+
* `intent`, when given, lands focus on the first/last row as the panel opens
|
|
197
|
+
* from the keyboard (a sub-panel focuses its own first row and passes none).
|
|
198
|
+
*/
|
|
199
|
+
export function useMenuPanelKeys(
|
|
200
|
+
panel: HTMLElement | null,
|
|
201
|
+
{ open, onTab, intent }: { open: boolean; onTab: () => void; intent?: MenuFocusIntent },
|
|
202
|
+
): void {
|
|
203
|
+
const onTabRef = useRef(onTab);
|
|
204
|
+
onTabRef.current = onTab;
|
|
205
|
+
|
|
206
|
+
const edge = intent?.edge;
|
|
207
|
+
const tick = intent?.tick;
|
|
208
|
+
useEffect(() => {
|
|
209
|
+
if (!open || !panel || !edge?.current) return;
|
|
210
|
+
const rows = menuRows(panel);
|
|
211
|
+
const target = edge.current === 'last' ? rows[rows.length - 1] : rows[0];
|
|
212
|
+
edge.current = null;
|
|
213
|
+
target?.focus({ preventScroll: true });
|
|
214
|
+
}, [open, panel, edge, tick]);
|
|
215
|
+
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
if (!panel || !open) return undefined;
|
|
218
|
+
const onKeyDown = (event: KeyboardEvent) => {
|
|
219
|
+
if (event.defaultPrevented) return;
|
|
220
|
+
const active =
|
|
221
|
+
typeof document !== 'undefined' ? (document.activeElement as HTMLElement | null) : null;
|
|
222
|
+
const current = active?.closest?.(MENU_ROW_SELECTOR) ?? null;
|
|
223
|
+
if (event.key === 'Tab') {
|
|
224
|
+
event.preventDefault();
|
|
225
|
+
onTabRef.current();
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (isSpaceKey(event.key)) {
|
|
229
|
+
if (!current || current.getAttribute('aria-disabled') === 'true') return;
|
|
230
|
+
event.preventDefault();
|
|
231
|
+
(current as HTMLElement).click();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const move = rovingMove(event.key, { orientation: 'vertical', homeEnd: true });
|
|
235
|
+
if (move === null) return;
|
|
236
|
+
event.preventDefault();
|
|
237
|
+
rovingTarget(menuRows(panel), current, move, true)?.focus();
|
|
238
|
+
};
|
|
239
|
+
panel.addEventListener('keydown', onKeyDown);
|
|
240
|
+
return () => panel.removeEventListener('keydown', onKeyDown);
|
|
241
|
+
}, [panel, open]);
|
|
242
|
+
}
|
|
@@ -51,7 +51,10 @@ import {
|
|
|
51
51
|
MENU_SUB_SIDE_OFFSET,
|
|
52
52
|
ROW_ICON_SIZE,
|
|
53
53
|
} from './constants';
|
|
54
|
+
import { useMenuSurface } from './context';
|
|
55
|
+
import { pushFloatingEscape } from './escape-stack';
|
|
54
56
|
import { FloatingPanel } from './FloatingPanel';
|
|
57
|
+
import { hostElement, MENU_ROW_SELECTOR, useMenuPanelKeys } from './menu-keyboard';
|
|
55
58
|
import { cx, MenuRowChevron, MenuRowShell, splitChildren, SUB_TRIGGER_CLASS } from './shared';
|
|
56
59
|
import type {
|
|
57
60
|
FloatingAnchor,
|
|
@@ -119,8 +122,7 @@ function isHoverPointer(event: Event): boolean {
|
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
/** Every role a menu ROW can carry — the rows a pointer can actually land on. */
|
|
122
|
-
const MENU_ITEM_SELECTOR =
|
|
123
|
-
'[role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="checkbox"], [role="radio"]';
|
|
125
|
+
const MENU_ITEM_SELECTOR = MENU_ROW_SELECTOR;
|
|
124
126
|
|
|
125
127
|
/**
|
|
126
128
|
* Did the pointer leave for another ROW, rather than for the gap this sub's
|
|
@@ -546,22 +548,25 @@ export function createFlyoutMenuSub(prefix: string): MenuSubParts {
|
|
|
546
548
|
};
|
|
547
549
|
}, [node, sub]);
|
|
548
550
|
|
|
549
|
-
// Escape
|
|
550
|
-
// `
|
|
551
|
-
//
|
|
552
|
-
//
|
|
553
|
-
//
|
|
554
|
-
//
|
|
551
|
+
// Escape closes this flyout and leaves the menu open. The flyout's panel is
|
|
552
|
+
// `dismissible={false}` (a press outside it is the parent's business), so it
|
|
553
|
+
// takes its own entry on the escape stack — pushed after the parent's, so it
|
|
554
|
+
// is the one Escape reaches first (`escape-stack.ts`). This used to be a
|
|
555
|
+
// document CAPTURE listener with `stopImmediatePropagation`, which also took
|
|
556
|
+
// Escape away from any field inside the flyout.
|
|
557
|
+
const { open: subOpen, closeAndRefocus } = sub;
|
|
558
|
+
const closeRef = useRef(closeAndRefocus);
|
|
559
|
+
closeRef.current = closeAndRefocus;
|
|
555
560
|
useEffect(() => {
|
|
556
|
-
if (!
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
561
|
+
if (!subOpen || typeof document === 'undefined') return undefined;
|
|
562
|
+
return pushFloatingEscape(() => closeRef.current());
|
|
563
|
+
}, [subOpen]);
|
|
564
|
+
|
|
565
|
+
// Arrows (wrapping), Home/End, Space and Tab among the flyout's own rows —
|
|
566
|
+
// the same keys as the menu it flew out of (`menu-keyboard.ts`). Tab closes
|
|
567
|
+
// the WHOLE menu, not just this flyout: the menu is not in the tab order.
|
|
568
|
+
const surface = useMenuSurface();
|
|
569
|
+
useMenuPanelKeys(hostElement(node), { open: sub.open, onTab: surface.close });
|
|
565
570
|
|
|
566
571
|
// Move focus onto the panel once it has been placed, so Right genuinely
|
|
567
572
|
// ENTERS the submenu rather than only opening it.
|
package/src/floating/types.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import type { GestureResponderEvent, StyleProp, TextStyle, View, ViewStyle } from 'react-native';
|
|
21
21
|
|
|
22
|
+
import type { MenuFocusIntent } from './menu-keyboard';
|
|
22
23
|
import type { WebAriaProps } from '../styles/styled-primitives';
|
|
23
24
|
|
|
24
25
|
/**
|
|
@@ -32,6 +33,11 @@ export interface OverlayShellContextValue {
|
|
|
32
33
|
setOpen: (next: boolean) => void;
|
|
33
34
|
/** The trigger wrapper. Measured by the web forks, unused on native. */
|
|
34
35
|
anchorRef: React.RefObject<View | null>;
|
|
36
|
+
/**
|
|
37
|
+
* Web menus only: where a keyboard open lands focus, handed from the trigger
|
|
38
|
+
* to the panel (`menu-keyboard.ts`). Absent on native and on `Popover`.
|
|
39
|
+
*/
|
|
40
|
+
focusIntent?: MenuFocusIntent;
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
/**
|
|
@@ -129,6 +135,11 @@ export interface FloatingPanelProps extends FloatingPositionProps {
|
|
|
129
135
|
* panel inline (`popover/surface.ts`) and passes it as `style`.
|
|
130
136
|
*/
|
|
131
137
|
surface?: 'popover' | 'menu' | 'listbox';
|
|
138
|
+
/**
|
|
139
|
+
* Receives the panel's own node as it mounts and unmounts — for a family that
|
|
140
|
+
* attaches keyboard handling to the rows inside it (`menu-keyboard.ts`).
|
|
141
|
+
*/
|
|
142
|
+
panelRef?: (node: View | null) => void;
|
|
132
143
|
}
|
|
133
144
|
|
|
134
145
|
/**
|
package/src/fonts/index.web.ts
CHANGED
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
// of the box), so an extensionless specifier here would quietly fall through
|
|
7
|
-
// to the default file.
|
|
8
|
-
//
|
|
9
|
-
// - `./apply-font-faces.web` performs the real `@font-face` injection against
|
|
10
|
-
// the `.woff2` URLs the consuming bundler emits (see `font-urls.web.ts`);
|
|
11
|
-
// the default `./apply-font-faces` is a no-op stub for native.
|
|
12
|
-
// - `./font-assets.web` is an empty map. The native map is built from Metro
|
|
13
|
-
// asset `require()` calls, and importing it from an ES module throws
|
|
14
|
-
// `ReferenceError: require is not defined` during module evaluation — which
|
|
15
|
-
// white-screens the consumer before React mounts. Naming the `.web` file
|
|
16
|
-
// here is what keeps it out of the web graph.
|
|
17
|
-
//
|
|
18
|
-
// Web bundlers select this file via the `"browser"` condition in
|
|
19
|
-
// `package.json`'s `exports['./fonts']`; native bundlers fall through to
|
|
20
|
-
// `./index.ts` via the `"react-native"` condition.
|
|
1
|
+
// AUTO-GENERATED by scripts/generate-platform-exports.mjs — DO NOT EDIT.
|
|
2
|
+
// Source of truth: src/fonts/index.ts.
|
|
3
|
+
// Re-run `bun run generate:exports` (or any `bun run build`) after
|
|
4
|
+
// changing that barrel or the set of web-forked subpaths.
|
|
5
|
+
|
|
21
6
|
export { fontFamilies, fontCssVars } from './tokens';
|
|
22
7
|
export type { FontFamilyName } from './tokens';
|
|
23
8
|
export { applyFontFaces } from './apply-font-faces.web';
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `FrostedIconButton` — WEB: a real HTML `<button>` frosted by a real CSS
|
|
3
|
+
* `backdrop-filter`.
|
|
4
|
+
*
|
|
5
|
+
* The native fork frosts via `expo-blur`'s `BlurView`. Forking the file rather
|
|
6
|
+
* than branching inside one is what keeps that import out of the web graph
|
|
7
|
+
* entirely — `expo-blur` is an optional peer, and a web bundler that resolves
|
|
8
|
+
* it at all is a build a consumer did not ask for.
|
|
9
|
+
*/
|
|
1
10
|
import { useBloomAppearance } from '../appearance';
|
|
2
11
|
import { resolveBloomColors } from '../appearance/colors';
|
|
3
12
|
import React, {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
// no `expo-blur` import ever reaches a web bundler. Web bundlers select this
|
|
7
|
-
// file via the `"browser"` export condition in `package.json`.
|
|
1
|
+
// AUTO-GENERATED by scripts/generate-platform-exports.mjs — DO NOT EDIT.
|
|
2
|
+
// Source of truth: src/frosted-icon-button/index.ts.
|
|
3
|
+
// Re-run `bun run generate:exports` (or any `bun run build`) after
|
|
4
|
+
// changing that barrel or the set of web-forked subpaths.
|
|
5
|
+
|
|
8
6
|
export { FrostedIconButton } from './FrostedIconButton.web';
|
|
9
7
|
export type { FrostedIconButtonProps, FrostedIconButtonSize } from './types';
|