UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

230 lines (229 loc) 7.61 kB
"use client"; var _AlignmentHelper; import _JSON$parse from "core-js-pure/stable/json/parse.js"; import _pushInstanceProperty from "core-js-pure/stable/instance/push.js"; import withComponentMarkers from "../../shared/helpers/withComponentMarkers.js"; import React, { useContext, useRef, useState, useCallback } from 'react'; import clsx from 'clsx'; import useId from "../../shared/helpers/useId.js"; import { extendExistingPropsWithContext, validateDOMAttributes, getStatusState, combineDescribedBy, combineLabelledBy, dispatchCustomElementEvent, removeUndefinedProps } from "../../shared/component-helper.js"; import { applySpacing } from "../space/SpacingUtils.js"; import AlignmentHelper from "../../shared/AlignmentHelper.js"; import FormLabel from "../FormLabel.js"; import FormStatus from "../FormStatus.js"; import Flex from "../Flex.js"; import Space from "../Space.js"; import Context from "../../shared/Context.js"; import Suffix from "../../shared/helpers/Suffix.js"; import ToggleButtonGroupContext from "./ToggleButtonGroupContext.js"; import { pickFormElementProps } from "../../shared/helpers/filterValidProps.js"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const toggleButtonGroupDefaultProps = { label: null, labelDirection: 'vertical', labelSrOnly: null, title: null, multiselect: null, variant: null, leftComponent: null, disabled: null, skeleton: null, id: null, name: null, size: null, status: null, statusState: 'error', statusProps: null, statusNoAnimation: null, globalStatus: null, suffix: null, vertical: null, layoutDirection: 'row', value: undefined, values: undefined, className: null, children: null, onChange: null }; function parseValues(props) { if (typeof props.values === 'string' && props.values[0] === '[') { return _JSON$parse(props.values); } return props.values; } function ToggleButtonGroup(ownProps) { const context = useContext(Context); const id = useId(ownProps.id); const _name = useId(ownProps.name); const [value, setValue] = useState(ownProps.value); const [values, setValues] = useState(() => ownProps.values ? parseValues(ownProps) : undefined); const [prevPropsValue, setPrevPropsValue] = useState(ownProps.value); const [prevPropsValues, setPrevPropsValues] = useState(ownProps.values); const prevContextRef = useRef(undefined); const ownPropsRef = useRef(ownProps); ownPropsRef.current = ownProps; const valuesRef = useRef(values); valuesRef.current = values; if (typeof ownProps.value !== 'undefined' && ownProps.value !== prevPropsValue) { setPrevPropsValue(ownProps.value); setValue(ownProps.value); } if (typeof ownProps.values !== 'undefined' && ownProps.values !== prevPropsValues) { setPrevPropsValues(ownProps.values); setValues(parseValues(ownProps)); } const onChangeHandler = useCallback(({ value: newValue, event }) => { const currentValues = [...(valuesRef.current || [])]; if (ownPropsRef.current.multiselect) { if (!currentValues.includes(newValue)) { _pushInstanceProperty(currentValues).call(currentValues, newValue); } else { currentValues.splice(currentValues.indexOf(newValue), 1); } } setValue(newValue); setValues([...currentValues]); dispatchCustomElementEvent({ props: ownPropsRef.current }, 'onChange', { value: newValue, values: currentValues, event }); }, []); const resolvedProps = { ...toggleButtonGroupDefaultProps, ...removeUndefinedProps({ ...ownProps }) }; const props = extendExistingPropsWithContext(resolvedProps, toggleButtonGroupDefaultProps, context.getTranslation(ownProps).ToggleButton, pickFormElementProps(context === null || context === void 0 ? void 0 : context.formElement), context.ToggleButtonGroup); const { status, statusState, statusProps, statusNoAnimation, globalStatus, suffix, labelDirection, labelSrOnly, vertical, layoutDirection, label, variant, leftComponent, size, disabled, skeleton, className, multiselect, id: _id, name: _propName, value: _value, values: _values, children, onChange, ...rest } = props; const showStatus = getStatusState(status); const rootProps = applySpacing(props, { className: clsx(`dnb-toggle-button-group dnb-toggle-button-group--${layoutDirection} dnb-form-component`, className, status && `dnb-toggle-button-group__status--${statusState}`, !label && 'dnb-toggle-button-group--no-label') }); const params = { ...rest }; if (showStatus || suffix) { params['aria-describedby'] = combineDescribedBy(params, showStatus ? id + '-status' : null, suffix ? id + '-suffix' : null); } if (label) { params['aria-labelledby'] = combineLabelledBy(params, id + '-label'); } validateDOMAttributes(ownProps, params); const setContext = useCallback(contextArg => { let resolved; if (typeof contextArg === 'function') { resolved = contextArg(prevContextRef.current); } else { resolved = contextArg; } prevContextRef.current = { ...prevContextRef.current, ...resolved }; if ('value' in resolved) { setValue(resolved.value); } if ('values' in resolved) { setValues(resolved.values); } }, []); const groupContext = { name: _name, value, values, size, multiselect: multiselect, variant, leftComponent, disabled, skeleton, setContext, onChange: onChangeHandler }; const Fieldset = label ? 'fieldset' : 'div'; return _jsx(ToggleButtonGroupContext, { value: groupContext, children: _jsxs("div", { ...rootProps, children: [_AlignmentHelper || (_AlignmentHelper = _jsx(AlignmentHelper, {})), _jsx(Fieldset, { className: "dnb-toggle-button-group__fieldset", "aria-labelledby": label ? id + '-label' : undefined, role: variant === 'radio' ? 'radiogroup' : 'group', children: _jsxs(Flex.Container, { direction: vertical || labelDirection === 'vertical' ? 'vertical' : 'horizontal', gap: vertical ? 'x-small' : 'small', children: [label && _jsx(FormLabel, { element: "legend", id: id + '-label', srOnly: labelSrOnly, vertical: false, children: label }), _jsxs(Space, { element: "span", id: id, className: "dnb-toggle-button-group__shell", ...params, children: [_jsx(FormStatus, { show: showStatus, id: id + '-form-status', globalStatus: globalStatus, label: label, textId: id + '-status', text: status, state: statusState, noAnimation: statusNoAnimation, skeleton: skeleton, ...statusProps }), _jsxs("span", { className: `dnb-toggle-button-group__shell__children dnb-toggle-button-group__shell__children--${layoutDirection}`, children: [children, suffix && _jsx(Suffix, { className: "dnb-toggle-button-group__suffix", id: id + '-suffix', context: props, children: suffix })] })] })] }) })] }) }); } withComponentMarkers(ToggleButtonGroup, { _supportsSpacingProps: true }); export default ToggleButtonGroup; //# sourceMappingURL=ToggleButtonGroup.js.map