From 3e8223730019e580f3e3893955ea42c32dba2ee1 Mon Sep 17 00:00:00 2001 From: Ahmed Elsakaan Date: Wed, 12 Jul 2023 18:15:32 +0100 Subject: [PATCH] feat(ui): adds many components to design system (#232) --- .vscode/settings.json | 3 +- packages/ui/package.json | 3 + .../ui/src/aspect-ratio/aspect-ratio.spec.tsx | 15 +++ .../src/aspect-ratio/aspect-ratio.stories.tsx | 40 ++++++++ packages/ui/src/aspect-ratio/index.tsx | 5 + packages/ui/src/avatar/avatar.spec.tsx | 66 +++++++++++++ packages/ui/src/avatar/avatar.stories.tsx | 36 ++++++++ packages/ui/src/avatar/index.tsx | 50 ++++++++++ packages/ui/src/brand/brand.stories.tsx | 2 +- packages/ui/src/index.ts | 9 +- packages/ui/src/skeleton/index.tsx | 19 ++++ packages/ui/src/skeleton/skeleton.spec.tsx | 11 +++ packages/ui/src/skeleton/skeleton.stories.tsx | 26 ++++++ packages/ui/src/tooltip/index.tsx | 29 ++++++ packages/ui/src/tooltip/tooltip.spec.tsx | 32 +++++++ packages/ui/src/tooltip/tooltip.stories.tsx | 32 +++++++ packages/ui/src/typography/index.tsx | 92 +++++++++++++++++++ .../ui/src/typography/typography.h1.spec.tsx | 29 ++++++ .../src/typography/typography.h1.stories.tsx | 17 ++++ .../ui/src/typography/typography.h2.spec.tsx | 29 ++++++ .../src/typography/typography.h2.stories.tsx | 17 ++++ .../ui/src/typography/typography.h3.spec.tsx | 29 ++++++ .../src/typography/typography.h3.stories.tsx | 17 ++++ .../ui/src/typography/typography.h4.spec.tsx | 29 ++++++ .../src/typography/typography.h4.stories.tsx | 17 ++++ .../ui/src/typography/typography.p.spec.tsx | 27 ++++++ .../src/typography/typography.p.stories.tsx | 17 ++++ pnpm-lock.yaml | 88 +++++++++++++++++- 28 files changed, 781 insertions(+), 5 deletions(-) create mode 100644 packages/ui/src/aspect-ratio/aspect-ratio.spec.tsx create mode 100644 packages/ui/src/aspect-ratio/aspect-ratio.stories.tsx create mode 100644 packages/ui/src/aspect-ratio/index.tsx create mode 100644 packages/ui/src/avatar/avatar.spec.tsx create mode 100644 packages/ui/src/avatar/avatar.stories.tsx create mode 100644 packages/ui/src/avatar/index.tsx create mode 100644 packages/ui/src/skeleton/index.tsx create mode 100644 packages/ui/src/skeleton/skeleton.spec.tsx create mode 100644 packages/ui/src/skeleton/skeleton.stories.tsx create mode 100644 packages/ui/src/tooltip/index.tsx create mode 100644 packages/ui/src/tooltip/tooltip.spec.tsx create mode 100644 packages/ui/src/tooltip/tooltip.stories.tsx create mode 100644 packages/ui/src/typography/index.tsx create mode 100644 packages/ui/src/typography/typography.h1.spec.tsx create mode 100644 packages/ui/src/typography/typography.h1.stories.tsx create mode 100644 packages/ui/src/typography/typography.h2.spec.tsx create mode 100644 packages/ui/src/typography/typography.h2.stories.tsx create mode 100644 packages/ui/src/typography/typography.h3.spec.tsx create mode 100644 packages/ui/src/typography/typography.h3.stories.tsx create mode 100644 packages/ui/src/typography/typography.h4.spec.tsx create mode 100644 packages/ui/src/typography/typography.h4.stories.tsx create mode 100644 packages/ui/src/typography/typography.p.spec.tsx create mode 100644 packages/ui/src/typography/typography.p.stories.tsx diff --git a/.vscode/settings.json b/.vscode/settings.json index 4f04b207..9a902aea 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,8 @@ } ], "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": true, + "source.organizeImports": true }, "editor.formatOnSave": true, "tailwindCSS.experimental.classRegex": [ diff --git a/packages/ui/package.json b/packages/ui/package.json index 41a6119a..486f1d0e 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -26,6 +26,9 @@ }, "dependencies": { "@fontsource-variable/inter": "^5.0.5", + "@radix-ui/react-aspect-ratio": "^1.0.3", + "@radix-ui/react-avatar": "^1.0.3", + "@radix-ui/react-tooltip": "^1.0.6", "clsx": "^1.2.1", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/packages/ui/src/aspect-ratio/aspect-ratio.spec.tsx b/packages/ui/src/aspect-ratio/aspect-ratio.spec.tsx new file mode 100644 index 00000000..8e619689 --- /dev/null +++ b/packages/ui/src/aspect-ratio/aspect-ratio.spec.tsx @@ -0,0 +1,15 @@ +import { render, screen } from '@noodle/test-utils/renderer'; + +import { AspectRatio } from '.'; + +describe('Aspect Ratio', () => { + it('should render children', () => { + render( + +
children
+
, + ); + + expect(screen.getByText('children')).toBeInTheDocument(); + }); +}); diff --git a/packages/ui/src/aspect-ratio/aspect-ratio.stories.tsx b/packages/ui/src/aspect-ratio/aspect-ratio.stories.tsx new file mode 100644 index 00000000..4c2ced46 --- /dev/null +++ b/packages/ui/src/aspect-ratio/aspect-ratio.stories.tsx @@ -0,0 +1,40 @@ +import { type FC } from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { AspectRatio } from '.'; + +const component: FC<{ ratio: number }> = ({ ratio }) => ( +
+ + random + +
+); + +export default { + title: 'UI / Aspect Ratio', + component, + args: { + ratio: 16 / 9, + }, +} as Meta; + +type Story = StoryObj; + +export const _16_9: Story = {}; + +export const _1_1: Story = { + args: { + ratio: 1, + }, +}; + +export const _4_3: Story = { + args: { + ratio: 4 / 3, + }, +}; diff --git a/packages/ui/src/aspect-ratio/index.tsx b/packages/ui/src/aspect-ratio/index.tsx new file mode 100644 index 00000000..5dfdf1e6 --- /dev/null +++ b/packages/ui/src/aspect-ratio/index.tsx @@ -0,0 +1,5 @@ +import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio'; + +const AspectRatio = AspectRatioPrimitive.Root; + +export { AspectRatio }; diff --git a/packages/ui/src/avatar/avatar.spec.tsx b/packages/ui/src/avatar/avatar.spec.tsx new file mode 100644 index 00000000..a4715b6e --- /dev/null +++ b/packages/ui/src/avatar/avatar.spec.tsx @@ -0,0 +1,66 @@ +import { render, screen } from '@noodle/test-utils/renderer'; + +import { Avatar, AvatarFallback, AvatarImage } from '.'; + +declare global { + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + interface Window { + Image: typeof Image; + } +} + +class MockImage extends Image { + override set onload(value: (() => void) | null) { + super.onload = value; + } + + override set src(value: string) { + super.src = value; + if (this.onload) { + this.onload(); + } + } +} + +describe('Avatar', () => { + let originalImage: typeof Image; + + beforeAll(() => { + // Save the original Image object + originalImage = window.Image; + + // Assign the mock Image + window.Image = MockImage as unknown as typeof Image; + }); + + afterAll(() => { + // Restore the original Image object after all tests in this block are done + window.Image = originalImage; + }); + + it('should render the image', () => { + render( + + + , + ); + + expect(screen.getByRole('img')).toHaveAttribute( + 'src', + 'https://avatars.githubusercontent.com/u/20271968?v=4', + ); + }); + + it('should render the fallback', () => { + render( + + AE + , + ); + + expect(screen.getByText('AE')).toBeInTheDocument(); + }); +}); diff --git a/packages/ui/src/avatar/avatar.stories.tsx b/packages/ui/src/avatar/avatar.stories.tsx new file mode 100644 index 00000000..b0ba3a37 --- /dev/null +++ b/packages/ui/src/avatar/avatar.stories.tsx @@ -0,0 +1,36 @@ +import { type FC } from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { Avatar, AvatarFallback, AvatarImage } from '.'; + +const component: FC<{ fallback: boolean }> = ({ fallback }) => { + return ( + + {!fallback && ( + + )} + AE + + ); +}; + +export default { + title: 'Design System / Avatar', + component, + args: { + fallback: false, + }, +} as Meta; + +type Story = StoryObj; + +export const Image: Story = {}; + +export const Fallback: Story = { + args: { + fallback: true, + }, +}; diff --git a/packages/ui/src/avatar/index.tsx b/packages/ui/src/avatar/index.tsx new file mode 100644 index 00000000..9992f7bf --- /dev/null +++ b/packages/ui/src/avatar/index.tsx @@ -0,0 +1,50 @@ +import { forwardRef } from 'react'; +import type { ComponentPropsWithoutRef, ElementRef } from 'react'; +import { Fallback, Image, Root } from '@radix-ui/react-avatar'; + +import { cn } from '../utils/cn'; + +export const Avatar = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +Avatar.displayName = Root.displayName; + +export const AvatarImage = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +AvatarImage.displayName = Image.displayName; + +export const AvatarFallback = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +AvatarFallback.displayName = Fallback.displayName; diff --git a/packages/ui/src/brand/brand.stories.tsx b/packages/ui/src/brand/brand.stories.tsx index 43f6771a..13458c6a 100644 --- a/packages/ui/src/brand/brand.stories.tsx +++ b/packages/ui/src/brand/brand.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Brand } from '.'; export default { - title: 'Design System / Brand', + title: 'UI / Brand', component: Brand, args: { size: 100, diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 1e8c834e..3719c105 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -1,2 +1,7 @@ -export { Brand } from './brand'; -export { cn } from './utils/cn'; +export * from './brand'; +export * from './utils/cn'; +export * from './typography'; +export * from './aspect-ratio'; +export * from './skeleton'; +export * from './avatar'; +export * from './tooltip'; diff --git a/packages/ui/src/skeleton/index.tsx b/packages/ui/src/skeleton/index.tsx new file mode 100644 index 00000000..bccbd8f1 --- /dev/null +++ b/packages/ui/src/skeleton/index.tsx @@ -0,0 +1,19 @@ +import { type HTMLAttributes } from 'react'; + +import { cn } from '../utils/cn'; + +export const Skeleton = ({ + className, + ...props +}: HTMLAttributes) => { + return ( +
+ ); +}; diff --git a/packages/ui/src/skeleton/skeleton.spec.tsx b/packages/ui/src/skeleton/skeleton.spec.tsx new file mode 100644 index 00000000..0247a078 --- /dev/null +++ b/packages/ui/src/skeleton/skeleton.spec.tsx @@ -0,0 +1,11 @@ +import { render, screen } from '@noodle/test-utils/renderer'; + +import { Skeleton } from '.'; + +describe('Skeleton', () => { + it('should render the component', () => { + render(); + + expect(screen.getByRole('presentation')).toHaveClass('animate-pulse'); + }); +}); diff --git a/packages/ui/src/skeleton/skeleton.stories.tsx b/packages/ui/src/skeleton/skeleton.stories.tsx new file mode 100644 index 00000000..da53ae3b --- /dev/null +++ b/packages/ui/src/skeleton/skeleton.stories.tsx @@ -0,0 +1,26 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Skeleton } from '.'; + +const component = () => { + return ( +
+ +
+ + +
+
+ ); +}; + +export default { + title: 'UI / Skeleton', + component, +} as Meta; + +type Story = StoryObj; + +export const Default: Story = { + name: 'Skeleton', +}; diff --git a/packages/ui/src/tooltip/index.tsx b/packages/ui/src/tooltip/index.tsx new file mode 100644 index 00000000..e7c92f1f --- /dev/null +++ b/packages/ui/src/tooltip/index.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import * as TooltipPrimitive from '@radix-ui/react-tooltip'; + +import { cn } from '../utils/cn'; + +const TooltipProvider = TooltipPrimitive.Provider; + +const Tooltip = TooltipPrimitive.Root; + +const TooltipTrigger = TooltipPrimitive.Trigger; + +const TooltipContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + +)); + +TooltipContent.displayName = TooltipPrimitive.Content.displayName; + +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }; diff --git a/packages/ui/src/tooltip/tooltip.spec.tsx b/packages/ui/src/tooltip/tooltip.spec.tsx new file mode 100644 index 00000000..7d087d44 --- /dev/null +++ b/packages/ui/src/tooltip/tooltip.spec.tsx @@ -0,0 +1,32 @@ +import userEvent from '@testing-library/user-event'; + +import { render, screen } from '@noodle/test-utils/renderer'; + +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '.'; + +describe('Tooltip', () => { + it('should render the tooltip content', async () => { + render( + + + Trigger Tooltip + +

+ You can invoke the bold styling by clicking on this button or + using the CMD + B keyboard shortcut. +

+
+
+
, + ); + + await userEvent.hover( + screen.getByRole('button', { name: /trigger tooltip/i }), + ); + + const all = await screen.findAllByText(/invoke the bold styling/i); + + // IDK why but it renders twice + expect(all).toHaveLength(2); + }); +}); diff --git a/packages/ui/src/tooltip/tooltip.stories.tsx b/packages/ui/src/tooltip/tooltip.stories.tsx new file mode 100644 index 00000000..20673381 --- /dev/null +++ b/packages/ui/src/tooltip/tooltip.stories.tsx @@ -0,0 +1,32 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import type { FC, PropsWithChildren } from 'react'; + +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '.'; + +const component: FC = ({ children }) => ( +
+ + + Trigger Tooltip + +

{children}

+
+
+
+
+); + +export default { + title: 'Design System / Tooltip', + component, + args: { + children: + 'You can invoke the bold styling by clicking on this button or using the CMD + B keyboard shortcut.', + }, +} as Meta; + +type Story = StoryObj; + +export const Default: Story = { + name: 'Tooltip', +}; diff --git a/packages/ui/src/typography/index.tsx b/packages/ui/src/typography/index.tsx new file mode 100644 index 00000000..44e58bb8 --- /dev/null +++ b/packages/ui/src/typography/index.tsx @@ -0,0 +1,92 @@ +import type { FC, PropsWithChildren } from 'react'; + +import { cn } from '../utils/cn'; + +type TypographyProps = { + className?: string; +}; + +const H1: FC> = ({ + children, + className, +}) => { + return ( +

+ {children} +

+ ); +}; + +const H2: FC> = ({ + children, + className, +}) => { + return ( +

+ {children} +

+ ); +}; + +const H3: FC> = ({ + children, + className, +}) => { + return ( +

+ {children} +

+ ); +}; + +const H4: FC> = ({ + children, + className, +}) => { + return ( +

+ {children} +

+ ); +}; + +const P: FC> = ({ children, className }) => { + return ( +

+ {children} +

+ ); +}; + +export const Typography = { + H1, + H2, + H3, + H4, + P, +}; diff --git a/packages/ui/src/typography/typography.h1.spec.tsx b/packages/ui/src/typography/typography.h1.spec.tsx new file mode 100644 index 00000000..4c139aca --- /dev/null +++ b/packages/ui/src/typography/typography.h1.spec.tsx @@ -0,0 +1,29 @@ +import { render, screen } from '@noodle/test-utils/renderer'; + +import { Typography } from '.'; + +describe('Typography H1', () => { + it('should render the children', () => { + render( + + The quick brown fox jumps over the lazy dog. + , + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toBeInTheDocument(); + }); + + it('should render with custom className', () => { + render( + + The quick brown fox jumps over the lazy dog. + , + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toHaveClass('custom-class'); + }); +}); diff --git a/packages/ui/src/typography/typography.h1.stories.tsx b/packages/ui/src/typography/typography.h1.stories.tsx new file mode 100644 index 00000000..61ef781d --- /dev/null +++ b/packages/ui/src/typography/typography.h1.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Typography } from '.'; + +export default { + title: 'Design System / Typography / H1', + component: Typography.H1, + args: { + children: 'The quick brown fox jumps over the lazy dog', + }, +} as Meta; + +type Story = StoryObj; + +export const Default: Story = { + name: 'H1', +}; diff --git a/packages/ui/src/typography/typography.h2.spec.tsx b/packages/ui/src/typography/typography.h2.spec.tsx new file mode 100644 index 00000000..0205c6ea --- /dev/null +++ b/packages/ui/src/typography/typography.h2.spec.tsx @@ -0,0 +1,29 @@ +import { render, screen } from '@noodle/test-utils/renderer'; + +import { Typography } from '.'; + +describe('Typography H2', () => { + it('should render the children', () => { + render( + + The quick brown fox jumps over the lazy dog. + , + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toBeInTheDocument(); + }); + + it('should render with custom className', () => { + render( + + The quick brown fox jumps over the lazy dog. + , + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toHaveClass('custom-class'); + }); +}); diff --git a/packages/ui/src/typography/typography.h2.stories.tsx b/packages/ui/src/typography/typography.h2.stories.tsx new file mode 100644 index 00000000..b6989ae2 --- /dev/null +++ b/packages/ui/src/typography/typography.h2.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Typography } from '.'; + +export default { + title: 'Design System / Typography / H2', + component: Typography.H2, + args: { + children: 'The quick brown fox jumps over the lazy dog', + }, +} as Meta; + +type Story = StoryObj; + +export const Default: Story = { + name: 'H2', +}; diff --git a/packages/ui/src/typography/typography.h3.spec.tsx b/packages/ui/src/typography/typography.h3.spec.tsx new file mode 100644 index 00000000..81c0aff9 --- /dev/null +++ b/packages/ui/src/typography/typography.h3.spec.tsx @@ -0,0 +1,29 @@ +import { render, screen } from '@noodle/test-utils/renderer'; + +import { Typography } from '.'; + +describe('Typography H3', () => { + it('should render the children', () => { + render( + + The quick brown fox jumps over the lazy dog. + , + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toBeInTheDocument(); + }); + + it('should render with custom className', () => { + render( + + The quick brown fox jumps over the lazy dog. + , + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toHaveClass('custom-class'); + }); +}); diff --git a/packages/ui/src/typography/typography.h3.stories.tsx b/packages/ui/src/typography/typography.h3.stories.tsx new file mode 100644 index 00000000..81780976 --- /dev/null +++ b/packages/ui/src/typography/typography.h3.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Typography } from '.'; + +export default { + title: 'Design System / Typography / H3', + component: Typography.H3, + args: { + children: 'The quick brown fox jumps over the lazy dog', + }, +} as Meta; + +type Story = StoryObj; + +export const Default: Story = { + name: 'H3', +}; diff --git a/packages/ui/src/typography/typography.h4.spec.tsx b/packages/ui/src/typography/typography.h4.spec.tsx new file mode 100644 index 00000000..e1bdd761 --- /dev/null +++ b/packages/ui/src/typography/typography.h4.spec.tsx @@ -0,0 +1,29 @@ +import { render, screen } from '@noodle/test-utils/renderer'; + +import { Typography } from '.'; + +describe('Typography H4', () => { + it('should render the children', () => { + render( + + The quick brown fox jumps over the lazy dog. + , + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toBeInTheDocument(); + }); + + it('should render with custom className', () => { + render( + + The quick brown fox jumps over the lazy dog. + , + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toHaveClass('custom-class'); + }); +}); diff --git a/packages/ui/src/typography/typography.h4.stories.tsx b/packages/ui/src/typography/typography.h4.stories.tsx new file mode 100644 index 00000000..b9ad016f --- /dev/null +++ b/packages/ui/src/typography/typography.h4.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Typography } from '.'; + +export default { + title: 'Design System / Typography / H4', + component: Typography.H4, + args: { + children: 'The quick brown fox jumps over the lazy dog', + }, +} as Meta; + +type Story = StoryObj; + +export const Default: Story = { + name: 'H4', +}; diff --git a/packages/ui/src/typography/typography.p.spec.tsx b/packages/ui/src/typography/typography.p.spec.tsx new file mode 100644 index 00000000..88733a98 --- /dev/null +++ b/packages/ui/src/typography/typography.p.spec.tsx @@ -0,0 +1,27 @@ +import { render, screen } from '@noodle/test-utils/renderer'; + +import { Typography } from '.'; + +describe('Typography P', () => { + it('should render the children', () => { + render( + The quick brown fox jumps over the lazy dog., + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toBeInTheDocument(); + }); + + it('should render with custom className', () => { + render( + + The quick brown fox jumps over the lazy dog. + , + ); + + expect( + screen.getByText('The quick brown fox jumps over the lazy dog.'), + ).toHaveClass('custom-class'); + }); +}); diff --git a/packages/ui/src/typography/typography.p.stories.tsx b/packages/ui/src/typography/typography.p.stories.tsx new file mode 100644 index 00000000..82c9f402 --- /dev/null +++ b/packages/ui/src/typography/typography.p.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Typography } from '.'; + +export default { + title: 'Design System / Typography / P', + component: Typography.P, + args: { + children: 'The quick brown fox jumps over the lazy dog', + }, +} as Meta; + +type Story = StoryObj; + +export const Default: Story = { + name: 'P', +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3cef5520..6b5dad9f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -521,6 +521,15 @@ importers: '@fontsource-variable/inter': specifier: ^5.0.5 version: 5.0.5 + '@radix-ui/react-aspect-ratio': + specifier: ^1.0.3 + version: 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-avatar': + specifier: ^1.0.3 + version: 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-tooltip': + specifier: ^1.0.6 + version: 1.0.6(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) clsx: specifier: ^1.2.1 version: 1.2.1 @@ -4163,6 +4172,51 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-aspect-ratio@1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-fXR5kbMan9oQqMuacfzlGG/SQMcmMlZ4wrvpckv8SgUulD0MMpspxJrxg/Gp/ISV3JfV1AeSWTYK9GvxA4ySwA==} + 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/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-avatar@1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-9ToF7YNex3Ste45LrAeTlKtONI9yVRt/zOS158iilIkW5K/Apeyb/TUQlcEFTEFvWr8Kzdi2ZYrm1/suiXPajQ==} + 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/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==} peerDependencies: @@ -4484,6 +4538,38 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-tooltip@1.0.6(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-DmNFOiwEc2UDigsYj6clJENma58OelxD24O4IODoZ+3sQc3Zb+L8w1EP+y9laTuKCLAysPw4fD6/v0j4KNV8rg==} + 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-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-popper': 1.1.2(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.14)(react@18.2.0): resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} peerDependencies: @@ -6224,7 +6310,7 @@ packages: std-env: 3.3.3 test-exclude: 6.0.0 v8-to-istanbul: 9.1.0 - vitest: 0.33.0(@vitest/ui@0.33.0)(happy-dom@10.0.3) + vitest: 0.33.0(less@4.1.3) transitivePeerDependencies: - supports-color dev: true