mirror of https://github.com/acid-info/lsd.git
feat: implement checkbox group component
This commit is contained in:
parent
8835bbbc7c
commit
5063763727
|
@ -8,6 +8,7 @@ import { CardStyles } from '../Card/Card.styles'
|
||||||
import { CardBodyStyles } from '../CardBody/CardBody.styles'
|
import { CardBodyStyles } from '../CardBody/CardBody.styles'
|
||||||
import { CardHeaderStyles } from '../CardHeader/CardHeader.styles'
|
import { CardHeaderStyles } from '../CardHeader/CardHeader.styles'
|
||||||
import { CheckboxStyles } from '../Checkbox/Checkbox.styles'
|
import { CheckboxStyles } from '../Checkbox/Checkbox.styles'
|
||||||
|
import { CheckboxGroupStyles } from '../CheckboxGroup/CheckboxGroup.styles'
|
||||||
import { CollapseStyles } from '../Collapse/Collapse.styles'
|
import { CollapseStyles } from '../Collapse/Collapse.styles'
|
||||||
import { CollapseHeaderStyles } from '../CollapseHeader/CollapseHeader.styles'
|
import { CollapseHeaderStyles } from '../CollapseHeader/CollapseHeader.styles'
|
||||||
import { DropdownStyles } from '../Dropdown/Dropdown.styles'
|
import { DropdownStyles } from '../Dropdown/Dropdown.styles'
|
||||||
|
@ -16,8 +17,6 @@ import { IconButtonStyles } from '../IconButton/IconButton.styles'
|
||||||
import { LsdIconStyles } from '../Icons/LsdIcon/LsdIcon.styles'
|
import { LsdIconStyles } from '../Icons/LsdIcon/LsdIcon.styles'
|
||||||
import { ListBoxStyles } from '../ListBox/ListBox.styles'
|
import { ListBoxStyles } from '../ListBox/ListBox.styles'
|
||||||
import { QuoteStyles } from '../Quote/Quote.styles'
|
import { QuoteStyles } from '../Quote/Quote.styles'
|
||||||
import { RadioButtonStyles } from '../RadioButton/RadioButton.styles'
|
|
||||||
import { RadioButtonGroupStyles } from '../RadioButtonGroup/RadioButtonGroup.styles'
|
|
||||||
import { TabItemStyles } from '../TabItem/TabItem.styles'
|
import { TabItemStyles } from '../TabItem/TabItem.styles'
|
||||||
import { TabsStyles } from '../Tabs/Tabs.styles'
|
import { TabsStyles } from '../Tabs/Tabs.styles'
|
||||||
import { TagStyles } from '../Tag/Tag.styles'
|
import { TagStyles } from '../Tag/Tag.styles'
|
||||||
|
@ -48,8 +47,7 @@ const componentStyles: Array<ReturnType<typeof withTheme> | SerializedStyles> =
|
||||||
QuoteStyles,
|
QuoteStyles,
|
||||||
CollapseStyles,
|
CollapseStyles,
|
||||||
CollapseHeaderStyles,
|
CollapseHeaderStyles,
|
||||||
RadioButtonStyles,
|
CheckboxGroupStyles,
|
||||||
RadioButtonGroupStyles,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export const CSSBaseline: React.FC<{ theme?: Theme }> = ({
|
export const CSSBaseline: React.FC<{ theme?: Theme }> = ({
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import React, { useEffect, useRef, useState } from 'react'
|
import React, { useEffect, useRef, useState } from 'react'
|
||||||
import { useInput } from '../../utils/useInput'
|
import { useInput } from '../../utils/useInput'
|
||||||
|
import { useCheckboxGroupContext } from '../CheckboxGroup/CheckboxGroup.context'
|
||||||
import { CheckboxFilledIcon, CheckboxIcon } from '../Icons'
|
import { CheckboxFilledIcon, CheckboxIcon } from '../Icons'
|
||||||
import { CheckboxIndeterminateIcon } from '../Icons/CheckboxIndeterminate'
|
import { CheckboxIndeterminateIcon } from '../Icons/CheckboxIndeterminate'
|
||||||
import { Typography } from '../Typography'
|
import { Typography } from '../Typography'
|
||||||
|
@ -24,7 +25,7 @@ export const Checkbox: React.FC<CheckboxProps> & {
|
||||||
classes: typeof checkboxClasses
|
classes: typeof checkboxClasses
|
||||||
} = ({
|
} = ({
|
||||||
name,
|
name,
|
||||||
size = 'large',
|
size: _size = 'large',
|
||||||
onChange,
|
onChange,
|
||||||
checked,
|
checked,
|
||||||
defaultChecked,
|
defaultChecked,
|
||||||
|
@ -43,6 +44,9 @@ export const Checkbox: React.FC<CheckboxProps> & {
|
||||||
ref,
|
ref,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const checkboxGroup = useCheckboxGroupContext()
|
||||||
|
const size = checkboxGroup?.size ?? _size
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ref.current) return
|
if (!ref.current) return
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
export const checkboxGroupClasses = {
|
||||||
|
root: `lsd-checkbox-group`,
|
||||||
|
label: `lsd-checkbox-group__label`,
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { ActiveCheckboxType, CheckboxGroupProps } from './CheckboxGroup'
|
||||||
|
|
||||||
|
export type CheckboxGroupContextType = {
|
||||||
|
activeCheckbox?: ActiveCheckboxType | null
|
||||||
|
setActiveCheckbox: (value: ActiveCheckboxType) => void
|
||||||
|
|
||||||
|
size?: CheckboxGroupProps['size']
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CheckboxGroupContext =
|
||||||
|
React.createContext<CheckboxGroupContextType>(null as any)
|
||||||
|
|
||||||
|
export const useCheckboxGroupContext = () =>
|
||||||
|
React.useContext(CheckboxGroupContext)
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { Meta, Story } from '@storybook/react'
|
||||||
|
import { Checkbox } from '../Checkbox'
|
||||||
|
import { CheckboxGroup, CheckboxGroupProps } from './CheckboxGroup'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'CheckboxGroup',
|
||||||
|
component: CheckboxGroup,
|
||||||
|
argTypes: {
|
||||||
|
size: {
|
||||||
|
type: {
|
||||||
|
name: 'enum',
|
||||||
|
value: ['small', 'medium', 'large'],
|
||||||
|
},
|
||||||
|
defaultValue: 'large',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as Meta
|
||||||
|
|
||||||
|
export const Root: Story<CheckboxGroupProps> = (args) => (
|
||||||
|
<CheckboxGroup {...args}>
|
||||||
|
<Checkbox>Checkbox label</Checkbox>
|
||||||
|
<Checkbox>Checkbox label</Checkbox>
|
||||||
|
<Checkbox>Checkbox label</Checkbox>
|
||||||
|
<Checkbox>Checkbox label</Checkbox>
|
||||||
|
<Checkbox>Checkbox label</Checkbox>
|
||||||
|
<Checkbox>Checkbox label</Checkbox>
|
||||||
|
<Checkbox>Checkbox label</Checkbox>
|
||||||
|
<Checkbox>Checkbox label</Checkbox>
|
||||||
|
</CheckboxGroup>
|
||||||
|
)
|
||||||
|
|
||||||
|
Root.args = {
|
||||||
|
size: 'large',
|
||||||
|
label: 'Label',
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { css } from '@emotion/react'
|
||||||
|
import { checkboxGroupClasses } from './CheckboxGroup.classes'
|
||||||
|
|
||||||
|
export const CheckboxGroupStyles = css`
|
||||||
|
.${checkboxGroupClasses.root} {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.${checkboxGroupClasses.label} {
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
`
|
|
@ -0,0 +1,49 @@
|
||||||
|
import clsx from 'clsx'
|
||||||
|
import React, { useEffect, useRef, useState } from 'react'
|
||||||
|
import { CheckboxGroupContext } from './CheckboxGroup.context'
|
||||||
|
import { checkboxGroupClasses } from './CheckboxGroup.classes'
|
||||||
|
import { Typography } from '../Typography'
|
||||||
|
|
||||||
|
export type ActiveCheckboxType = string | number | readonly string[]
|
||||||
|
|
||||||
|
export type CheckboxGroupProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||||
|
activeCheckbox?: ActiveCheckboxType | null
|
||||||
|
size?: 'small' | 'medium' | 'large'
|
||||||
|
label?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CheckboxGroup: React.FC<CheckboxGroupProps> & {
|
||||||
|
classes: typeof checkboxGroupClasses
|
||||||
|
} = ({ size = 'large', label, activeCheckbox, children, ...props }) => {
|
||||||
|
const ref = useRef<HTMLDivElement>(null)
|
||||||
|
const [value, setValue] = useState(activeCheckbox)
|
||||||
|
|
||||||
|
const setActiveCheckbox = (radioButton: ActiveCheckboxType) => {
|
||||||
|
setValue(radioButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => setValue(activeCheckbox), [activeCheckbox])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CheckboxGroupContext.Provider
|
||||||
|
value={{ activeCheckbox: value, setActiveCheckbox, size }}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
className={clsx(props.className, checkboxGroupClasses.root)}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
component="span"
|
||||||
|
variant={size === 'small' ? 'label2' : 'label1'}
|
||||||
|
className={checkboxGroupClasses.label}
|
||||||
|
>
|
||||||
|
{label && label}
|
||||||
|
</Typography>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</CheckboxGroupContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckboxGroup.classes = checkboxGroupClasses
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './CheckboxGroup'
|
|
@ -18,5 +18,5 @@ export * from './components/TabItem'
|
||||||
export * from './components/Tabs'
|
export * from './components/Tabs'
|
||||||
export * from './components/Tag'
|
export * from './components/Tag'
|
||||||
export * from './components/Theme'
|
export * from './components/Theme'
|
||||||
export * from './components/RadioButton'
|
export * from './components/Checkbox'
|
||||||
export * from './components/RadioButtonGroup'
|
export * from './components/CheckboxGroup'
|
||||||
|
|
Loading…
Reference in New Issue