UNPKG

@adaptabletools/adaptable

Version:

Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

65 lines (64 loc) 4.12 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from 'react'; import { useState } from 'react'; import useProperty from '../utils/useProperty'; import { Box, Flex } from '../Flex'; import { twMerge } from '../../twMerge'; import { targetChildren, targetOwn } from '../twUtils'; import { cn } from '../../lib/utils'; const RadioContext = React.createContext({ value: null, name: '', onChange: (v) => { }, variant: 'default', }); export const useRadioContext = () => { return React.useContext(RadioContext); }; const Radio = ({ children, checked, onChange, value, name, gapDistance = 'var(--ab-radio-gap)', childrenPosition = 'end', as = 'label', id, tabIndex, disabled, ...props }) => { const context = useRadioContext(); const { value: contextValue, onChange: contextOnChange, name: contextName, variant } = context; const [stateChecked, setStateChecked] = useState(false); const computedChecked = checked !== undefined ? checked : contextValue !== undefined ? contextValue === value : stateChecked; const onInputChange = (event) => { const newChecked = event.target.checked; if (checked === undefined) { setStateChecked(newChecked); } if (onChange) { onChange(newChecked, event); } if (newChecked) { contextOnChange(value); } }; const gap = _jsx("div", { style: { marginLeft: gapDistance, display: 'inline-block' } }); const before = childrenPosition === 'start' ? children : null; const beforeGap = childrenPosition === 'start' ? gap : null; const after = childrenPosition === 'end' ? children : null; const afterGap = childrenPosition === 'end' ? gap : null; return (_jsxs(Box, { ...props, className: twMerge(`ab-Radio twa:my-2 twa:inline-flex twa:flex-row twa:items-center twa:cursor-pointer twa:relative`, props.className), "data-checked": computedChecked, as: as, children: [before, beforeGap, _jsx("input", { disabled: disabled, className: cn('ab-Radio-input', targetOwn.focusOutline, 'twa:align-middle', 'twa:m-0', 'twa:rounded-full', 'twa:cursor-pointer', 'twa:position-relative', 'twa:w-[1rem]', 'twa:h-[1rem]', 'twa:min-w-[1rem]', 'twa:min-h-[1rem]', variant === 'default' && 'ab-Radio-input--default', variant === 'text-only' && 'ab-Radio-input--text-only twa:size-0 twa:opacity-0'), id: id, checked: computedChecked, type: "radio", name: name ?? contextName, value: value, tabIndex: tabIndex, onChange: onInputChange }), afterGap, after] })); }; export const RadioGroup = (props) => { const { orientation, value: _value, name, onRadioChange, children, variant = 'default' } = props; const [value, setValue] = useProperty(props, 'value', undefined, { onChange: (value) => { onRadioChange(value); }, }); return (_jsx(RadioContext.Provider, { value: { value, onChange: setValue, name, variant }, children: _jsx(Flex, { className: cn('ab-RadioGroup', props.className), flexDirection: orientation == 'horizontal' ? 'row' : 'column', alignItems: orientation == 'horizontal' ? 'center' : 'flex-start', children: children }) })); }; export const radioGroupStyling = { horizontalTextOnly: cn('twa:bg-primarylight twa:rounded-standard twa:p-1 twa:gap-5', { 'twa:*:flex-1 twa:*:shrink-0 twa:*:min-w-fit twa:*:rounded-standard twa:*:p-1 twa:*:m-0 twa:*:px-4': 'default styles for all the radio buttons', 'twa:*:data-[checked=true]:bg-accent twa:*:data-[checked=true]:text-accent-foreground': 'style the checked state', 'twa:[--ab-radio-gap:0]': 'remove the gap between the radio input and its label', 'twa:[&_input]:size-0 twa:[&_input]:min-w-0 twa:[&_input]:min-h-0 twa:[&_input]:border-0 twa:[&_input]:p-0': 'collapse any nested radio inputs to zero size (overriding their fixed min-w/min-h)', [targetChildren.focusWithinOutline]: 'styles for when a radio is currently focused - show a ring, so people know they can do keyboard nav with left/right arrow keys', }), }; export default Radio;