diff --git a/src/components/atoms/HeadlessCheckbox/index.store.tsx b/src/components/atoms/HeadlessCheckbox/index.store.tsx new file mode 100644 index 0000000..0fe89a7 --- /dev/null +++ b/src/components/atoms/HeadlessCheckbox/index.store.tsx @@ -0,0 +1,13 @@ +import { HeadlessCheckboxProps } from "@/components/atoms/HeadlessCheckbox"; +import { createContext, useContext } from "react"; + +export const useCheckboxContext = () => { + const context = useContext(CheckboxContext); + return context; +}; + +export const CheckboxContext = createContext({ + id: "", + isChecked: false, + onChange: () => {}, +}); diff --git a/src/components/atoms/HeadlessCheckbox/index.stories.tsx b/src/components/atoms/HeadlessCheckbox/index.stories.tsx new file mode 100644 index 0000000..dab6076 --- /dev/null +++ b/src/components/atoms/HeadlessCheckbox/index.stories.tsx @@ -0,0 +1,40 @@ +/* eslint-disable react-hooks/rules-of-hooks */ +/* eslint-disable storybook/prefer-pascal-case */ +import type { Meta, StoryObj } from "@storybook/react"; +import { HeadlessCheckbox } from "."; + +const meta: Meta = { + title: "atoms/HeadlessCheckbox", + component: HeadlessCheckbox, + parameters: { + // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout + layout: "centered", + }, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs + tags: ["autodocs"], + argTypes: { + isChecked: { + control: { + type: "boolean", + default: false, + description: "isChecked", + }, + }, + onChange: { action: "changed" }, + }, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + render: (args) => { + return ( + + + Checkbox + + ); + }, +}; diff --git a/src/components/atoms/HeadlessCheckbox/index.tsx b/src/components/atoms/HeadlessCheckbox/index.tsx new file mode 100644 index 0000000..ca26c53 --- /dev/null +++ b/src/components/atoms/HeadlessCheckbox/index.tsx @@ -0,0 +1,64 @@ +import { + CheckboxContext, + useCheckboxContext, +} from "@/components/atoms/HeadlessCheckbox/index.store"; +import { HTMLInputProps } from "@/components/atoms/Input"; +import { HTMLLabelProps } from "@/components/atoms/Label"; +import { PropsWithChildren } from "react"; + +export type HeadlessCheckboxContextProps = { + id: string; + isChecked: boolean; + onChange: () => void; +}; + +export type HeadlessCheckboxProps = + PropsWithChildren; + +const HeadlessCheckboxWrapper = ({ + id, + isChecked, + onChange, + children, +}: HeadlessCheckboxProps) => { + const value = { + id, + isChecked, + onChange, + }; + return ( + + {children} + + ); +}; + +const Checkbox = ({ ...props }: HTMLInputProps) => { + const { id, isChecked, onChange } = useCheckboxContext(); + return ( + + ); +}; + +const Label = ({ children, ...props }: PropsWithChildren) => { + const { id } = useCheckboxContext(); + return ( + + ); +}; + +HeadlessCheckboxWrapper.Checkbox = Checkbox; +HeadlessCheckboxWrapper.Label = Label; + +export const HeadlessCheckbox = Object.assign(HeadlessCheckboxWrapper, { + Checkbox, + Label, +});