diff --git a/package.json b/package.json index c5e0d7ed..cb8e7a4b 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-popover": "^1.0.7", + "@radix-ui/react-toggle-group": "^1.0.4", "@supabase/supabase-js": "^2.39.8", "@t3-oss/env-nextjs": "^0.9.2", "@tanstack/react-query": "^5.25.0", diff --git a/src/common/components/ToggleGroup/ToggleGroup.stories.tsx b/src/common/components/ToggleGroup/ToggleGroup.stories.tsx new file mode 100644 index 00000000..f224c1d0 --- /dev/null +++ b/src/common/components/ToggleGroup/ToggleGroup.stories.tsx @@ -0,0 +1,63 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import { ToggleGroup } from "./ToggleGroup"; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export +const meta = { + title: "Common/ToggleGroup", + component: ToggleGroup, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs + tags: ["autodocs"], + args: { + type: "single", + size: "md", + disabled: false, + }, + // More on argTypes: https://storybook.js.org/docs/api/argtypes +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: (args) => { + console.log(args); + return ( + + + Down + + + Check + + + Lock + + + ); + }, +}; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Multiple: Story = { + ...Default, + args: { + type: "multiple", + }, +}; + +export const Small: Story = { + ...Default, + args: { + ...Default.args, + size: "sm", + }, +}; + +export const Disabled: Story = { + ...Default, + args: { + ...Default.args, + disabled: true, + }, +}; diff --git a/src/common/components/ToggleGroup/ToggleGroup.theme.ts b/src/common/components/ToggleGroup/ToggleGroup.theme.ts new file mode 100644 index 00000000..1832773e --- /dev/null +++ b/src/common/components/ToggleGroup/ToggleGroup.theme.ts @@ -0,0 +1,41 @@ +import { tv, type VariantProps } from "tailwind-variants"; + +export const toggleGroupTheme = tv({ + slots: { + root: [ + "inline-flex", + "items-start", + "rounded-lg", + "border", + "border-solid", + "text-border-default", + "overflow-hidden", + ], + item: [ + "inline-flex", + "items-center", + "justify-center", + "py-2", + "px-5", + "flex-shrink-0", + "transition-colors", + "bg-surface-base", + "text-text-em-high", + "focus-ring", + "hover:bg-bg-alt", + "data-[state=on]:bg-primary-default", + "data-[state=on]:text-text-on-primary", + ], + }, + variants: { + size: { + sm: { + item: ["h-8", "text-sm"], + }, + md: { + item: ["h-10", "text-base"], + }, + }, + }, +}); +export type ToggleGroupVariants = VariantProps; diff --git a/src/common/components/ToggleGroup/ToggleGroup.tsx b/src/common/components/ToggleGroup/ToggleGroup.tsx new file mode 100644 index 00000000..407bd954 --- /dev/null +++ b/src/common/components/ToggleGroup/ToggleGroup.tsx @@ -0,0 +1,56 @@ +"use client"; + +import * as React from "react"; +import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"; + +import { + toggleGroupTheme, + type ToggleGroupVariants, +} from "./ToggleGroup.theme"; + +const ToggleGroupContext = React.createContext({ + size: "md", +}); + +const ToggleGroupRoot = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + ToggleGroupVariants +>(({ className, size = "md", children, ...props }, ref) => { + const { root } = toggleGroupTheme(); + return ( + + + {children} + + + ); +}); +ToggleGroupRoot.displayName = ToggleGroupPrimitive.Root.displayName; + +const ToggleGroupItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + ToggleGroupVariants +>(({ className, children, size = "md", ...props }, ref) => { + const context = React.useContext(ToggleGroupContext); + const { item } = toggleGroupTheme(); + return ( + + {children} + + ); +}); +ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName; + +export const ToggleGroup = Object.assign({}, ToggleGroupRoot, { + Item: ToggleGroupItem, +}); diff --git a/src/common/components/ToggleGroup/index.ts b/src/common/components/ToggleGroup/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/yarn.lock b/yarn.lock index 34edbd50..c3859752 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1823,6 +1823,30 @@ "@babel/runtime" "^7.13.10" "@radix-ui/react-compose-refs" "1.0.1" +"@radix-ui/react-toggle-group@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz#f5b5c8c477831b013bec3580c55e20a68179d6ec" + integrity sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-roving-focus" "1.0.4" + "@radix-ui/react-toggle" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + +"@radix-ui/react-toggle@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz#aecb2945630d1dc5c512997556c57aba894e539e" + integrity sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-use-callback-ref@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a"