diff --git a/apps/playground/app/dashboard/page.tsx b/apps/playground/app/dashboard/page.tsx
index 273a87a1..e8d4572c 100644
--- a/apps/playground/app/dashboard/page.tsx
+++ b/apps/playground/app/dashboard/page.tsx
@@ -1,3 +1,4 @@
+'use client';
import {
AccessibilityIcon,
CameraIcon,
@@ -43,6 +44,8 @@ import {
PopoverTrigger,
Separator,
Strong,
+ TabsNavLink,
+ TabsNavRoot,
Text,
TextArea,
TextFieldInput,
@@ -174,10 +177,14 @@ const WhopSVG = () => {
);
};
+import Link from 'next/link';
+import { usePathname } from 'next/navigation';
import { users } from '../demo/users';
import styles from './page.module.css';
export default function Demo() {
+ const pathname = usePathname();
+
return (
@@ -330,6 +337,14 @@ export default function Demo() {
+
+
+ Dashboard
+
+
+ Demo
+
+
;
+
+export default meta;
+type Story = StoryObj;
+
+// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
+
+export const Default: Story = {
+ render: (args) => (
+
+
+
+ Account
+
+ Documents
+ Settings
+
+
+ ),
+};
diff --git a/packages/frosted-ui/package.json b/packages/frosted-ui/package.json
index 046ba0b2..c7319a4f 100644
--- a/packages/frosted-ui/package.json
+++ b/packages/frosted-ui/package.json
@@ -64,6 +64,7 @@
"@radix-ui/react-direction": "^1.0.1",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-hover-card": "^1.0.7",
+ "@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-portal": "^1.0.4",
"@radix-ui/react-progress": "^1.0.3",
diff --git a/packages/frosted-ui/src/components/base-tabs-list.css b/packages/frosted-ui/src/components/base-tabs-list.css
new file mode 100644
index 00000000..ebb34bd8
--- /dev/null
+++ b/packages/frosted-ui/src/components/base-tabs-list.css
@@ -0,0 +1,144 @@
+.fui-BaseTabsList {
+ display: flex;
+ overflow-x: auto;
+ white-space: nowrap;
+
+ scrollbar-width: none;
+ &::-webkit-scrollbar {
+ display: none;
+ }
+}
+
+.fui-BaseTabsTrigger {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-sizing: border-box;
+ flex-shrink: 0;
+ position: relative;
+ user-select: none;
+}
+
+.fui-BaseTabsTriggerInner,
+.fui-BaseTabsTriggerInnerHidden {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.fui-BaseTabsTriggerInner {
+ position: absolute;
+
+ :where(.fui-BaseTabsTrigger[data-state='inactive'], .fui-TabsNavLink:not([data-active])) & {
+ letter-spacing: var(--tabs-trigger-inactive-letter-spacing);
+ word-spacing: var(--tabs-trigger-inactive-word-spacing);
+ }
+
+ :where(.fui-BaseTabsTrigger[data-state='active'], .fui-TabsNavLink[data-active]) & {
+ font-weight: var(--font-weight-medium);
+ letter-spacing: var(--tabs-trigger-active-letter-spacing);
+ word-spacing: var(--tabs-trigger-active-word-spacing);
+ }
+}
+
+.fui-BaseTabsTriggerInnerHidden {
+ visibility: hidden;
+ font-weight: var(--font-weight-medium);
+ letter-spacing: var(--tabs-trigger-active-letter-spacing);
+ word-spacing: var(--tabs-trigger-active-word-spacing);
+}
+
+.fui-BaseTabsContent {
+ position: relative;
+ outline: 0;
+}
+
+/***************************************************************************************************
+ * *
+ * SIZES *
+ * *
+ ***************************************************************************************************/
+
+.fui-BaseTabsTrigger {
+ padding-left: var(--tabs-trigger-padding-x);
+ padding-right: var(--tabs-trigger-padding-x);
+}
+
+.fui-BaseTabsTriggerInner,
+.fui-BaseTabsTriggerInnerHidden {
+ padding: var(--tabs-trigger-inner-padding-y)
+ var(--tabs-trigger-inner-padding-x);
+ border-radius: var(--tabs-trigger-inner-border-radius);
+}
+
+@breakpoints {
+ .fui-BaseTabsList {
+ &:where(.fui-r-size-1) {
+ height: 36px;
+ font-size: var(--font-size-1);
+ line-height: var(--line-height-1);
+ letter-spacing: var(--letter-spacing-1);
+ --tabs-trigger-padding-x: var(--space-1);
+ --tabs-trigger-inner-padding-x: calc(1.5 * var(--space-1));
+ --tabs-trigger-inner-padding-y: var(--space-1);
+ --tabs-trigger-inner-border-radius: var(--radius-2);
+ }
+ &:where(.fui-r-size-2) {
+ height: var(--space-7);
+ font-size: var(--font-size-2);
+ line-height: var(--line-height-2);
+ letter-spacing: var(--letter-spacing-2);
+ --tabs-trigger-padding-x: var(--space-1);
+ --tabs-trigger-inner-padding-x: calc(1.25 * var(--space-2));
+ --tabs-trigger-inner-padding-y: var(--space-1);
+ --tabs-trigger-inner-border-radius: var(--radius-3);
+ }
+ }
+}
+
+/***************************************************************************************************
+ * *
+ * VARIANTS *
+ * *
+ ***************************************************************************************************/
+
+.fui-BaseTabsList {
+ box-shadow: inset 0 -1px 0 0 var(--gray-a5);
+}
+
+.fui-BaseTabsTrigger {
+ color: var(--gray-a11);
+
+ @media (hover: hover) {
+ &:where(:hover) {
+ color: var(--gray-12);
+ }
+ &:where(:hover) :where(.fui-BaseTabsTriggerInner) {
+ background-color: var(--gray-a3);
+ }
+ &:where(:focus-visible:hover) :where(.fui-BaseTabsTriggerInner) {
+ background-color: var(--accent-a3);
+ }
+ }
+ &:where([data-state='active'], [data-active]) {
+ color: var(--gray-12);
+ }
+ &:where(:focus-visible) :where(.fui-BaseTabsTriggerInner) {
+ outline: 2px solid var(--color-focus-root);
+ outline-offset: -2px;
+ }
+ &:where([data-state='active'], [data-active])::before {
+ box-sizing: border-box;
+ content: '';
+ height: 2px;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background-color: var(--accent-10);
+ }
+}
+
+.fui-BaseTabsContent:where(:focus-visible) {
+ outline: 2px solid var(--color-focus-root);
+}
diff --git a/packages/frosted-ui/src/components/base-tabs-list.props.ts b/packages/frosted-ui/src/components/base-tabs-list.props.ts
new file mode 100644
index 00000000..06098b42
--- /dev/null
+++ b/packages/frosted-ui/src/components/base-tabs-list.props.ts
@@ -0,0 +1,11 @@
+import { PropDef } from '../helpers';
+
+const sizes = ['1', '2'] as const;
+
+const baseTabsListPropDefs = {
+ size: { type: 'enum', values: sizes, default: '2', responsive: true },
+} satisfies {
+ size: PropDef<(typeof sizes)[number]>;
+};
+
+export { baseTabsListPropDefs };
diff --git a/packages/frosted-ui/src/components/index.ts b/packages/frosted-ui/src/components/index.ts
index 5844fbe5..7a2b278c 100644
--- a/packages/frosted-ui/src/components/index.ts
+++ b/packages/frosted-ui/src/components/index.ts
@@ -245,6 +245,8 @@ export {
} from './table';
export * from './table.props';
export { Tabs, TabsContent, TabsList, TabsRoot, TabsTrigger } from './tabs';
+export { TabsNav, TabsNavLink, TabsNavRoot } from './tabs-nav';
+export * from './tabs-nav.props';
export * from './tabs.props';
// export * from './toast';
// export * from './toggle';
diff --git a/packages/frosted-ui/src/components/tabs-nav.css b/packages/frosted-ui/src/components/tabs-nav.css
new file mode 100644
index 00000000..808ff16e
--- /dev/null
+++ b/packages/frosted-ui/src/components/tabs-nav.css
@@ -0,0 +1,5 @@
+@import './base-tabs-list.css';
+
+.fui-TabsNavItem {
+ display: flex;
+}
diff --git a/packages/frosted-ui/src/components/tabs-nav.props.ts b/packages/frosted-ui/src/components/tabs-nav.props.ts
new file mode 100644
index 00000000..f5623bc8
--- /dev/null
+++ b/packages/frosted-ui/src/components/tabs-nav.props.ts
@@ -0,0 +1,10 @@
+import { asChildProp } from '../helpers';
+
+const tabsNavLinkPropDefs = {
+ asChild: asChildProp,
+} satisfies {
+ asChild: typeof asChildProp;
+};
+
+export { baseTabsListPropDefs as tabsNavPropDefs } from './base-tabs-list.props';
+export { tabsNavLinkPropDefs };
diff --git a/packages/frosted-ui/src/components/tabs-nav.tsx b/packages/frosted-ui/src/components/tabs-nav.tsx
new file mode 100644
index 00000000..b2bfdac0
--- /dev/null
+++ b/packages/frosted-ui/src/components/tabs-nav.tsx
@@ -0,0 +1,121 @@
+'use client';
+
+import * as NavigationMenu from '@radix-ui/react-navigation-menu';
+import classNames from 'classnames';
+import * as React from 'react';
+import {
+ GetPropDefTypes,
+ MarginProps,
+ extractMarginProps,
+ getSubtree,
+ withBreakpoints,
+ withMarginProps,
+} from '../helpers';
+import { tabsNavLinkPropDefs, tabsNavPropDefs } from './tabs-nav.props';
+
+type TabsNavRootElement = React.ElementRef;
+type TabsNavOwnProps = GetPropDefTypes;
+interface TabsNavRootProps
+ extends Omit<
+ React.ComponentPropsWithoutRef,
+ | 'asChild'
+ | 'orientation'
+ | 'defauValue'
+ | 'value'
+ | 'onValueChange'
+ | 'delayDuration'
+ | 'skipDelayDuration'
+ >,
+ MarginProps,
+ TabsNavOwnProps {}
+const TabsNavRoot = React.forwardRef(
+ (props, forwardedRef) => {
+ const { rest: marginRest, ...marginProps } = extractMarginProps(props);
+ const {
+ children,
+ className,
+ size = tabsNavPropDefs.size.default,
+ ...rootProps
+ } = marginRest;
+
+ return (
+
+
+ {children}
+
+
+ );
+ },
+);
+TabsNavRoot.displayName = 'TabsNavRoot';
+
+type TabsNavLinkElement = React.ElementRef;
+type TabsNavLinkOwnProps = GetPropDefTypes;
+interface TabsNavLinkProps
+ extends Omit<
+ React.ComponentPropsWithoutRef,
+ 'onSelect'
+ >,
+ TabsNavLinkOwnProps {}
+const TabsNavLink = React.forwardRef(
+ (props, forwardedRef) => {
+ const { asChild, children, className, ...linkProps } = props;
+
+ return (
+
+ {}}
+ asChild={asChild}
+ >
+ {getSubtree({ asChild, children }, (children) => (
+ <>
+
+ {children}
+
+
+ {children}
+
+ >
+ ))}
+
+
+ );
+ },
+);
+
+TabsNavLink.displayName = 'TabsNavLink';
+
+const TabsNav = Object.assign(
+ {},
+ {
+ Root: TabsNavRoot,
+ Link: TabsNavLink,
+ },
+);
+
+export { TabsNav, TabsNavLink, TabsNavRoot };
+export type { TabsNavLinkProps, TabsNavRootProps };
diff --git a/packages/frosted-ui/src/components/tabs.css b/packages/frosted-ui/src/components/tabs.css
index 175a8c66..28805040 100644
--- a/packages/frosted-ui/src/components/tabs.css
+++ b/packages/frosted-ui/src/components/tabs.css
@@ -1,144 +1,10 @@
-.fui-TabsList {
- display: flex;
- overflow-x: auto;
- white-space: nowrap;
-
- scrollbar-width: none;
- &::-webkit-scrollbar {
- display: none;
- }
-}
-
-.fui-TabsTrigger {
- display: flex;
- align-items: center;
- justify-content: center;
- box-sizing: border-box;
- flex-shrink: 0;
- position: relative;
- user-select: none;
-}
-
-.fui-TabsTriggerInner,
-.fui-TabsTriggerInnerHidden {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.fui-TabsTriggerInner {
- position: absolute;
-
- :where(.fui-TabsTrigger[data-state='inactive']) & {
- letter-spacing: var(--tabs-trigger-inactive-letter-spacing);
- word-spacing: var(--tabs-trigger-inactive-word-spacing);
- }
-
- :where(.fui-TabsTrigger[data-state='active']) & {
- font-weight: var(--font-weight-medium);
- letter-spacing: var(--tabs-trigger-active-letter-spacing);
- word-spacing: var(--tabs-trigger-active-word-spacing);
- }
-}
-
-.fui-TabsTriggerInnerHidden {
- visibility: hidden;
- font-weight: var(--font-weight-medium);
- letter-spacing: var(--tabs-trigger-active-letter-spacing);
- word-spacing: var(--tabs-trigger-active-word-spacing);
-}
+@import './base-tabs-list.css';
.fui-TabsContent {
position: relative;
outline: 0;
}
-/***************************************************************************************************
- * *
- * SIZES *
- * *
- ***************************************************************************************************/
-
-.fui-TabsTrigger {
- padding-left: var(--tabs-trigger-padding-x);
- padding-right: var(--tabs-trigger-padding-x);
-}
-
-.fui-TabsTriggerInner,
-.fui-TabsTriggerInnerHidden {
- padding: var(--tabs-trigger-inner-padding-y)
- var(--tabs-trigger-inner-padding-x);
- border-radius: var(--tabs-trigger-inner-border-radius);
-}
-
-@breakpoints {
- .fui-TabsList {
- &:where(.fui-r-size-1) {
- height: 36px;
- font-size: var(--font-size-1);
- line-height: var(--line-height-1);
- letter-spacing: var(--letter-spacing-1);
- --tabs-trigger-padding-x: var(--space-1);
- --tabs-trigger-inner-padding-x: calc(1.5 * var(--space-1));
- --tabs-trigger-inner-padding-y: var(--space-1);
- --tabs-trigger-inner-border-radius: var(--radius-2);
- }
- &:where(.fui-r-size-2) {
- height: var(--space-7);
- font-size: var(--font-size-2);
- line-height: var(--line-height-2);
- letter-spacing: var(--letter-spacing-2);
- --tabs-trigger-padding-x: var(--space-1);
- --tabs-trigger-inner-padding-x: calc(1.25 * var(--space-2));
- --tabs-trigger-inner-padding-y: var(--space-1);
- --tabs-trigger-inner-border-radius: var(--radius-3);
- }
- }
-}
-
-/***************************************************************************************************
- * *
- * VARIANTS *
- * *
- ***************************************************************************************************/
-
-.fui-TabsList {
- box-shadow: inset 0 -1px 0 0 var(--gray-a5);
-}
-
-.fui-TabsTrigger {
- color: var(--gray-a11);
-
- @media (hover: hover) {
- &:where(:hover) {
- color: var(--gray-12);
- }
- &:where(:hover) :where(.fui-TabsTriggerInner) {
- background-color: var(--gray-a3);
- }
- &:where(:focus-visible:hover) :where(.fui-TabsTriggerInner) {
- background-color: var(--accent-a3);
- }
- }
- &:where([data-state='active']) {
- color: var(--gray-12);
- }
- &:where(:focus-visible) :where(.fui-TabsTriggerInner) {
- outline: 2px solid var(--color-focus-root);
- outline-offset: -2px;
- }
- &:where([data-state='active'])::before {
- box-sizing: border-box;
- content: '';
- height: 2px;
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- background-color: var(--accent-10);
- }
-}
-
.fui-TabsContent:where(:focus-visible) {
outline: 2px solid var(--color-focus-root);
}
diff --git a/packages/frosted-ui/src/components/tabs.props.ts b/packages/frosted-ui/src/components/tabs.props.ts
index 2209e79c..58196af1 100644
--- a/packages/frosted-ui/src/components/tabs.props.ts
+++ b/packages/frosted-ui/src/components/tabs.props.ts
@@ -1,11 +1 @@
-import { PropDef } from '../helpers';
-
-const sizes = ['1', '2'] as const;
-
-const tabsListPropDefs = {
- size: { type: 'enum', values: sizes, default: '2', responsive: true },
-} satisfies {
- size: PropDef<(typeof sizes)[number]>;
-};
-
-export { tabsListPropDefs };
+export { baseTabsListPropDefs as tabsListPropDefs } from './base-tabs-list.props';
diff --git a/packages/frosted-ui/src/components/tabs.tsx b/packages/frosted-ui/src/components/tabs.tsx
index 150fefbe..823c578b 100644
--- a/packages/frosted-ui/src/components/tabs.tsx
+++ b/packages/frosted-ui/src/components/tabs.tsx
@@ -52,6 +52,7 @@ const TabsList = React.forwardRef(
{...listProps}
ref={forwardedRef}
className={classNames(
+ 'fui-BaseTabsList',
'fui-TabsList',
className,
withBreakpoints(size, 'fui-r-size'),
@@ -72,10 +73,19 @@ const TabsTrigger = React.forwardRef(
- {children}
- {children}
+
+ {children}
+
+
+ {children}
+
);
},
diff --git a/packages/frosted-ui/src/helpers/get-subtree.ts b/packages/frosted-ui/src/helpers/get-subtree.ts
new file mode 100644
index 00000000..51595eba
--- /dev/null
+++ b/packages/frosted-ui/src/helpers/get-subtree.ts
@@ -0,0 +1,21 @@
+import * as React from 'react';
+
+/**
+ * This is a helper function that is used when a component supports `asChild`
+ * using the `Slot` component but its implementation contains nested DOM elements.
+ *
+ * Using it ensures if a consumer uses the `asChild` prop, the elements are in
+ * correct order in the DOM, adopting the intended consumer `children`.
+ */
+export function getSubtree(
+ options: { asChild: boolean | undefined; children: React.ReactNode },
+ content: React.ReactNode | ((children: React.ReactNode) => React.ReactNode)
+) {
+ const { asChild, children } = options;
+ if (!asChild) return typeof content === 'function' ? content(children) : content;
+
+ const firstChild = React.Children.only(children) as React.ReactElement;
+ return React.cloneElement(firstChild, {
+ children: typeof content === 'function' ? content(firstChild.props.children) : content,
+ });
+}
diff --git a/packages/frosted-ui/src/helpers/index.ts b/packages/frosted-ui/src/helpers/index.ts
index c49113e8..92c4eab3 100644
--- a/packages/frosted-ui/src/helpers/index.ts
+++ b/packages/frosted-ui/src/helpers/index.ts
@@ -1,6 +1,7 @@
-export * from './props';
export * from './breakpoints';
export * from './extract-props-for-tag';
+export * from './get-subtree';
export * from './has-own-property';
export * from './nice-intersection';
+export * from './props';
export * from './radix-colors';
diff --git a/packages/frosted-ui/src/helpers/props/as-child.prop.ts b/packages/frosted-ui/src/helpers/props/as-child.prop.ts
new file mode 100644
index 00000000..6b04bd52
--- /dev/null
+++ b/packages/frosted-ui/src/helpers/props/as-child.prop.ts
@@ -0,0 +1,8 @@
+import { PropDef } from './prop-def.js';
+
+const asChildProp = {
+ type: 'boolean',
+ default: undefined,
+} satisfies PropDef;
+
+export { asChildProp };
diff --git a/packages/frosted-ui/src/helpers/props/index.ts b/packages/frosted-ui/src/helpers/props/index.ts
index c418154c..7c9c7242 100644
--- a/packages/frosted-ui/src/helpers/props/index.ts
+++ b/packages/frosted-ui/src/helpers/props/index.ts
@@ -1,3 +1,4 @@
+export * from './as-child.prop';
export * from './color.prop';
export * from './high-contrast.prop';
export * from './layout.props';
diff --git a/packages/frosted-ui/src/styles/index.css b/packages/frosted-ui/src/styles/index.css
index 48039773..509464b5 100644
--- a/packages/frosted-ui/src/styles/index.css
+++ b/packages/frosted-ui/src/styles/index.css
@@ -54,6 +54,7 @@
@import '../components/strong.css';
@import '../components/switch.css';
@import '../components/tabs.css';
+@import '../components/tabs-nav.css';
@import '../components/table.css';
@import '../components/text-area.css';
@import '../components/text-field.css';
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9fb5681a..23d56ade 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -182,6 +182,9 @@ importers:
'@radix-ui/react-hover-card':
specifier: ^1.0.7
version: 1.0.7(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-navigation-menu':
+ specifier: ^1.1.4
+ version: 1.1.4(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-popover':
specifier: ^1.0.7
version: 1.0.7(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0)
@@ -3090,6 +3093,40 @@ packages:
react-remove-scroll: 2.5.5(@types/react@18.0.22)(react@18.2.0)
dev: false
+ /@radix-ui/react-navigation-menu@1.1.4(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-Cc+seCS3PmWmjI51ufGG7zp1cAAIRqHVw7C9LOA2TZ+R4hG6rDvHcTqIsEEFLmZO3zNVH72jOOE7kKNy8W+RtA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.22.6
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.0.22)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.0.22)(react@18.2.0)
+ '@radix-ui/react-direction': 1.0.1(@types/react@18.0.22)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.0.22)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.0.22)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.0.22)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.0.22)(react@18.2.0)
+ '@radix-ui/react-use-previous': 1.0.1(@types/react@18.0.22)(react@18.2.0)
+ '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0)
+ '@types/react': 18.0.22
+ '@types/react-dom': 18.2.7
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.7)(@types/react@18.0.22)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==}
peerDependencies: