diff --git a/.changeset/add-checkbox.md b/.changeset/add-checkbox.md new file mode 100644 index 0000000..838ef77 --- /dev/null +++ b/.changeset/add-checkbox.md @@ -0,0 +1,5 @@ +--- +"@destinygg/libstiny": minor +--- + +Add checkbox component and make switch a variant of it. diff --git a/docs/components/checkbox.ts b/docs/components/checkbox.ts new file mode 100644 index 0000000..c845a04 --- /dev/null +++ b/docs/components/checkbox.ts @@ -0,0 +1,11 @@ +import { cva } from "cva"; + +export const checkboxComponent = cva({ + base: "checkbox", + variants: { + type: { + default: "", + switch: "checkbox--switch", + }, + }, +}); diff --git a/docs/stories/checkbox.stories.tsx b/docs/stories/checkbox.stories.tsx new file mode 100644 index 0000000..4c08402 --- /dev/null +++ b/docs/stories/checkbox.stories.tsx @@ -0,0 +1,61 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { checkboxComponent } from "../components/checkbox"; + +type CheckboxArgs = { + type: "default" | "switch"; + label: string; +}; + +const meta: Meta = { + title: "Checkbox", + tags: ["autodocs"], + argTypes: { + type: { + options: ["default", "switch"], + control: { + type: "select", + }, + }, + }, +}; + +export default meta; + +type Story = StoryObj; + +const TickIcon = () => ( + + + +); + +export const Primary: Story = { + render: (args) => ( + + ), + args: { + type: "default", + label: "Toggle me", + }, +}; diff --git a/docs/stories/stepper.stories.tsx b/docs/stories/stepper.stories.tsx index 0f2b626..20f6a7f 100644 --- a/docs/stories/stepper.stories.tsx +++ b/docs/stories/stepper.stories.tsx @@ -22,9 +22,9 @@ const DotIcon = () => ( ); diff --git a/docs/stories/switch.stories.tsx b/docs/stories/switch.stories.tsx deleted file mode 100644 index afa98ef..0000000 --- a/docs/stories/switch.stories.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react"; - -type SwitchArgs = {}; - -const meta: Meta = { - title: "Switch", - tags: ["autodocs"], -}; - -export default meta; - -type Story = StoryObj; - -export const Primary: Story = { - render: () => ( - - ), - args: {}, -}; diff --git a/lib/_docs.scss b/lib/_docs.scss index b17bb01..9bc3ad3 100644 --- a/lib/_docs.scss +++ b/lib/_docs.scss @@ -13,6 +13,7 @@ This file is used in the documentation and shouldn't be consumed directly @use "components/notification" as *; @use "components/input" as *; @use "components/card" as *; +@use "components/checkbox" as *; @use "components/navbar" as *; @use "components/dropdown" as *; @use "components/modal" as *; @@ -22,7 +23,6 @@ This file is used in the documentation and shouldn't be consumed directly @use "components/radio" as *; @use "components/tabs" as *; @use "components/drawer" as *; -@use "components/switch" as *; @use "components/stepper" as *; @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@400;500;600;700&display=swap"); diff --git a/lib/components/switch.scss b/lib/components/checkbox.scss similarity index 51% rename from lib/components/switch.scss rename to lib/components/checkbox.scss index cebc862..1f34708 100644 --- a/lib/components/switch.scss +++ b/lib/components/checkbox.scss @@ -1,72 +1,102 @@ -@use "../tokens/component" as *; -@use "../tokens/core" as *; -@use "../tokens/semantic" as *; -@use "../tokens/shadows" as *; -@use "../tokens/typography" as *; -@use "../utils/transitions" as *; - -.switch { - display: inline-flex; - align-items: center; - cursor: pointer; - - &__toggle { - position: relative; - display: inline-block; - width: $switch-width; - height: $switch-height; - flex-shrink: 0; - } - - input { - appearance: none; - opacity: 0; - - &:checked + .switch__slider { - background-color: $switch-background-active-rest; - - &:hover { - background-color: $switch-background-active-hover; - } - - &::before { - transform: translateX($switch-toggle-size); - } - } - - &:focus-visible + .switch__slider { - outline: 4px auto Highlight; - } - } - - &__slider { - @include create-transition(all, default); - position: absolute; - cursor: pointer; - inset: 0; - background-color: $switch-background-default-rest; - border-radius: $semantic-radii-pill; - - &:hover { - background-color: $switch-background-default-hover; - } - - &::before { - @include create-transition(all, movement); - position: absolute; - content: ""; - height: $switch-toggle-size; - width: $switch-toggle-size; - left: $space-1; - bottom: $space-1; - background-color: $switch-toggle-background; - border-radius: 50%; - } - } - - &__label { - margin-left: $space-3; - cursor: pointer; - font: $body-300-medium; - } -} +@use "../tokens/component" as *; +@use "../tokens/core" as *; +@use "../tokens/semantic" as *; +@use "../tokens/shadows" as *; +@use "../tokens/typography" as *; +@use "../utils/transitions" as *; + +@mixin checkbox--switch { + input { + &:checked + .checkbox__icon::before { + transform: translateX($switch-toggle-size); + } + } + + .checkbox__icon { + background-color: $switch-background-default-rest; + border-radius: $semantic-radii-pill; + border: none; + width: $switch-width; + height: $switch-height; + + &::before { + @include create-transition(all, movement); + position: absolute; + content: ""; + height: $switch-toggle-size; + width: $switch-toggle-size; + left: $space-1; + top: $space-1; + background-color: $switch-toggle-background; + border-radius: 50%; + } + } + + .checkbox__label { + font: $body-300-medium; + } +} + +.checkbox { + display: inline-flex; + align-items: center; + cursor: pointer; + + &--switch { + @include checkbox--switch; + } + + &__toggle { + position: relative; + display: flex; + flex-shrink: 0; + } + + input { + appearance: none; + margin: 0; + + &:checked + .checkbox__icon { + background-color: $switch-background-active-rest; + } + + &:checked + .checkbox__icon .checkbox__tick { + display: block; + } + + &:focus-visible + .checkbox__icon { + outline: 4px auto Highlight; + } + } + + &:hover { + .checkbox__icon { + background-color: $switch-background-default-hover; + } + + input:checked + .checkbox__icon { + background-color: $switch-background-active-hover; + } + } + + &__icon { + @include create-transition(all, default); + background-color: $palette-neutral-2; + border-radius: $semantic-radii-x-small; + border: 1px solid $palette-neutral-7; + width: 20px; + height: 20px; + } + + &__tick { + display: none; + height: 100%; + margin: auto; + } + + &__label { + margin-left: $space-3; + font: $body-200-medium; + user-select: none; + } +} diff --git a/lib/components/index.scss b/lib/components/index.scss index 0a7395f..c33c816 100644 --- a/lib/components/index.scss +++ b/lib/components/index.scss @@ -3,6 +3,7 @@ @forward "notification"; @forward "input"; @forward "card"; +@forward "checkbox"; @forward "navbar"; @forward "dropdown"; @forward "modal"; @@ -12,5 +13,4 @@ @forward "radio"; @forward "tabs"; @forward "drawer"; -@forward "switch"; @forward "stepper";