This repository has been archived by the owner on Feb 10, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: refactored Switch and Checkbox from shadcn (#116)
- Loading branch information
Showing
10 changed files
with
333 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { Checkbox } from "./Checkbox"; | ||
|
||
const meta: Meta<typeof Checkbox> = { | ||
title: "Primitives/Checkbox", | ||
component: Checkbox, | ||
tags: ["autodocs"], | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof Checkbox>; | ||
|
||
// Small Checkboxes Story | ||
export const SmallCheckboxes: Story = { | ||
render: () => ( | ||
<div className="flex items-center gap-4"> | ||
<Checkbox size="sm" color="moss" defaultChecked /> | ||
<Checkbox size="sm" color="black" defaultChecked /> | ||
<Checkbox size="sm" color="white" defaultChecked /> | ||
<Checkbox size="sm" color="purple" defaultChecked /> | ||
</div> | ||
), | ||
}; | ||
|
||
// Medium Checkboxes Story | ||
export const MediumCheckboxes: Story = { | ||
render: () => ( | ||
<div className="flex items-center gap-4"> | ||
<Checkbox size="md" color="moss" defaultChecked /> | ||
<Checkbox size="md" color="black" defaultChecked /> | ||
<Checkbox size="md" color="white" defaultChecked /> | ||
<Checkbox size="md" color="purple" defaultChecked /> | ||
</div> | ||
), | ||
}; | ||
|
||
// Large Checkboxes Story | ||
export const LargeCheckboxes: Story = { | ||
render: () => ( | ||
<div className="flex items-center gap-4"> | ||
<Checkbox size="lg" color="moss" defaultChecked /> | ||
<Checkbox size="lg" color="black" defaultChecked /> | ||
<Checkbox size="lg" color="white" defaultChecked /> | ||
<Checkbox size="lg" color="purple" defaultChecked /> | ||
</div> | ||
), | ||
}; | ||
|
||
// Interactive Checkbox Story with Controls | ||
export const Interactive: Story = { | ||
args: { | ||
size: "md", | ||
color: "moss", | ||
defaultChecked: true, | ||
}, | ||
argTypes: { | ||
size: { | ||
control: "select", | ||
options: ["sm", "md", "lg"], | ||
}, | ||
color: { | ||
control: "select", | ||
options: ["moss", "black", "white", "purple"], | ||
}, | ||
defaultChecked: { | ||
control: "boolean", | ||
}, | ||
}, | ||
}; | ||
|
||
// States Story | ||
export const States: Story = { | ||
render: () => ( | ||
<div className="flex flex-col gap-4"> | ||
<div className="flex items-center gap-4"> | ||
<Checkbox color="moss" /> | ||
<span className="text-sm">Unchecked</span> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Checkbox color="moss" defaultChecked /> | ||
<span className="text-sm">Checked</span> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Checkbox color="moss" disabled /> | ||
<span className="text-sm">Disabled Unchecked</span> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Checkbox color="moss" disabled defaultChecked /> | ||
<span className="text-sm">Disabled Checked</span> | ||
</div> | ||
</div> | ||
), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
"use client"; | ||
|
||
import * as React from "react"; | ||
|
||
import { CheckIcon } from "@heroicons/react/solid"; | ||
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; | ||
import { tv, VariantProps } from "tailwind-variants"; | ||
|
||
import { cn } from "@/lib/utils"; | ||
|
||
const checkboxVariants = tv({ | ||
slots: { | ||
base: "peer size-4 rounded-sm border border-moss-300 text-center ring-offset-white hover:border-moss-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-moss-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-moss-500 data-[state=checked]:text-grey-50", | ||
}, | ||
variants: { | ||
size: { | ||
sm: { | ||
base: "size-4", | ||
}, | ||
md: { | ||
base: "size-5", | ||
}, | ||
lg: { | ||
base: "size-6", | ||
}, | ||
}, | ||
color: { | ||
moss: { | ||
base: "border-moss-700 hover:border-moss-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-moss-900 focus-visible:ring-offset-2 data-[state=checked]:bg-moss-700 data-[state=unchecked]:bg-transparent data-[state=checked]:text-white data-[state=unchecked]:text-white", | ||
}, | ||
black: { | ||
base: "border-grey-300 hover:border-grey-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-grey-500 focus-visible:ring-offset-2 data-[state=checked]:bg-black data-[state=unchecked]:bg-transparent data-[state=checked]:text-grey-50 data-[state=unchecked]:text-grey-50", | ||
}, | ||
white: { | ||
base: "border-black hover:border-black focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2 data-[state=checked]:bg-white data-[state=unchecked]:bg-transparent data-[state=checked]:text-black data-[state=unchecked]:text-black dark:border-grey-50 dark:hover:border-grey-200 dark:focus-visible:ring-grey-200 dark:data-[state=checked]:bg-grey-50 dark:data-[state=checked]:text-black dark:data-[state=unchecked]:text-grey-50", | ||
}, | ||
purple: { | ||
base: "border-purple-700 hover:border-purple-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-purple-900 focus-visible:ring-offset-2 data-[state=checked]:bg-purple-700 data-[state=unchecked]:bg-transparent data-[state=checked]:text-grey-50 data-[state=unchecked]:text-white", | ||
}, | ||
}, | ||
}, | ||
defaultVariants: { | ||
size: "sm", | ||
color: "moss", | ||
}, | ||
}); | ||
|
||
export type CheckboxVariants = VariantProps<typeof checkboxVariants>; | ||
|
||
const Checkbox = React.forwardRef< | ||
React.ElementRef<typeof CheckboxPrimitive.Root>, | ||
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> & CheckboxVariants | ||
>(({ className, ...props }, ref) => { | ||
const { size, color, ...rest } = props; | ||
const { base } = checkboxVariants({ size, color }); | ||
|
||
return ( | ||
<CheckboxPrimitive.Root ref={ref} className={cn(base(), className)} {...rest}> | ||
<CheckboxPrimitive.Indicator> | ||
<CheckIcon /> | ||
</CheckboxPrimitive.Indicator> | ||
</CheckboxPrimitive.Root> | ||
); | ||
}); | ||
|
||
Checkbox.displayName = CheckboxPrimitive.Root.displayName; | ||
|
||
export { Checkbox }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { Checkbox } from "./Checkbox"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import { Switch } from "./Switch"; | ||
|
||
const meta: Meta<typeof Switch> = { | ||
title: "Primitives/Switch", | ||
component: Switch, | ||
tags: ["autodocs"], | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof Switch>; | ||
|
||
// Color Variants Story | ||
export const ColorVariants: Story = { | ||
render: () => ( | ||
<div className="flex flex-col gap-4"> | ||
<div className="flex items-center gap-4"> | ||
<Switch color="moss" defaultChecked /> | ||
<span className="text-sm">Moss</span> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Switch color="black" defaultChecked /> | ||
<span className="text-sm">Black</span> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Switch color="purple" defaultChecked /> | ||
<span className="text-sm">Purple</span> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Switch color="white" defaultChecked /> | ||
<span className="text-sm">White</span> | ||
</div> | ||
</div> | ||
), | ||
}; | ||
|
||
// States Story | ||
export const States: Story = { | ||
render: () => ( | ||
<div className="flex flex-col gap-4"> | ||
<div className="flex items-center gap-4"> | ||
<Switch color="moss" /> | ||
<span className="text-sm">Unchecked</span> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Switch color="moss" defaultChecked /> | ||
<span className="text-sm">Checked</span> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Switch color="moss" disabled /> | ||
<span className="text-sm">Disabled Unchecked</span> | ||
</div> | ||
<div className="flex items-center gap-4"> | ||
<Switch color="moss" disabled defaultChecked /> | ||
<span className="text-sm">Disabled Checked</span> | ||
</div> | ||
</div> | ||
), | ||
}; | ||
|
||
// Interactive Story with Controls | ||
export const Interactive: Story = { | ||
args: { | ||
color: "moss", | ||
defaultChecked: true, | ||
disabled: false, | ||
}, | ||
argTypes: { | ||
color: { | ||
control: "select", | ||
options: ["moss", "black", "purple", "white"], | ||
}, | ||
defaultChecked: { | ||
control: "boolean", | ||
}, | ||
disabled: { | ||
control: "boolean", | ||
}, | ||
}, | ||
}; | ||
|
||
// Group Story | ||
export const Group: Story = { | ||
render: () => ( | ||
<div className="space-y-8"> | ||
<div className="flex items-center justify-between"> | ||
<label htmlFor="airplane-mode" className="text-sm font-medium"> | ||
Airplane Mode | ||
</label> | ||
<Switch id="airplane-mode" color="moss" /> | ||
</div> | ||
<div className="flex items-center justify-between"> | ||
<label htmlFor="wifi" className="text-sm font-medium"> | ||
Wi-Fi | ||
</label> | ||
<Switch id="wifi" color="purple" defaultChecked /> | ||
</div> | ||
<div className="flex items-center justify-between"> | ||
<label htmlFor="notifications" className="text-sm font-medium"> | ||
Notifications | ||
</label> | ||
<Switch id="notifications" color="black" defaultChecked /> | ||
</div> | ||
</div> | ||
), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
"use client"; | ||
|
||
import * as React from "react"; | ||
|
||
import * as SwitchPrimitives from "@radix-ui/react-switch"; | ||
import { tv, VariantProps } from "tailwind-variants"; | ||
|
||
import { cn } from "@/lib/utils"; | ||
|
||
const switchVariants = tv({ | ||
slots: { | ||
base: "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-moss-700 data-[state=unchecked]:bg-grey-100", | ||
thumb: | ||
"pointer-events-none block h-5 w-5 rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0", | ||
}, | ||
variants: { | ||
color: { | ||
moss: { | ||
base: "data-[state=checked]:bg-moss-700 data-[state=unchecked]:bg-grey-100", | ||
thumb: "bg-white", | ||
}, | ||
black: { | ||
base: "data-[state=checked]:bg-black data-[state=unchecked]:bg-grey-100", | ||
thumb: "bg-white", | ||
}, | ||
purple: { | ||
base: "data-[state=checked]:bg-purple-700 data-[state=unchecked]:bg-grey-100", | ||
thumb: "bg-white", | ||
}, | ||
white: { | ||
base: "data-[state=checked]:bg-white data-[state=unchecked]:bg-grey-100", | ||
thumb: "bg-black", | ||
}, | ||
}, | ||
}, | ||
defaultVariants: { | ||
color: "moss", | ||
}, | ||
}); | ||
|
||
type SwitchVariants = VariantProps<typeof switchVariants>; | ||
|
||
const Switch = React.forwardRef< | ||
React.ElementRef<typeof SwitchPrimitives.Root>, | ||
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> & SwitchVariants | ||
>(({ className, ...props }, ref) => { | ||
const { color, ...rest } = props; | ||
const { base, thumb } = switchVariants({ color }); | ||
|
||
return ( | ||
<SwitchPrimitives.Root className={cn(base(), className)} {...rest} ref={ref}> | ||
<SwitchPrimitives.Thumb className={thumb()} /> | ||
</SwitchPrimitives.Root> | ||
); | ||
}); | ||
|
||
Switch.displayName = SwitchPrimitives.Root.displayName; | ||
|
||
export { Switch }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { Switch } from "./Switch"; |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.