Skip to content

Commit

Permalink
Feat/165 switch (#171)
Browse files Browse the repository at this point in the history
* feat: base switch

* feat: switch working

* feat: add code into docs

* fix: disabled title

* fix: disabled bg
  • Loading branch information
Ademsk1 authored Nov 22, 2023
1 parent b791efc commit f5110fc
Show file tree
Hide file tree
Showing 6 changed files with 284 additions and 0 deletions.
30 changes: 30 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tooltip": "^1.0.7",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
Expand Down
67 changes: 67 additions & 0 deletions src/components/Switch/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import * as React from 'react'
import * as SwitchPrimitives from '@radix-ui/react-switch'

import { cn } from '@/lib/utils'
import { cva } from 'class-variance-authority'

const switchVariants = cva([
[
'peer',
'inline-flex',
'h-5',
'py-0.5',
'w-10',
'gap-[8px]',
'shrink-0',
'cursor-pointer',
'items-center',
'rounded-full',
'border-none',
'transition-colors ',
'focus-visible:outline-none',
'focus-visible:shadow-blue',
'disabled:cursor-not-allowed'
],
[
'dark:data-[state=checked]:bg-blue-300', //TODO: change to accent/dark when colour changes are made
'dark:bg-foreground-subtle-dark',
'dark:disabled:bg-grey-200'
],
[
'data-[state=checked]:bg-accent',
'data-[state=unchecked]:bg-foreground-subtle',
'data-[disabled]:bg-grey-200'
]
])

const Switch = React.forwardRef<
React.ElementRef<typeof SwitchPrimitives.Root>,
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
>(({ className, ...props }, ref) => (
<SwitchPrimitives.Root
className={cn(switchVariants(), className)}
{...props}
ref={ref}
>
<SwitchPrimitives.Thumb
className={cn([
'pointer-events-none',
'block',
'h-4',
'w-4',
'rounded-full',
'bg-background',
'ring-0',
'transition-transform ',
'data-[state=checked]:translate-x-[22px]',
'data-[state=unchecked]:translate-x-[2px]',
'data-[disabled]:bg-grey-300',
'dark:bg-black',
'dark:data-[disabled]:bg-grey-300'
])}
/>
</SwitchPrimitives.Root>
))
Switch.displayName = SwitchPrimitives.Root.displayName

export { Switch }
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from './components/Table'
export * from './components/ButtonGroup'
export * from './components/Tooltip'
export * from './components/Input'
export * from './components/Switch'
158 changes: 158 additions & 0 deletions stories/Switch/Docs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { Canvas, Meta } from '@storybook/blocks'

import * as SwitchStories from './Switch.stories'

<Meta of={SwitchStories} />

# Switch

A switch is a small, typically toggleable element that allows users to turn a specific setting or feature on or off. It's often represented as a sliding button that visually switches between two states. Switches provide a simple and intuitive way for users to control various options in digital interfaces.

## Default

<Canvas of={SwitchStories.Default} />

## Disabled

<Canvas of={SwitchStories.Disabled} />

## Attributes

<table>
<tbody>
<tr>
<th>Attribute</th>
<th>Type</th>
<th>Default</th>
</tr>
<tr>
<td>defaultChecked</td>
<td>`boolean`</td>
<td>-</td>
</tr>
<tr>
<td>checked</td>
<td>`boolean`</td>
<td>-</td>
</tr>
<tr>
<td>onCheckedChange</td>
<td>`function`</td>
<td>-</td>
</tr>
<tr>
<td>disabled</td>
<td>`boolean`</td>
<td>-</td>
</tr>
<tr>
<td>required</td>
<td>`boolean`</td>
<td>-</td>
</tr>
<tr>
<td>name</td>
<td>`string`</td>
<td>-</td>
</tr>
<tr>
<td>value</td>
<td>`string`</td>
<td>"on"</td>
</tr>
</tbody>
</table>

## Data states

<table>
<tbody>
<tr>
<th>Attribute</th>
<th>Type</th>
<th>Default</th>
</tr>
<tr>
<td>`[data-state]`</td>
<td>`"checked" | "unchecked"`</td>
<td>-</td>
</tr>
<tr>
<td>`[data-disabled]`</td>
<td>Present when disabled</td>
<td>-</td>
</tr>

</tbody>
</table>

## Switch

```tsx
import * as React from 'react'
import * as SwitchPrimitives from '@radix-ui/react-switch'

import { cn } from '@/lib/utils'
import { cva } from 'class-variance-authority'

const switchVariants = cva([
[
'peer',
'inline-flex',
'h-5',
'py-0.5',
'w-10',
'gap-[8px]',
'shrink-0',
'cursor-pointer',
'items-center',
'rounded-full',
'border-none',
'transition-colors ',
'focus-visible:outline-none',
'focus-visible:shadow-blue',
'disabled:cursor-not-allowed'
],
[
'dark:data-[state=checked]:bg-blue-300',
'dark:bg-foreground-subtle-dark',
'dark:disabled:bg-grey-200'
],
[
'data-[state=checked]:bg-accent',
'data-[state=unchecked]:bg-foreground-subtle'
]
])

const Switch = React.forwardRef<
React.ElementRef<typeof SwitchPrimitives.Root>,
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
>(({ className, ...props }, ref) => (
<SwitchPrimitives.Root
className={cn(switchVariants(), className)}
{...props}
ref={ref}
>
<SwitchPrimitives.Thumb
className={cn([
'pointer-events-none',
'block',
'h-4',
'w-4',
'rounded-full',
'bg-background',
'ring-0',
'transition-transform ',
'data-[state=checked]:translate-x-[22px]',
'data-[state=unchecked]:translate-x-[2px]',
'data-[disabled]:bg-grey-300',
'dark:bg-black',
'dark:data-[disabled]:bg-grey-300'
])}
/>
</SwitchPrimitives.Root>
))
Switch.displayName = SwitchPrimitives.Root.displayName

export { Switch }
```
27 changes: 27 additions & 0 deletions stories/Switch/Switch.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Meta, StoryObj } from '@storybook/react'

import { Switch } from '@/index'

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
title: 'Form/Switch',
component: Switch,
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
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
} satisfies Meta<typeof Switch>

export default meta
type Story = StoryObj<typeof meta>

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Default: Story = {}

export const Disabled: Story = {
args: {
disabled: true
}
}

0 comments on commit f5110fc

Please sign in to comment.