Skip to content

Commit

Permalink
Merge pull request #454 from omnifed/449-feat-make-checkbox-component
Browse files Browse the repository at this point in the history
449 feat make checkbox component
  • Loading branch information
caseybaggz committed Sep 6, 2024
2 parents 29d0773 + 062c284 commit 5e1561d
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 191 deletions.
34 changes: 2 additions & 32 deletions docs/app/react/checkbox/components/checkbox-preview.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,8 @@
'use client'

import { Checkmark } from '@cerberus-design/icons'
import { Field, Label, Show } from '@cerberus-design/react'
import { Field, Label, Checkbox } from '@cerberus-design/react'
import { hstack, vstack } from '@cerberus/styled-system/patterns'
import {
checkbox,
type CheckboxVariantProps,
} from '@cerberus/styled-system/recipes'
import {
useCallback,
useState,
type ChangeEvent,
type InputHTMLAttributes,
} from 'react'

type CheckboxProps = CheckboxVariantProps &
Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'id'> & {
id: string
}

function Checkbox(props: CheckboxProps) {
const { size, ...nativeProps } = props
const styles = checkbox({ size })
return (
<div className={styles.root}>
<input {...nativeProps} className={styles.input} type="checkbox" />
<Show when={props.checked}>
<span className={styles.icon}>
<Checkmark />
</span>
</Show>
</div>
)
}
import { useCallback, useState, type ChangeEvent } from 'react'

interface OverviewState {
legal: boolean
Expand Down
113 changes: 113 additions & 0 deletions docs/app/react/checkbox/components/live-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use client'

import CodeBuilder from '@/app/components/code-builder/code-builder'
import { builder } from '@/app/components/code-builder/helpers'
import { useCodeBuilder } from '@/app/context/code-builder'
import { Checkbox, Label, Field, Show } from '@cerberus-design/react'
import { hstack } from '@cerberus/styled-system/patterns'
import { useCallback, useState, type ChangeEvent } from 'react'

const api = {
size: builder.Enum('size', ['md', 'lg']),
text: builder.Text('text', 'Add your label text here'),
id: builder.Text('id', 'add-uuid'),
disabled: builder.Boolean('disabled', false),
invalid: builder.Boolean('invalid', false),
readOnly: builder.Boolean('readOnly', false),
required: builder.Boolean('required', false),
}

export function LivePlayground() {
return (
<CodeBuilder api={api}>
<CheckboxPreview />
</CodeBuilder>
)
}

export function LivePlaygroundWithCode() {
return (
<CodeBuilder
api={api}
code={`import { Field, Label, Checkbox, type CheckboxProps } from '@cerberus-design/react'
import { hstack } from '@cerberus/styled-system/patterns'
export function MyCheckbox(props: CheckboxProps) {
const { describedBy, size, ...nativeProps } = props
const labelSize = size === 'md' ? 'sm' : 'md'
return (
<Field
disabled={{disabled}}
invalid={{invalid}}
readOnly={{readOnly}}
required={{required}}
>
<Label
className={hstack({
justify: 'flex-start',
gap: 0,
})}
htmlFor={{id}}
size={labelSize}
>
<Checkbox
{...nativeProps}
{...(describedBy && { describedBy: describedBy })}
id={{id}}
size={{size}}
/>
{{text}}
</Label>
</Field>
)
}`}
>
<CheckboxPreview />
</CodeBuilder>
)
}

export function CheckboxPreview() {
const { selectedProps } = useCodeBuilder()
const { size, text, id, ...fieldState } = selectedProps
const [checked, setChecked] = useState<boolean>(false)

const handleChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setChecked((prev) => !prev)
}, [])

return (
<Field {...fieldState}>
<Label
className={hstack({
justify: 'flex-start',
})}
htmlFor={id as string}
size={size === 'md' ? 'sm' : 'md'}
>
<Show
when={size === 'md'}
fallback={
<Checkbox
checked={checked}
id={id as string}
name={id as string}
onChange={handleChange}
size="lg"
/>
}
>
<Checkbox
checked={checked}
id={id as string}
name={id as string}
onChange={handleChange}
size="md"
/>
</Show>
{text}
</Label>
</Field>
)
}
116 changes: 0 additions & 116 deletions docs/app/react/checkbox/components/radio-preview.tsx

This file was deleted.

45 changes: 10 additions & 35 deletions docs/app/react/checkbox/dev.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,23 @@ import CodePreview from '@/app/components/CodePreview'
import {
OverviewPreview
} from '@/app/react/checkbox/components/checkbox-preview'
import { LivePlaygroundWithCode } from '@/app/react/checkbox/components/live-preview'

```ts
import { Field, Label, Checkbox } from '@cerberus-design/react'
```

## Usage

<CodePreview preview={<OverviewPreview />} />
<LivePlaygroundWithCode />

## Customizing

<CodePreview preview={<OverviewPreview />}>
```tsx title="custom-radio.tsx"
import { Field, Label, Radio } from '@cerberus-design/react'

function CustomRadioPreview() {
return (
<Field>
<Radio
className={css({
borderColor: 'yellow',
_groupHover: {
bgColor: 'black',
},
_checked: {
bg: 'yellow',
},
})}
id="custom"
name="states"
value="custom"
defaultChecked
>
<Label htmlFor="custom">Wu-Tang</Label>
</Radio>
</Field>
)
}
```
</CodePreview>
To customize the Checkbox we recommend extending the slot recipe provided by the `@cerberus-design/panda-preset` package.

## API

<NoteAdmonition description="The Radio component must be used within a Field provider." />
<NoteAdmonition description="The Checkbox component must be used within a Field provider." />

```ts showLineNumbers=false
export interface FieldProps {
Expand All @@ -66,19 +39,21 @@ define function Field(props: PropsWithChildren<FieldProps>): ReactNode
```

```ts showLineNumbers=false
export interface RadioProps extends InputHTMLAttributes<HTMLInputElement> {
export interface CheckboxProps extends InputHTMLAttributes<HTMLInputElement> {
describedBy?: string
id: string
size?: 'sm' | 'md' | 'lg'
size?: 'md' | 'lg'
}
define function Radio(props: RadioProps): ReactNode
define function Checkbox(props: CheckboxProps): ReactNode
```

### Props

The Radio component accepts the following props:
The Checkbox component accepts the following props:

| Name | Default | Description |
| -------- | ------- | ------------------------------------------------------------- |
| describedBy | | The ID of the FieldMessage element that describes the input field. |
| id | | An identifier that is shared with the Label `htmlFor` attribute. |
| size | `md` | The size of the input field. |
2 changes: 2 additions & 0 deletions docs/app/react/checkbox/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import OverviewList from '@/app/components/OverviewList'
import {
OverviewPreview
} from '@/app/react/checkbox/components/checkbox-preview'
import { LivePlayground } from '@/app/react/checkbox/components/live-preview'

<OverviewList rules={[
'Use checkboxes (instead of switches or radio buttons) if multiple options can be selected from a list',
Expand All @@ -19,6 +20,7 @@ import {
## Example

<CodePreview preview={<OverviewPreview />} />
<LivePlayground />

## Resources

Expand Down
Loading

0 comments on commit 5e1561d

Please sign in to comment.