Skip to content

Commit

Permalink
Merge pull request #294 from omnifed/291-feature-make-toggle-component
Browse files Browse the repository at this point in the history
291 feature make toggle component
  • Loading branch information
caseybaggz committed Jul 19, 2024
2 parents b1fa39d + acc7227 commit ec0aaab
Show file tree
Hide file tree
Showing 21 changed files with 604 additions and 176 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"arrowright",
"caseybaggz",
"cerb",
"Checkmark",
"csstools",
"frontmatter",
"Killa",
Expand Down
5 changes: 3 additions & 2 deletions docs/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { css, cx } from '@cerberus/styled-system/css'
import { Nav } from './components/Nav'

import './globals.css'
import { description, openGraph } from './shared-metadata'

const poppins = Poppins({
display: 'swap',
Expand All @@ -15,8 +16,8 @@ const poppins = Poppins({

export const metadata: Metadata = {
title: 'Cerberus Design System',
description:
'Guarding the brand integrity of the Digital University realm by creating a flexible and extensible design system.',
description,
openGraph,
}

interface RootProps {}
Expand Down
1 change: 1 addition & 0 deletions docs/app/react/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ This is purely for convenience and is not required to use the Cerberus React lib
```tsx title="API"
export interface DefinedIcons {
invalid: CarbonIconType | ElementType
toggleChecked: CarbonIconType | ElementType
}

define function defineIcons(icons: DefinedIcons): DefinedIcons
Expand Down
5 changes: 5 additions & 0 deletions docs/app/react/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ import type { PropsWithChildren } from 'react'
import { PageLayout, PageSideNav } from '../components/PageLayout'
import SideNav, { type NavList } from '../components/SideNav'
import sideNavData from './side-nav.json'
import type { Metadata } from 'next/types'

interface ReactProps {}

export const metadata: Metadata = {
title: 'Cerberus Design System | React',
}

export default function ReactLayout(props: PropsWithChildren<ReactProps>) {
return (
<PageLayout>
Expand Down
7 changes: 7 additions & 0 deletions docs/app/react/side-nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,12 @@
"route": "/react/use-theme-context",
"tag": "",
"type": "route"
},
{
"id": "3:c",
"label": "useToggle",
"route": "/react/use-toggle",
"tag": "next",
"type": "route"
}
]
192 changes: 104 additions & 88 deletions docs/app/react/toggle/components/toggle-preview.tsx
Original file line number Diff line number Diff line change
@@ -1,99 +1,111 @@
'use client'

import { Checkmark } from '@cerberus-design/icons'
import { cx } from '@cerberus/styled-system/css'
import { hstack, vstack } from '@cerberus/styled-system/patterns'
import {
toggle,
type ToggleVariantProps,
} from '@cerberus/styled-system/recipes'
import { on } from 'events'
import {
useCallback,
useMemo,
useState,
type ChangeEvent,
type InputHTMLAttributes,
type MouseEvent,
} from 'react'

function useToggle(options: {
checked?: string
onChange?: (e: ChangeEvent<HTMLInputElement>) => void
}) {
const { onChange } = options
const [checked, setChecked] = useState<string>(options.checked ?? '')
Field,
FieldMessage,
Label,
Toggle,
useToggle,
} from '@cerberus-design/react'
import { hstack, vstack } from '@cerberus/styled-system/patterns'

const handleChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
const target = e.currentTarget as HTMLInputElement
setChecked((prev) => {
return prev === target.value ? '' : target.value
})
onChange?.(e)
},
[onChange],
export function DefaultTogglePreview() {
const { checked, handleChange } = useToggle({ checked: 'default' })
return (
<Field>
<Toggle
checked={checked === 'default'}
id="default"
onChange={handleChange}
value="default"
/>
</Field>
)

return useMemo(() => ({ checked, handleChange }), [checked, handleChange])
}

type ToggleBase = Omit<InputHTMLAttributes<HTMLInputElement>, 'size'>
type ToggleProps = ToggleBase & ToggleVariantProps

function Toggle(props: ToggleProps) {
const { size, ...nativeProps } = props
const styles = toggle({ size })

export function DisabledTogglePreview() {
const { checked, handleChange } = useToggle()
return (
<span
className={cx('group', styles.track, hstack())}
data-checked={props.checked || props.defaultChecked}
>
<input
{...nativeProps}
aria-label="Toggle"
className={cx('peer', styles.input)}
role="switch"
type="checkbox"
<Field disabled>
<Toggle
checked={checked === 'default'}
id="default"
onChange={handleChange}
value="default"
/>
<span
className={cx(
styles.thumb,
vstack({
justify: 'center',
}),
)}
</Field>
)
}

export function WithMessageTogglePreview() {
const { checked, handleChange } = useToggle()
return (
<Field>
<div
className={vstack({
alignItems: 'flex-start',
})}
>
<Checkmark />
</span>
</span>
<Label htmlFor="default">User Settings</Label>
<div className={hstack()}>
<Toggle
describedBy="help:default"
checked={checked === 'default'}
id="default"
onChange={handleChange}
value="default"
/>
<FieldMessage id="help:default">Show notifications</FieldMessage>
</div>
</div>
</Field>
)
}

export function WithLabelTogglePreview() {
const { checked, handleChange } = useToggle()
return (
<Field>
<div className={hstack()}>
<Toggle
describedBy="help:default"
checked={checked === 'default'}
id="default"
onChange={handleChange}
value="default"
/>
<Label htmlFor="default">Show notifications</Label>
</div>
</Field>
)
}

export function OverviewToggleGroup() {
const { checked, handleChange } = useToggle({ checked: 'lg-one' })

return (
<div
className={hstack({
gap: 4,
})}
>
<Toggle
checked={checked === 'lg-one'}
id="lg-one"
size="lg"
onChange={handleChange}
value="lg-one"
/>
<Toggle
checked={checked === 'lg-two'}
id="lg-two"
size="lg"
onChange={handleChange}
value="lg-two"
/>
<Field>
<Toggle
checked={checked === 'lg-one'}
id="lg-one"
size="lg"
onChange={handleChange}
value="lg-one"
/>
</Field>
<Field>
<Toggle
checked={checked === 'lg-two'}
id="lg-two"
size="lg"
onChange={handleChange}
value="lg-two"
/>
</Field>
</div>
)
}
Expand All @@ -107,19 +119,23 @@ export function OverviewToggleSizes() {
gap: 4,
})}
>
<Toggle
checked={checked === 'sm-t'}
id="sm-t"
onChange={handleChange}
value="sm-t"
/>
<Toggle
checked={checked === 'lg-t'}
id="lg-t"
onChange={handleChange}
size="lg"
value="lg-t"
/>
<Field>
<Toggle
checked={checked === 'sm-t'}
id="sm-t"
onChange={handleChange}
value="sm-t"
/>
</Field>
<Field>
<Toggle
checked={checked === 'lg-t'}
id="lg-t"
onChange={handleChange}
size="lg"
value="lg-t"
/>
</Field>
</div>
)
}
Loading

0 comments on commit ec0aaab

Please sign in to comment.