diff --git a/packages/react/react/package.json b/packages/react/react/package.json index a7a65cda..736422e5 100644 --- a/packages/react/react/package.json +++ b/packages/react/react/package.json @@ -31,6 +31,7 @@ ], "license": "Apache-2.0", "dependencies": { + "@floating-ui/react": "^0.27.16", "@vjs-10/core": "workspace:*", "@vjs-10/media": "workspace:*", "@vjs-10/media-store": "workspace:*", @@ -42,8 +43,8 @@ "react": ">=16.8.0" }, "devDependencies": { - "@types/react": "^18.0.0", - "react": "^18.0.0", + "@types/react": "^19.0.0", + "react": "^19.0.0", "tsdown": "^0.15.4", "typescript": "^5.9.2" }, diff --git a/packages/react/react/src/components/Popover.tsx b/packages/react/react/src/components/Popover.tsx new file mode 100644 index 00000000..4617b875 --- /dev/null +++ b/packages/react/react/src/components/Popover.tsx @@ -0,0 +1,158 @@ +import type { Placement } from '@floating-ui/react'; +import type { ReactNode } from 'react'; + +import React, { createContext, useContext, useState } from 'react'; + +import { + autoUpdate, + flip, + offset, + shift, + useDismiss, + useFloating, + useFocus, + useHover, + useInteractions, + useRole, +} from '@floating-ui/react'; + +interface PopoverContextType { + open: boolean; + setOpen: (open: boolean) => void; + refs: ReturnType['refs']; + floatingStyles: ReturnType['floatingStyles']; + getReferenceProps: ReturnType['getReferenceProps']; + getFloatingProps: ReturnType['getFloatingProps']; + context: ReturnType['context']; + updatePositioning: (placement: Placement, sideOffset: number) => void; +} + +interface PopoverRootProps { + openOnHover?: boolean; + delay?: number; + closeDelay?: number; + children: ReactNode; +} + +interface PopoverTriggerProps { + children: ReactNode; +} + +interface PopoverPositionerProps { + side?: Placement; + sideOffset?: number; + children: ReactNode; +} + +interface PopoverPopupProps { + className?: string; + children: ReactNode; +} + +const PopoverContext = createContext(null); + +function usePopoverContext(): PopoverContextType { + const context = useContext(PopoverContext); + if (!context) { + throw new Error('Popover components must be used within PopoverRoot'); + } + return context; +} + +function PopoverRoot({ openOnHover = false, delay = 0, closeDelay = 0, children }: PopoverRootProps): JSX.Element { + const [open, setOpen] = useState(false); + const [placement, setPlacement] = useState('top'); + const [sideOffset, setSideOffset] = useState(5); + + const { refs, floatingStyles, context } = useFloating({ + open, + onOpenChange: setOpen, + placement, + middleware: [offset(sideOffset), flip(), shift()], + whileElementsMounted: autoUpdate, + }); + + const hover = useHover(context, { + enabled: openOnHover, + delay: { + open: delay, + close: closeDelay, + }, + }); + const focus = useFocus(context); + const dismiss = useDismiss(context); + const role = useRole(context); + + const { getReferenceProps, getFloatingProps } = useInteractions([hover, focus, dismiss, role]); + + const updatePositioning = (newPlacement: Placement, newSideOffset: number) => { + setPlacement(newPlacement); + setSideOffset(newSideOffset); + }; + + const value: PopoverContextType = { + open, + setOpen, + refs, + floatingStyles, + getReferenceProps, + getFloatingProps, + context, + updatePositioning, + }; + + return {children}; +} + +function PopoverTrigger({ children }: PopoverTriggerProps): JSX.Element { + const { refs, getReferenceProps } = usePopoverContext(); + + return React.cloneElement(React.Children.only(children) as JSX.Element, { + ref: refs.setReference, + ...getReferenceProps(), + }); +} + +function PopoverPositioner({ side = 'top', sideOffset = 5, children }: PopoverPositionerProps): JSX.Element | null { + const { open, refs, floatingStyles, updatePositioning } = usePopoverContext(); + + // Update positioning when props change + React.useEffect(() => { + updatePositioning(side, sideOffset); + }, [side, sideOffset, updatePositioning]); + + if (!open) { + return null; + } + + return ( +
+ {children} +
+ ); +} + +function PopoverPopup({ className, children }: PopoverPopupProps): JSX.Element { + const { getFloatingProps } = usePopoverContext(); + + return ( +
+ {children} +
+ ); +} + +// Export compound component +export const Popover: { + Root: typeof PopoverRoot; + Trigger: typeof PopoverTrigger; + Positioner: typeof PopoverPositioner; + Popup: typeof PopoverPopup; +} = { + Root: PopoverRoot, + Trigger: PopoverTrigger, + Positioner: PopoverPositioner, + Popup: PopoverPopup, +}; + +export default Popover; diff --git a/packages/react/react/src/components/TimeRange.tsx b/packages/react/react/src/components/TimeRange.tsx index ba499239..77c9b2fa 100644 --- a/packages/react/react/src/components/TimeRange.tsx +++ b/packages/react/react/src/components/TimeRange.tsx @@ -54,6 +54,7 @@ export const useTimeRangeRootProps = (props: TimeRange.Props, state: TimeRange.S return { ref: useCallback((el: HTMLDivElement) => { + if (!el) return; state.core?.attach(el); }, []), id, diff --git a/packages/react/react/src/components/VolumeRange.tsx b/packages/react/react/src/components/VolumeRange.tsx index 1f7584da..08adc23f 100644 --- a/packages/react/react/src/components/VolumeRange.tsx +++ b/packages/react/react/src/components/VolumeRange.tsx @@ -58,6 +58,7 @@ export const useVolumeRangeRootProps = (props: VolumeRange.Props, state: VolumeR return { ref: useCallback((el: HTMLDivElement) => { + if (!el) return; state.core?.attach(el); }, []), id, diff --git a/packages/react/react/src/index.ts b/packages/react/react/src/index.ts index e84d5f34..17a85139 100644 --- a/packages/react/react/src/index.ts +++ b/packages/react/react/src/index.ts @@ -9,3 +9,4 @@ export { VolumeRange } from './components/VolumeRange'; export { FullscreenButton } from './components/FullscreenButton'; export { DurationDisplay } from './components/DurationDisplay'; export { CurrentTimeDisplay } from './components/CurrentTimeDisplay'; +export { Popover } from './components/Popover'; diff --git a/packages/react/react/src/skins/default/MediaSkinDefault.tsx b/packages/react/react/src/skins/default/MediaSkinDefault.tsx index 84303c4d..4e48c0ce 100644 --- a/packages/react/react/src/skins/default/MediaSkinDefault.tsx +++ b/packages/react/react/src/skins/default/MediaSkinDefault.tsx @@ -15,6 +15,7 @@ import { DurationDisplay } from '../../components/DurationDisplay'; import { FullscreenButton } from '../../components/FullscreenButton'; import { MediaContainer } from '../../components/MediaContainer'; import MuteButton from '../../components/MuteButton'; +import { Popover } from '../../components/Popover'; import PlayButton from '../../components/PlayButton'; import { TimeRange } from '../../components/TimeRange'; import { VolumeRange } from '../../components/VolumeRange'; @@ -56,18 +57,25 @@ export default function MediaSkinDefault({ children, className = '' }: SkinProps - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/packages/react/react/src/skins/default/styles.ts b/packages/react/react/src/skins/default/styles.ts index de2cdc0d..0450a52e 100644 --- a/packages/react/react/src/skins/default/styles.ts +++ b/packages/react/react/src/skins/default/styles.ts @@ -26,6 +26,7 @@ export interface MediaDefaultSkinStyles { readonly TimeRangeProgress: string; readonly TimeRangePointer: string; readonly TimeRangeThumb: string; + readonly VolumePopup: string; readonly VolumeRangeRoot: string; readonly VolumeRangeTrack: string; readonly VolumeRangeProgress: string; @@ -139,6 +140,17 @@ const styles: MediaDefaultSkinStyles = { 'group-hover/slider:opacity-100 group-focus-within/slider:opacity-100', 'size-2.5 active:size-3 group-active/slider:size-3' ), + VolumePopup: cn( + 'relative z-30 px-2 py-4 rounded-2xl', + 'bg-white/10 backdrop-blur-3xl backdrop-saturate-150 backdrop-brightness-90', + 'ring ring-white/10 ring-inset shadow-sm shadow-black/15', + // Border to enhance contrast on lighter videos + 'after:absolute after:inset-0 after:ring after:rounded-[inherit] after:ring-black/15 after:pointer-events-none after:z-10', + // Reduced transparency for users with preference + 'reduced-transparency:bg-black/70 reduced-transparency:ring-black reduced-transparency:after:ring-white/20', + // High contrast mode + 'contrast-more:bg-black/90 contrast-more:ring-black contrast-more:after:ring-white/20' + ), VolumeRangeRoot: cn('flex [&[data-orientation="horizontal"]]:w-20 [&[data-orientation="horizontal"]]:h-5 [&[data-orientation="vertical"]]:w-5 [&[data-orientation="vertical"]]:h-20 items-center justify-center group/slider relative'), VolumeRangeTrack: cn('[&[data-orientation="horizontal"]]:h-1 [&[data-orientation="vertical"]]:w-1 w-full relative select-none rounded-full bg-white/20 ring-1 ring-black/5'), VolumeRangeProgress: cn('bg-white rounded-[inherit]'), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad397855..308b3773 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -298,6 +298,9 @@ importers: packages/react/react: dependencies: + '@floating-ui/react': + specifier: ^0.27.16 + version: 0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@vjs-10/core': specifier: workspace:* version: link:../../core/core @@ -318,11 +321,11 @@ importers: version: link:../react-media-store devDependencies: '@types/react': - specifier: ^18.0.0 - version: 18.3.24 + specifier: ^19.0.0 + version: 19.1.13 react: - specifier: ^18.0.0 - version: 18.3.1 + specifier: ^19.0.0 + version: 19.1.1 tsdown: specifier: ^0.15.4 version: 0.15.4(typescript@5.9.2) @@ -825,6 +828,27 @@ packages: resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/react-dom@2.1.6': + resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/react@0.27.16': + resolution: {integrity: sha512-9O8N4SeG2z++TSM8QA/KTeKFBVCNEz/AGS7gWPJf6KFRzmRWixFRnCnkPHRDwSVZW6QPDO6uT0P2SpWNKCc9/g==} + peerDependencies: + react: '>=17.0.0' + react-dom: '>=17.0.0' + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -897,8 +921,8 @@ packages: '@open-wc/context-protocol@0.0.9': resolution: {integrity: sha512-3mMJ16BbRqFaZNR7ongBJEEvAjZFBpo5qUtc2dk/rlk3k09AVRp2Dcldu5VTB0r/tsWdfExbRLlCw/8f3cD/kQ==} - '@oxc-project/types@0.92.0': - resolution: {integrity: sha512-PDLfCbwgXjGdTBxzcuDOUxJYNBl6P8dOp3eDKWw54dYvqONan9rwGDRQU0zrkdEMiItfXQQUOI17uOcMX5Zm7A==} + '@oxc-project/types@0.93.0': + resolution: {integrity: sha512-yNtwmWZIBtJsMr5TEfoZFDxIWV6OdScOpza/f5YxbqUMJk+j6QX3Cf3jgZShGEFYWQJ5j9mJ6jM0tZHu2J9Yrg==} '@pkgr/core@0.1.2': resolution: {integrity: sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==} @@ -916,89 +940,89 @@ packages: '@quansync/fs@0.1.5': resolution: {integrity: sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA==} - '@rolldown/binding-android-arm64@1.0.0-beta.40': - resolution: {integrity: sha512-9Ii9phC7QU6Lb+ncMfG1Xlosq0NBB1N/4sw+EGZ3y0BBWGy02TOb5ghWZalphAKv9rn1goqo5WkBjyd2YvsLmA==} + '@rolldown/binding-android-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-Edflndd9lU7JVhVIvJlZhdCj5DkhYDJPIRn4Dx0RUdfc8asP9xHOI5gMd8MesDDx+BJpdIT/uAmVTearteU/mQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-beta.40': - resolution: {integrity: sha512-5O6d0y2tBQTL+ecQY3qXIwSnF1/Zik8q7LZMKeyF+VJ9l194d0IdMhl2zUF0cqWbYHuF4Pnxplk4OhurPQ/Z9Q==} + '@rolldown/binding-darwin-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-XGCzqfjdk7550PlyZRTBKbypXrB7ATtXhw/+bjtxnklLQs0mKP/XkQVOKyn9qGKSlvH8I56JLYryVxl0PCvSNw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-beta.40': - resolution: {integrity: sha512-izB9jygt3miPQbOTZfSu5K51isUplqa8ysByOKQqcJHgrBWmbTU8TM9eouv6tRmBR0kjcEcID9xhmA1CeZ1VIg==} + '@rolldown/binding-darwin-x64@1.0.0-beta.41': + resolution: {integrity: sha512-Ho6lIwGJed98zub7n0xcRKuEtnZgbxevAmO4x3zn3C3N4GVXZD5xvCvTVxSMoeBJwTcIYzkVDRTIhylQNsTgLQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-beta.40': - resolution: {integrity: sha512-2fdpEpKT+wwP0vig9dqxu+toTeWmVSjo3psJQVDeLJ51rO+GXcCJ1IkCXjhMKVEevNtZS7B8T8Z2vvmRV9MAdA==} + '@rolldown/binding-freebsd-x64@1.0.0-beta.41': + resolution: {integrity: sha512-ijAZETywvL+gACjbT4zBnCp5ez1JhTRs6OxRN4J+D6AzDRbU2zb01Esl51RP5/8ZOlvB37xxsRQ3X4YRVyYb3g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.40': - resolution: {integrity: sha512-HP2lo78OWULN+8TewpLbS9PS00jh0CaF04tA2u8z2I+6QgVgrYOYKvX+T0hlO5smgso4+qb3YchzumWJl3yCPQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': + resolution: {integrity: sha512-EgIOZt7UildXKFEFvaiLNBXm+4ggQyGe3E5Z1QP9uRcJJs9omihOnm897FwOBQdCuMvI49iBgjFrkhH+wMJ2MA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.40': - resolution: {integrity: sha512-ng00gfr9BhA2NPAOU5RWAlTiL+JcwAD+L+4yUD1sbBy6tgHdLiNBOvKtHISIF9RM9/eQeS0tAiWOYZGIH9JMew==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': + resolution: {integrity: sha512-F8bUwJq8v/JAU8HSwgF4dztoqJ+FjdyjuvX4//3+Fbe2we9UktFeZ27U4lRMXF1vxWtdV4ey6oCSqI7yUrSEeg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.40': - resolution: {integrity: sha512-mF0R1l9kLcaag/9cLEiYYdNZ4v1uuX4jklSDZ1s6vJE4RB3LirUney0FavdVRwCJ5sDvfvsPgXgtBXWYr2M2tQ==} + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': + resolution: {integrity: sha512-MioXcCIX/wB1pBnBoJx8q4OGucUAfC1+/X1ilKFsjDK05VwbLZGRgOVD5OJJpUQPK86DhQciNBrfOKDiatxNmg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.40': - resolution: {integrity: sha512-+wi08S7wT5iLPHRZb0USrS6n+T6m+yY++dePYedE5uvKIpWCJJioFTaRtWjpm0V6dVNLcq2OukrvfdlGtH9Wgg==} + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': + resolution: {integrity: sha512-m66M61fizvRCwt5pOEiZQMiwBL9/y0bwU/+Kc4Ce/Pef6YfoEkR28y+DzN9rMdjo8Z28NXjsDPq9nH4mXnAP0g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-beta.40': - resolution: {integrity: sha512-W5qBGAemUocIBKCcOsDjlV9GUt28qhl/+M6etWBeLS5gQK0J6XDg0YVzfOQdvq57ZGjYNP0NvhYzqhOOnEx+4g==} + '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': + resolution: {integrity: sha512-yRxlSfBvWnnfrdtJfvi9lg8xfG5mPuyoSHm0X01oiE8ArmLRvoJGHUTJydCYz+wbK2esbq5J4B4Tq9WAsOlP1Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-beta.40': - resolution: {integrity: sha512-vJwoDehtt+yqj2zacq1AqNc2uE/oh7mnRGqAUbuldV6pgvU01OSQUJ7Zu+35hTopnjFoDNN6mIezkYlGAv5RFA==} + '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-PHVxYhBpi8UViS3/hcvQQb9RFqCtvFmFU1PvUoTRiUdBtgHA6fONNHU4x796lgzNlVSD3DO/MZNk1s5/ozSMQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-beta.40': - resolution: {integrity: sha512-Oj3YyqVUPurr1FlMpEE/bJmMC+VWAWPM/SGUfklO5KUX97bk5Q/733nPg4RykK8q8/TluJoQYvRc05vL/B74dw==} + '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': + resolution: {integrity: sha512-OAfcO37ME6GGWmj9qTaDT7jY4rM0T2z0/8ujdQIJQ2x2nl+ztO32EIwURfmXOK0U1tzkyuaKYvE34Pug/ucXlQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.40': - resolution: {integrity: sha512-0ZtO6yN8XjVoFfN4HDWQj4nDu3ndMybr7jIM00DJqOmc+yFhly7rdOy7fNR9Sky3leCpBtsXfepVqRmVpYKPVA==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-NIYGuCcuXaq5BC4Q3upbiMBvmZsTsEPG9k/8QKQdmrch+ocSy5Jv9tdpdmXJyighKqm182nh/zBt+tSJkYoNlg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.40': - resolution: {integrity: sha512-BPl1inoJXPpIe38Ja46E4y11vXlJyuleo+9Rmu//pYL5fIDYJkXUj/oAXqjSuwLcssrcwnuPgzvzvlz9++cr3w==} + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-kANdsDbE5FkEOb5NrCGBJBCaZ2Sabp3D7d4PRqMYJqyLljwh9mDyYyYSv5+QNvdAmifj+f3lviNEUUuUZPEFPw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.40': - resolution: {integrity: sha512-UguA4ltbAk+nbwHRxqaUP/etpTbR0HjyNlsu4Zjbh/ytNbFsbw8CA4tEBkwDyjgI5NIPea6xY11zpl7R2/ddVA==} + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-UlpxKmFdik0Y2VjZrgUCgoYArZJiZllXgIipdBRV1hw6uK45UbQabSTW6Kp6enuOu7vouYWftwhuxfpE8J2JAg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1006,8 +1030,8 @@ packages: '@rolldown/pluginutils@1.0.0-beta.35': resolution: {integrity: sha512-slYrCpoxJUqzFDDNlvrOYRazQUNRvWPjXA17dAOISY3rDMxX6k8K4cj2H+hEYMHF81HO3uNd5rHVigAWRM5dSg==} - '@rolldown/pluginutils@1.0.0-beta.40': - resolution: {integrity: sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==} + '@rolldown/pluginutils@1.0.0-beta.41': + resolution: {integrity: sha512-ycMEPrS3StOIeb87BT3/+bu+blEtyvwQ4zmo2IcJQy0Rd1DAAhKksA0iUZ3MYSpJtjlPhg0Eo6mvVS6ggPhRbw==} '@rollup/rollup-android-arm-eabi@4.52.0': resolution: {integrity: sha512-VxDYCDqOaR7NXzAtvRx7G1u54d2kEHopb28YH/pKzY6y0qmogP3gG7CSiWsq9WvDFxOQMpNEyjVAHZFXfH3o/A==} @@ -1497,6 +1521,10 @@ packages: resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} engines: {node: '>=14'} + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + are-docs-informative@0.0.2: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} engines: {node: '>=14'} @@ -3214,8 +3242,8 @@ packages: vue-tsc: optional: true - rolldown@1.0.0-beta.40: - resolution: {integrity: sha512-VqEHbKpOgTPmQrZ4fVn4eshDQS/6g/fRpNE7cFSJY+eQLDZn4B9X61J6L+hnlt1u2uRI+pF7r1USs6S5fuWCvw==} + rolldown@1.0.0-beta.41: + resolution: {integrity: sha512-U+NPR0Bkg3wm61dteD2L4nAM1U9dtaqVrpDXwC36IKRHpEO/Ubpid4Nijpa2imPchcVNHfxVFwSSMJdwdGFUbg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -3400,6 +3428,9 @@ packages: resolution: {integrity: sha512-JJoOEKTfL1urb1mDoEblhD9NhEbWmq9jHEMEnxoC4ujUaZ4itA8vKgwkFAyNClgxplLi9tsUKX+EduK0p/l7sg==} engines: {node: ^14.18.0 || >=16.0.0} + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tailwindcss@4.1.13: resolution: {integrity: sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==} @@ -4142,6 +4173,31 @@ snapshots: '@eslint/core': 0.15.2 levn: 0.4.1 + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/react-dom@2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/dom': 1.7.4 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + '@floating-ui/react@0.27.16(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@floating-ui/utils': 0.2.10 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + tabbable: 6.2.0 + + '@floating-ui/utils@0.2.10': {} + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -4210,7 +4266,7 @@ snapshots: '@open-wc/context-protocol@0.0.9': {} - '@oxc-project/types@0.92.0': {} + '@oxc-project/types@0.93.0': {} '@pkgr/core@0.1.2': {} @@ -4225,53 +4281,53 @@ snapshots: dependencies: quansync: 0.2.11 - '@rolldown/binding-android-arm64@1.0.0-beta.40': + '@rolldown/binding-android-arm64@1.0.0-beta.41': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-beta.40': + '@rolldown/binding-darwin-arm64@1.0.0-beta.41': optional: true - '@rolldown/binding-darwin-x64@1.0.0-beta.40': + '@rolldown/binding-darwin-x64@1.0.0-beta.41': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-beta.40': + '@rolldown/binding-freebsd-x64@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.40': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.40': + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.40': + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.40': + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-beta.40': + '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-beta.40': + '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-beta.40': + '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': dependencies: '@napi-rs/wasm-runtime': 1.0.5 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.40': + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': optional: true - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.40': + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.40': + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': optional: true '@rolldown/pluginutils@1.0.0-beta.35': {} - '@rolldown/pluginutils@1.0.0-beta.40': {} + '@rolldown/pluginutils@1.0.0-beta.41': {} '@rollup/rollup-android-arm-eabi@4.52.0': optional: true @@ -4762,6 +4818,8 @@ snapshots: ansis@4.1.0: {} + ansis@4.2.0: {} + are-docs-informative@0.0.2: {} argparse@2.0.1: {} @@ -6843,7 +6901,7 @@ snapshots: rfdc@1.4.1: {} - rolldown-plugin-dts@0.16.7(rolldown@1.0.0-beta.40)(typescript@5.9.2): + rolldown-plugin-dts@0.16.7(rolldown@1.0.0-beta.41)(typescript@5.9.2): dependencies: '@babel/generator': 7.28.3 '@babel/parser': 7.28.4 @@ -6854,33 +6912,33 @@ snapshots: dts-resolver: 2.1.2 get-tsconfig: 4.10.1 magic-string: 0.30.19 - rolldown: 1.0.0-beta.40 + rolldown: 1.0.0-beta.41 optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - oxc-resolver - supports-color - rolldown@1.0.0-beta.40: + rolldown@1.0.0-beta.41: dependencies: - '@oxc-project/types': 0.92.0 - '@rolldown/pluginutils': 1.0.0-beta.40 - ansis: 4.1.0 + '@oxc-project/types': 0.93.0 + '@rolldown/pluginutils': 1.0.0-beta.41 + ansis: 4.2.0 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.40 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.40 - '@rolldown/binding-darwin-x64': 1.0.0-beta.40 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.40 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.40 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.40 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.40 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.40 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.40 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.40 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.40 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.40 - '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.40 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.40 + '@rolldown/binding-android-arm64': 1.0.0-beta.41 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.41 + '@rolldown/binding-darwin-x64': 1.0.0-beta.41 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.41 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.41 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.41 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.41 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.41 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.41 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.41 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.41 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.41 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.41 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.41 rollup@4.52.0: dependencies: @@ -7133,6 +7191,8 @@ snapshots: '@pkgr/core': 0.1.2 tslib: 2.8.1 + tabbable@6.2.0: {} + tailwindcss@4.1.13: {} tapable@2.2.3: {} @@ -7183,8 +7243,8 @@ snapshots: diff: 8.0.2 empathic: 2.0.0 hookable: 5.5.3 - rolldown: 1.0.0-beta.40 - rolldown-plugin-dts: 0.16.7(rolldown@1.0.0-beta.40)(typescript@5.9.2) + rolldown: 1.0.0-beta.41 + rolldown-plugin-dts: 0.16.7(rolldown@1.0.0-beta.41)(typescript@5.9.2) semver: 7.7.2 tinyexec: 1.0.1 tinyglobby: 0.2.15