/
kaws
/
ui-kit-ce
Обзор
Документация
Войти
/
kaws
/
ui-kit-ce
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
packages/label-control/src/LabelControl.tsx
217 строк
6 KB
Строганов Федор
feat(label-control,radio,radio-group): добавлена возможность использования number и boolean
25 мар 2025, 13:54
25 мар 2025, 13:54
41543ad
Код
Авторство
О чём код?
'use client' import * as React from 'react' import { createUseStyles, clsx } from '@v-uik/theme' import { useClassList } from '@v-uik/hooks' import { ElementSize, ElementSizeType, ComponentPropsWithRefFix, ComponentPropsWithAttributes, } from '@v-uik/common' import { Classes } from './classes' const useStyles = createUseStyles((theme) => ({ label: { position: 'relative', display: 'inline-flex', alignItems: 'center', cursor: 'pointer', verticalAlign: 'middle', }, end: { flexDirection: 'row-reverse', '& $labelContent': { marginLeft: 8, }, }, top: { flexDirection: 'column', '& $labelContent': { marginBottom: 4, }, }, bottom: { flexDirection: 'column-reverse', '& $labelContent': { marginTop: 4, }, }, start: { flexDirection: 'row', '& $labelContent': { marginRight: 8, }, }, disabled: { cursor: 'default', pointerEvents: 'none', '& $labelContent': { color: theme.comp.labelControl.colorTextDisabled, }, }, labelContent: { color: theme.comp.labelControl.colorText, fontFamily: theme.comp.labelControl.typographyFontFamilyMd, fontWeight: theme.comp.labelControl.typographyFontWeightMd, fontSize: theme.comp.labelControl.typographyFontSizeMd, lineHeight: theme.comp.labelControl.typographyLineHeightMd, letterSpacing: theme.comp.labelControl.typographyLetterSpacingMd, }, labelSmall: { fontFamily: theme.comp.labelControl.typographyFontFamilySm, fontWeight: theme.comp.labelControl.typographyFontWeightSm, fontSize: theme.comp.labelControl.typographyFontSizeSm, lineHeight: theme.comp.labelControl.typographyLineHeightSm, letterSpacing: theme.comp.labelControl.typographyLetterSpacingSm, }, labelMedium: { fontFamily: theme.comp.labelControl.typographyFontFamilyMd, fontWeight: theme.comp.labelControl.typographyFontWeightMd, fontSize: theme.comp.labelControl.typographyFontSizeMd, lineHeight: theme.comp.labelControl.typographyLineHeightMd, letterSpacing: theme.comp.labelControl.typographyLetterSpacingMd, }, labelLarge: { fontFamily: theme.comp.labelControl.typographyFontFamilyLg, fontWeight: theme.comp.labelControl.typographyFontWeightLg, fontSize: theme.comp.labelControl.typographyFontSizeLg, lineHeight: theme.comp.labelControl.typographyLineHeightLg, letterSpacing: theme.comp.labelControl.typographyLetterSpacingLg, }, })) export interface LabelControlProps extends Omit<ComponentPropsWithRefFix<'label'>, 'onChange'> { /** * CSS классы компонента. * * @inner */ classes?: Partial<Classes> /** * Значение поля. * * @inner */ checked?: boolean /** * Размер заголовка и элемента формы. * * @inner */ size?: ElementSizeType /** * Элемент формы, который будет выводиться вместе с меткой Radio, CheckBox или Switch. * * @inner */ control: React.ReactElement /** * Элемент отключен. * * @inner */ disabled?: boolean /** * Обработчик, вызываемый при изменении состояния. * * @returns */ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void /** * Свойства элемента input. * * @inner * * @param inputProps.onBlur - Обработчик потери фокуса с элемента. * @param inputProps.onFocus — обработчик onFocus. * @param inputProps — остальные нативные атрибуты элемента input. */ inputProps?: ComponentPropsWithAttributes<ComponentPropsWithRefFix<'input'>> /** * Текст, который будет использоваться рядом с меткой. * * @inner */ label: React.ReactNode /** * Расположение лейбла относительно элемента формы. * * @inner */ labelPlacement?: 'bottom' | 'end' | 'start' | 'top' /** * Value компонента. * * @inner */ value?: string | number | boolean /** * Атрибут name элемента input. * * @inner */ name?: string } export const LabelControl = React.forwardRef( ( { classes, className: classNameProps, checked, control, disabled, size = 'md', onChange, inputProps, label, value, name, labelPlacement = 'end', defaultChecked, ...rest }: LabelControlProps, ref: React.Ref<HTMLLabelElement> ) => { const classList = useStyles() const classesMap = useClassList(classList, classes) const className = clsx(classesMap.label, classNameProps, { [classesMap.disabled]: disabled, [classesMap.start]: labelPlacement === 'start', [classesMap.top]: labelPlacement === 'top', [classesMap.bottom]: labelPlacement === 'bottom', [classesMap.end]: labelPlacement === 'end', }) const contentClassName = clsx(classesMap.labelContent, { [classesMap.labelSmall]: size === ElementSize.sm, [classesMap.labelMedium]: size === ElementSize.md, [classesMap.labelLarge]: size === ElementSize.lg, }) return ( <label {...rest} ref={ref} className={className}> <span className={contentClassName}>{label}</span> {React.cloneElement(control, { disabled, inputProps, checked, onChange, size, value, name, defaultChecked, })} </label> ) } )