diff --git a/package.json b/package.json index 88aa4b9a..f5abe3cf 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@loomhq/loom-embed": "1.5.0", "@markdoc/markdoc": "0.4.0", "@monaco-editor/react": "4.6.0", + "@radix-ui/react-accordion": "^1.2.0", "@react-aria/utils": "3.23.0", "@react-hooks-library/core": "0.6.0", "@react-spring/web": "9.7.3", diff --git a/src/components/Accordion.tsx b/src/components/Accordion.tsx index 76463c4a..e346dd4a 100644 --- a/src/components/Accordion.tsx +++ b/src/components/Accordion.tsx @@ -1,266 +1,222 @@ +import * as RadixAccordion from '@radix-ui/react-accordion' import { type ComponentProps, - type HTMLAttributes, type ReactElement, type ReactNode, + type Ref, + createContext, + forwardRef, useCallback, - useEffect, + useContext, useMemo, - useRef, useState, } from 'react' -import React from 'react' -import { useSpring } from '@react-spring/web' -import styled, { useTheme } from 'styled-components' -import useResizeObserver from '../hooks/useResizeObserver' -import { type UseDisclosureProps, useDisclosure } from '../hooks/useDisclosure' +import styled, { css, keyframes } from 'styled-components' + import { DropdownArrowIcon } from '../icons' import Card from './Card' -import { AnimatedDiv } from './AnimatedDiv' - -const paddingTransition = '0.2s ease' -function AccordionTriggerUnstyled({ - children, - isOpen: _isOpen, - unstyled: _unstyled, - ...props -}: { isOpen?: boolean; unstyled?: boolean } & ComponentProps<'div'>) { - return ( -
-
{children}
-
- -
-
- ) +export type AccordionProps = ComponentProps +type AccordionContextT = { + type: AccordionProps['type'] + openItems: AccordionProps['value'] + setOpenItems: (openItems: AccordionProps['value']) => void } -const AccordionTrigger = styled(AccordionTriggerUnstyled)(({ theme }) => { - const focusInset = theme.spacing.xsmall - const padding = theme.spacing.medium - - return { - display: 'flex', - gap: theme.spacing.medium, - padding, - ...theme.partials.text.body2Bold, - color: theme.colors.text, - '.label': { - flexGrow: 1, - }, - '.icon > *:first-child': { - transform: 'scale(100%)', - transition: 'transform 0.4 ease', - }, - '&:focus-visible': { - outline: 'none', - position: 'relative', - '&::after': { - ...theme.partials.focus.insetAbsolute, - borderRadius: theme.borderRadiuses.medium, - top: focusInset, - bottom: focusInset, - left: focusInset, - right: focusInset, - }, - }, - '&:hover': { - '.icon > *:first-child': { - transform: 'scale(115%)', - }, - }, - '.icon': { - display: 'flex', - alignItems: 'center', - position: 'relative', - marginLeft: theme.spacing.xsmall, - transformOrigin: '50% 50%', - transform: 'scaleY(100%)', - transition: 'transform 0.2s ease', - }, - '&[aria-expanded="true"] .icon': { - transform: 'scaleY(-100%)', - }, - } -}) - -function AccordionContentUnstyled({ - isOpen, - className, - children, - pad: _pad, - unstyled: _unstyled, - ...props -}: { - isOpen?: boolean - pad?: boolean - unstyled?: boolean -} & HTMLAttributes) { - const eltRef = useRef(null) - const [contentHeight, setContentHeight] = useState(0) - const onResize = useCallback(() => { - if (eltRef.current?.offsetHeight) { - setContentHeight(eltRef.current?.offsetHeight) - } - }, []) - const theme = useTheme() - - useEffect(() => { - onResize() - }, [onResize]) +const AccordionContext = createContext(undefined) +const useAccordionContext = () => { + const ctx = useContext(AccordionContext) - useResizeObserver(eltRef, onResize) - const springs = useSpring({ - to: { height: isOpen ? contentHeight || 'auto' : 0 }, - config: isOpen - ? { - clamp: true, - mass: 0.6, - tension: 280, - velocity: 0.02, - } - : { - clamp: true, - mass: 0.6, - tension: 400, - velocity: 0.02, - }, - }) - const mOffset = theme.spacing.medium - theme.spacing.small + if (!ctx) throw Error('AccordionContext must be used inside an ') - return ( - -
- {children} -
-
- ) + return ctx } -const AccordionContent = styled(AccordionContentUnstyled)( - ({ theme, pad, unstyled }) => - unstyled - ? {} - : { - transition: `marginTop ${paddingTransition}`, - ...(pad - ? { - paddingLeft: theme.spacing.medium, - paddingRight: theme.spacing.medium, - paddingBottom: theme.spacing.medium, - } - : {}), - } -) -type AccordionPropsBase = { - textValue?: string - padContent?: boolean - unstyled?: boolean - children?: ReactNode | ((props: { isOpen: boolean }) => ReactNode) -} & UseDisclosureProps +export function useIsItemOpen(itemValue: string) { + const { openItems } = useAccordionContext() -type AccordionPropsWithTrigger = AccordionPropsBase & { - triggerButton: ReactElement - label?: never -} + if (!openItems) return false -type AccordionPropsWithLabel = AccordionPropsBase & { - label: ReactNode - triggerButton?: never + return typeof openItems === 'string' + ? openItems === itemValue + : (openItems as string[]).includes(itemValue) } -export type AccordionProps = AccordionPropsWithTrigger | AccordionPropsWithLabel - -export default function Accordion({ - textValue, - label, - triggerButton, - padContent = true, - unstyled = false, - children, - isOpen: isOpenProp, - onOpenChange, - defaultOpen, - id, - ...props -}: AccordionProps) { - if (!textValue && typeof label === 'string') { - textValue = label - } - - const { triggerProps, contentProps, isOpen } = useDisclosure({ - defaultOpen, - isOpen: isOpenProp, - onOpenChange, - id, - }) +export function useCloseItem(itemValue: string) { + const { openItems, setOpenItems } = useAccordionContext() - useEffect(() => {}, [isOpen]) + return useCallback(() => { + if (typeof openItems === 'string' && openItems === itemValue) { + setOpenItems('') + } else { + setOpenItems((openItems as string[]).filter((v) => v !== itemValue)) + } + }, [itemValue, openItems, setOpenItems]) +} - const kids = useMemo( - () => - typeof children === 'function' - ? children({ isOpen: !!isOpen }) - : children, - [children, isOpen] +function AccordionRef( + { + children, + onValueChange: valueChangePropFunc, + ...props + }: { + children?: + | ReactElement + | ReactElement[] + collapsible?: boolean + } & AccordionProps, + ref: Ref +) { + const [openItems, setOpenItems] = useState( + props.value ) - const Wrapper = useMemo(() => { - if (unstyled) { - return function Div(props: ComponentProps<'div'>) { - return
- } - } - - return Card - }, [unstyled]) - const finalTriggerProps = { - isOpen, - ...triggerProps, - } + // for both keeping track of current open items, and still allowing user-specified function + const onValueChange = useCallback( + (val: AccordionProps['value']) => { + setOpenItems(val) + valueChangePropFunc?.(val as string & string[]) + }, + [valueChangePropFunc] + ) - const trigger = triggerButton ? ( - React.cloneElement(triggerButton, finalTriggerProps) - ) : ( - - {label} - + const context = useMemo( + () => ({ + type: props.type, + openItems, + setOpenItems, + }), + [openItems, props.type] ) return ( - - {trigger} - + - {kids} - - + {children} + + + ) +} + +export const Accordion = forwardRef(AccordionRef) +function AccordionItemRef( + { + hideDefaultIcon = false, + trigger, + children, + ...props + }: { + hideDefaultIcon?: boolean + trigger: ReactNode + children: ReactNode + } & ComponentProps, + ref: Ref +) { + return ( + + + + {trigger} + {!hideDefaultIcon && ( + + )} + + + {children} + ) } +export const AccordionItem = forwardRef(AccordionItemRef) + +const ItemSC: typeof RadixAccordion.Item = styled(RadixAccordion.Item)((_) => ({ + display: 'flex', + height: '100%', + width: '100%', + '&[data-orientation="vertical"]': { + flexDirection: 'column', + }, + '&[data-orientation="horizontal"]': { + flexDirection: 'row', + }, +})) +const TriggerSC = styled(RadixAccordion.Trigger)(({ theme }) => ({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + cursor: 'pointer', + ...theme.partials.text.body2Bold, + color: theme.colors.text, + // reset default button styles + background: 'transparent', + border: 'none', + padding: 0, + '.icon': { + transform: 'scaleY(100%)', + transition: 'transform 0.3s ease', + }, + '&:hover': { + '.icon': { + transform: 'scale(115%)', + }, + }, + '&[data-state="open"] .icon': { + transform: 'scaleY(-100%)', + }, +})) + +const slideAnimation = ( + direction: 'in' | 'out', + orientation: 'height' | 'width' +) => keyframes` + from { + ${orientation}: ${ + direction === 'out' + ? '0' + : `var(--radix-accordion-content-${orientation})` + }; + } + to { + ${orientation}: ${ + direction === 'out' + ? `var(--radix-accordion-content-${orientation})` + : '0' + }; + } +` +const ContentSC = styled(RadixAccordion.Content)` + overflow: hidden; + &[data-state='open'][data-orientation='vertical'] { + animation: ${css` + ${slideAnimation('out', 'height')}`} 300ms ease-out; + } + &[data-state='closed'][data-orientation='vertical'] { + animation: ${css` + ${slideAnimation('in', 'height')}`} 300ms ease-out; + } + &[data-state='open'][data-orientation='horizontal'] { + animation: ${css` + ${slideAnimation('out', 'width')}`} 300ms ease-out; + } + &[data-state='closed'][data-orientation='horizontal'] { + animation: ${css` + ${slideAnimation('in', 'width')}`} 300ms ease-out; + } +` + +export default Accordion diff --git a/src/components/AccordionOLD.tsx b/src/components/AccordionOLD.tsx new file mode 100644 index 00000000..76463c4a --- /dev/null +++ b/src/components/AccordionOLD.tsx @@ -0,0 +1,266 @@ +import { + type ComponentProps, + type HTMLAttributes, + type ReactElement, + type ReactNode, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react' +import React from 'react' +import { useSpring } from '@react-spring/web' +import styled, { useTheme } from 'styled-components' + +import useResizeObserver from '../hooks/useResizeObserver' +import { type UseDisclosureProps, useDisclosure } from '../hooks/useDisclosure' +import { DropdownArrowIcon } from '../icons' + +import Card from './Card' +import { AnimatedDiv } from './AnimatedDiv' + +const paddingTransition = '0.2s ease' + +function AccordionTriggerUnstyled({ + children, + isOpen: _isOpen, + unstyled: _unstyled, + ...props +}: { isOpen?: boolean; unstyled?: boolean } & ComponentProps<'div'>) { + return ( +
+
{children}
+
+ +
+
+ ) +} + +const AccordionTrigger = styled(AccordionTriggerUnstyled)(({ theme }) => { + const focusInset = theme.spacing.xsmall + const padding = theme.spacing.medium + + return { + display: 'flex', + gap: theme.spacing.medium, + padding, + ...theme.partials.text.body2Bold, + color: theme.colors.text, + '.label': { + flexGrow: 1, + }, + '.icon > *:first-child': { + transform: 'scale(100%)', + transition: 'transform 0.4 ease', + }, + '&:focus-visible': { + outline: 'none', + position: 'relative', + '&::after': { + ...theme.partials.focus.insetAbsolute, + borderRadius: theme.borderRadiuses.medium, + top: focusInset, + bottom: focusInset, + left: focusInset, + right: focusInset, + }, + }, + '&:hover': { + '.icon > *:first-child': { + transform: 'scale(115%)', + }, + }, + '.icon': { + display: 'flex', + alignItems: 'center', + position: 'relative', + marginLeft: theme.spacing.xsmall, + transformOrigin: '50% 50%', + transform: 'scaleY(100%)', + transition: 'transform 0.2s ease', + }, + '&[aria-expanded="true"] .icon': { + transform: 'scaleY(-100%)', + }, + } +}) + +function AccordionContentUnstyled({ + isOpen, + className, + children, + pad: _pad, + unstyled: _unstyled, + ...props +}: { + isOpen?: boolean + pad?: boolean + unstyled?: boolean +} & HTMLAttributes) { + const eltRef = useRef(null) + const [contentHeight, setContentHeight] = useState(0) + const onResize = useCallback(() => { + if (eltRef.current?.offsetHeight) { + setContentHeight(eltRef.current?.offsetHeight) + } + }, []) + const theme = useTheme() + + useEffect(() => { + onResize() + }, [onResize]) + + useResizeObserver(eltRef, onResize) + const springs = useSpring({ + to: { height: isOpen ? contentHeight || 'auto' : 0 }, + config: isOpen + ? { + clamp: true, + mass: 0.6, + tension: 280, + velocity: 0.02, + } + : { + clamp: true, + mass: 0.6, + tension: 400, + velocity: 0.02, + }, + }) + const mOffset = theme.spacing.medium - theme.spacing.small + + return ( + +
+ {children} +
+
+ ) +} +const AccordionContent = styled(AccordionContentUnstyled)( + ({ theme, pad, unstyled }) => + unstyled + ? {} + : { + transition: `marginTop ${paddingTransition}`, + ...(pad + ? { + paddingLeft: theme.spacing.medium, + paddingRight: theme.spacing.medium, + paddingBottom: theme.spacing.medium, + } + : {}), + } +) + +type AccordionPropsBase = { + textValue?: string + padContent?: boolean + unstyled?: boolean + children?: ReactNode | ((props: { isOpen: boolean }) => ReactNode) +} & UseDisclosureProps + +type AccordionPropsWithTrigger = AccordionPropsBase & { + triggerButton: ReactElement + label?: never +} + +type AccordionPropsWithLabel = AccordionPropsBase & { + label: ReactNode + triggerButton?: never +} + +export type AccordionProps = AccordionPropsWithTrigger | AccordionPropsWithLabel + +export default function Accordion({ + textValue, + label, + triggerButton, + padContent = true, + unstyled = false, + children, + isOpen: isOpenProp, + onOpenChange, + defaultOpen, + id, + ...props +}: AccordionProps) { + if (!textValue && typeof label === 'string') { + textValue = label + } + + const { triggerProps, contentProps, isOpen } = useDisclosure({ + defaultOpen, + isOpen: isOpenProp, + onOpenChange, + id, + }) + + useEffect(() => {}, [isOpen]) + + const kids = useMemo( + () => + typeof children === 'function' + ? children({ isOpen: !!isOpen }) + : children, + [children, isOpen] + ) + + const Wrapper = useMemo(() => { + if (unstyled) { + return function Div(props: ComponentProps<'div'>) { + return
+ } + } + + return Card + }, [unstyled]) + const finalTriggerProps = { + isOpen, + ...triggerProps, + } + + const trigger = triggerButton ? ( + React.cloneElement(triggerButton, finalTriggerProps) + ) : ( + + {label} + + ) + + return ( + + {trigger} + + {kids} + + + ) +} diff --git a/src/index.ts b/src/index.ts index 7ee7b823..7a4894d9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,14 @@ export * from './icons' export * from './plural-logos' // Components -export { default as Accordion } from './components/Accordion' +export { default as AccordionOLD } from './components/AccordionOLD' +export type { AccordionProps } from './components/Accordion' +export { + default as Accordion, + AccordionItem, + useIsItemOpen, + useCloseItem, +} from './components/Accordion' export { default as ArrowScroll } from './components/ArrowScroll' export { default as Banner } from './components/Banner' export { default as Button } from './components/Button' diff --git a/src/stories/Accordion.stories.tsx b/src/stories/Accordion.stories.tsx index 80954684..e2e6a162 100644 --- a/src/stories/Accordion.stories.tsx +++ b/src/stories/Accordion.stories.tsx @@ -1,45 +1,62 @@ -import styled from 'styled-components' - -import { Accordion, Button } from '..' +import { Accordion } from '..' +import { AccordionItem } from '../components/Accordion' export default { title: 'Accordion', component: Accordion, -} - -const CustomContent = styled.div(({ theme }) => ({ - paddingTop: theme.spacing.medium, - ...theme.partials.text.subtitle1, -})) - -function Template({ customTrigger, customContent, ...args }: any) { - if (customTrigger) { - args.triggerButton = - } - if (customContent) { - args.children = {args.children} - } - - return + argTypes: { + hideDefaultIcon: { + control: { + type: 'boolean', + }, + }, + type: { + options: ['single', 'multiple'], + control: { + type: 'select', + }, + }, + orientation: { + options: ['vertical', 'horizontal'], + control: { + type: 'select', + }, + }, + }, } export const Default = Template.bind({}) - Default.args = { - unstyled: false, - customTrigger: false, - label: 'Title', - children: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', + hideDefaultIcon: false, + type: 'single', + trigger: 'Title', + children: 'Children', } -export const CustomStyling = Template.bind({}) - -CustomStyling.args = { - unstyled: true, - customTrigger: true, - customContent: true, - label: 'Title', - children: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', +function Template({ hideDefaultIcon, trigger, children, ...args }: any) { + return ( + + + {children} + + + {children} + + + {children} + + + ) } diff --git a/src/theme.tsx b/src/theme.tsx index 878b4641..1aae2457 100644 --- a/src/theme.tsx +++ b/src/theme.tsx @@ -177,16 +177,6 @@ const getHonorableThemeProps = ({ mode }: { mode: ColorMode }) => { ({ inline }: any) => inline && textPartials.inlineLink, ], }, - Accordion: { - Root: [ - ({ ghost }: any) => - ghost && { - border: 'none', - elevation: 0, - backgroundColor: 'inherit', - }, - ], - }, Avatar: { Root: [ { diff --git a/yarn.lock b/yarn.lock index b6cd0f2a..976d5475 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3059,6 +3059,7 @@ __metadata: "@markdoc/markdoc": 0.4.0 "@monaco-editor/react": 4.6.0 "@pluralsh/eslint-config-typescript": 2.5.147 + "@radix-ui/react-accordion": ^1.2.0 "@react-aria/utils": 3.23.0 "@react-hooks-library/core": 0.6.0 "@react-spring/web": 9.7.3 @@ -3313,6 +3314,40 @@ __metadata: languageName: node linkType: hard +"@radix-ui/primitive@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/primitive@npm:1.1.0" + checksum: 7cbf70bfd4b2200972dbd52a9366801b5a43dd844743dc97eb673b3ec8e64f5dd547538faaf9939abbfe8bb275773767ecf5a87295d90ba09c15cba2b5528c89 + languageName: node + linkType: hard + +"@radix-ui/react-accordion@npm:^1.2.0": + version: 1.2.0 + resolution: "@radix-ui/react-accordion@npm:1.2.0" + dependencies: + "@radix-ui/primitive": 1.1.0 + "@radix-ui/react-collapsible": 1.1.0 + "@radix-ui/react-collection": 1.1.0 + "@radix-ui/react-compose-refs": 1.1.0 + "@radix-ui/react-context": 1.1.0 + "@radix-ui/react-direction": 1.1.0 + "@radix-ui/react-id": 1.1.0 + "@radix-ui/react-primitive": 2.0.0 + "@radix-ui/react-use-controllable-state": 1.1.0 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 7761c9e5758d4aa288d21ad02925cca0b58dbcab1ebe4de2c660b601d12a4cb50c9949a267a1d34d4a48fa87dd3076a4a476c28a22efdfbae219d6e51b99b760 + languageName: node + linkType: hard + "@radix-ui/react-arrow@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-arrow@npm:1.0.3" @@ -3333,20 +3368,49 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-collapsible@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-collapsible@npm:1.1.0" + dependencies: + "@radix-ui/primitive": 1.1.0 + "@radix-ui/react-compose-refs": 1.1.0 + "@radix-ui/react-context": 1.1.0 + "@radix-ui/react-id": 1.1.0 + "@radix-ui/react-presence": 1.1.0 + "@radix-ui/react-primitive": 2.0.0 + "@radix-ui/react-use-controllable-state": 1.1.0 + "@radix-ui/react-use-layout-effect": 1.1.0 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 1891dde55bf716d9619bd54da72bc65005cbc9dec2395079b53abe0bf4d655906bcbb85ca040e09b9bd8e3fcd0e58154a7ddc410b848db1dfb34ca1530459af0 + languageName: node + linkType: hard + "@radix-ui/react-collection@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-collection@npm:1.0.3" dependencies: - "@babel/runtime": ^7.13.10 - "@radix-ui/react-compose-refs": 1.0.1 - "@radix-ui/react-context": 1.0.1 - "@radix-ui/react-primitive": 1.0.3 - "@radix-ui/react-slot": 1.0.2 + "@radix-ui/primitive": 1.1.0 + "@radix-ui/react-compose-refs": 1.1.0 + "@radix-ui/react-context": 1.1.0 + "@radix-ui/react-id": 1.1.0 + "@radix-ui/react-presence": 1.1.0 + "@radix-ui/react-primitive": 2.0.0 + "@radix-ui/react-use-controllable-state": 1.1.0 + "@radix-ui/react-use-layout-effect": 1.1.0 peerDependencies: "@types/react": "*" "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: "@types/react": optional: true @@ -3356,6 +3420,28 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-collection@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-collection@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": 1.1.0 + "@radix-ui/react-context": 1.1.0 + "@radix-ui/react-primitive": 2.0.0 + "@radix-ui/react-slot": 1.1.0 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 70cee7f23cf19b0a9533723ba2ce80a40013d7b5e3588acd40e3f155cb46e0d94d9ebef58fd907d9862e2cb2b65f3f73315719597a790aefabfeae8a64566807 + languageName: node + linkType: hard + "@radix-ui/react-compose-refs@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-compose-refs@npm:1.0.1" @@ -3371,6 +3457,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-compose-refs@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-compose-refs@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 047a4ed5f87cb848be475507cd62836cf5af5761484681f521ea543ea7c9d59d61d42806d6208863d5e2380bf38cdf4cff73c2bbe5f52dbbe50fb04e1a13ac72 + languageName: node + linkType: hard + "@radix-ui/react-context@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-context@npm:1.0.1" @@ -3386,6 +3485,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-context@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-context@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: d48df5e5193a1d963a1ff7a58f08497c60ddc364216c59090c8267985bd478447dd617847ea277afe10e67c4e0c528894c8d7407082325e0650038625140558a + languageName: node + linkType: hard + "@radix-ui/react-direction@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-direction@npm:1.0.1" @@ -3401,6 +3513,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-direction@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-direction@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 25ad0d1d65ad08c93cebfbefdff9ef2602e53f4573a66b37d2c366ede9485e75ec6fc8e7dd7d2939b34ea5504ca0fe6ac4a3acc2f6ee9b62d131d65486eafd49 + languageName: node + linkType: hard + "@radix-ui/react-dismissable-layer@npm:1.0.4": version: 1.0.4 resolution: "@radix-ui/react-dismissable-layer@npm:1.0.4" @@ -3478,6 +3603,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-id@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-id@npm:1.1.0" + dependencies: + "@radix-ui/react-use-layout-effect": 1.1.0 + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 6fbc9d1739b3b082412da10359e63967b4f3a60383ebda4c9e56b07a722d29bee53b203b3b1418f88854a29315a7715867133bb149e6e22a027a048cdd20d970 + languageName: node + linkType: hard + "@radix-ui/react-popper@npm:1.1.2": version: 1.1.2 resolution: "@radix-ui/react-popper@npm:1.1.2" @@ -3527,12 +3667,51 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-presence@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-presence@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": 1.1.0 + "@radix-ui/react-use-layout-effect": 1.1.0 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 7f482268aa5bb5a4214dcf39d20ad93cac96585f1f248931be897ed8a9f99965b7f9b2e8bd4f4140c64eb243b471c471bf148e107f49578cc582faa773d3e83a + languageName: node + linkType: hard + "@radix-ui/react-primitive@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-primitive@npm:1.0.3" dependencies: - "@babel/runtime": ^7.13.10 - "@radix-ui/react-slot": 1.0.2 + "@radix-ui/react-compose-refs": 1.1.0 + "@radix-ui/react-use-layout-effect": 1.1.0 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 9402bc22923c8e5c479051974a721c301535c36521c0237b83e5fa213d013174e77f3ad7905e6d60ef07e14f88ec7f4ea69891dc7a2b39047f8d3640e8f8d713 + languageName: node + linkType: hard + +"@radix-ui/react-primitive@npm:2.0.0": + version: 2.0.0 + resolution: "@radix-ui/react-primitive@npm:2.0.0" + dependencies: + "@radix-ui/react-slot": 1.1.0 peerDependencies: "@types/react": "*" "@types/react-dom": "*" @@ -3543,7 +3722,7 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 9402bc22923c8e5c479051974a721c301535c36521c0237b83e5fa213d013174e77f3ad7905e6d60ef07e14f88ec7f4ea69891dc7a2b39047f8d3640e8f8d713 + checksum: 04afc0f3a5ccf1de6e4861f755a89f31640d5a07237c5ac5bffe47bcd8fdf318257961fa56fedc823af49281800ee755752a371561c36fd92f008536a0553748 languageName: node linkType: hard @@ -3651,6 +3830,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-slot@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-slot@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": 1.1.0 + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 3c9cd90aabf08f541e20dbecb581744be01c552a0cd16e90d7c218381bcc5307aa8a6013d045864e692ba89d3d8c17bfae08df18ed18be6d223d9330ab0302fa + languageName: node + linkType: hard + "@radix-ui/react-toggle-group@npm:1.0.4": version: 1.0.4 resolution: "@radix-ui/react-toggle-group@npm:1.0.4" @@ -3740,6 +3934,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-callback-ref@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-callback-ref@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 2ec7903c67e3034b646005556f44fd975dc5204db6885fc58403e3584f27d95f0b573bc161de3d14fab9fda25150bf3b91f718d299fdfc701c736bd0bd2281fa + languageName: node + linkType: hard + "@radix-ui/react-use-controllable-state@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-use-controllable-state@npm:1.0.1" @@ -3756,6 +3963,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-controllable-state@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-controllable-state@npm:1.1.0" + dependencies: + "@radix-ui/react-use-callback-ref": 1.1.0 + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: a6c167cf8eb0744effbeab1f92ea6c0ad71838b222670c0488599f28eecd941d87ac1eed4b5d3b10df6dc7b7b2edb88a54e99d92c2942ce3b21f81d5c188f32d + languageName: node + linkType: hard + "@radix-ui/react-use-escape-keydown@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-use-escape-keydown@npm:1.0.3" @@ -3787,6 +4009,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-layout-effect@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-layout-effect@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 271ea0bf1cd74718895a68414a6e95537737f36e02ad08eeb61a82b229d6abda9cff3135a479e134e1f0ce2c3ff97bb85babbdce751985fb755a39b231d7ccf2 + languageName: node + linkType: hard + "@radix-ui/react-use-previous@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-use-previous@npm:1.0.1"