@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
339 lines (338 loc) • 12.2 kB
JavaScript
;
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _withComponentMarkers = _interopRequireDefault(require("../../shared/helpers/withComponentMarkers.js"));
var _react = _interopRequireWildcard(require("react"));
var _clsx = _interopRequireDefault(require("clsx"));
var _useId = _interopRequireDefault(require("../../shared/helpers/useId.js"));
var _componentHelper = require("../../shared/component-helper.js");
var _AlignmentHelper2 = _interopRequireDefault(require("../../shared/AlignmentHelper.js"));
var _SpacingUtils = require("../space/SpacingUtils.js");
var _SkeletonHelper = require("../skeleton/SkeletonHelper.js");
var _FormLabel = _interopRequireDefault(require("../form-label/FormLabel.js"));
var _FormStatus = _interopRequireDefault(require("../form-status/FormStatus.js"));
var _RadioGroup = _interopRequireDefault(require("./RadioGroup.js"));
var _RadioGroupContext = _interopRequireDefault(require("./RadioGroupContext.js"));
var _Context = _interopRequireDefault(require("../../shared/Context.js"));
var _Suffix = _interopRequireDefault(require("../../shared/helpers/Suffix.js"));
var _filterValidProps = require("../../shared/helpers/filterValidProps.js");
var _jsxRuntime = require("react/jsx-runtime");
var _AlignmentHelper, _span;
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const radioDefaultProps = {
label: null,
labelSrOnly: null,
labelPosition: null,
checked: null,
disabled: null,
id: null,
size: null,
element: 'input',
group: null,
status: null,
statusState: 'error',
statusProps: null,
statusNoAnimation: null,
globalStatus: null,
suffix: null,
value: '',
readOnly: false,
skeleton: null,
className: null,
children: null,
onChange: null,
ref: null
};
const parseChecked = state => /true|on/.test(String(state));
function RadioInner({
ref: externalRef,
...ownProps
}) {
const groupContext = (0, _react.useContext)(_RadioGroupContext.default);
const context = (0, _react.useContext)(_Context.default);
const inputRef = (0, _react.useRef)(null);
const ownPropsRef = (0, _react.useRef)(ownProps);
ownPropsRef.current = ownProps;
const groupContextRef = (0, _react.useRef)(groupContext);
groupContextRef.current = groupContext;
const id = (0, _useId.default)(ownProps.id);
const [checkedState, setCheckedState] = (0, _react.useState)(() => parseChecked(ownProps.checked));
const [prevPropsChecked, setPrevPropsChecked] = (0, _react.useState)(ownProps.checked);
const skipNextPropSync = (0, _react.useRef)(false);
if (ownProps.checked !== prevPropsChecked) {
setPrevPropsChecked(ownProps.checked);
if (!skipNextPropSync.current) {
setCheckedState(parseChecked(ownProps.checked));
}
}
skipNextPropSync.current = false;
const isContextGroupOrSingle = (0, _react.useCallback)(() => typeof groupContext.value !== 'undefined' && !ownProps.group, [groupContext.value, ownProps.group]);
const isPlainGroup = (0, _react.useCallback)(() => typeof groupContext.value === 'undefined' && ownProps.group, [groupContext.value, ownProps.group]);
const isInNoGroup = (0, _react.useCallback)(() => typeof groupContext.value === 'undefined' && !ownProps.group, [groupContext.value, ownProps.group]);
const callOnChange = (0, _react.useCallback)(({
value,
checked: isChecked,
event
}) => {
const {
group
} = ownPropsRef.current;
if (groupContextRef.current.onChange) {
groupContextRef.current.onChange({
value,
event
});
}
(0, _componentHelper.dispatchCustomElementEvent)({
props: ownPropsRef.current
}, 'onChange', {
group,
checked: isChecked,
value,
event
});
if (inputRef.current) {
inputRef.current.focus();
}
}, []);
const onChangeHandler = (0, _react.useCallback)(_event => {
const event = _event;
if (ownPropsRef.current.readOnly) {
return event.preventDefault();
}
const value = event.target.value;
const newChecked = !checkedState;
if (isPlainGroup()) {
setTimeout(() => {
skipNextPropSync.current = true;
setCheckedState(newChecked);
callOnChange({
value,
checked: newChecked,
event
});
}, 1);
} else {
skipNextPropSync.current = true;
setCheckedState(newChecked);
callOnChange({
value,
checked: newChecked,
event
});
}
}, [checkedState, isPlainGroup, callOnChange]);
const onKeyDownHandler = (0, _react.useCallback)(event => {
const key = event.key;
if (isInNoGroup()) {
if (key === 'Enter') {
onChangeHandler(event);
}
} else if (isContextGroupOrSingle()) {
if (key === 'Enter' || key === ' ') {
const {
value
} = groupContextRef.current;
if (value !== null && typeof value !== 'undefined') {
event.preventDefault();
}
onChangeHandler(event);
}
} else {
if (key === ' ') {
event.preventDefault();
}
}
(0, _componentHelper.dispatchCustomElementEvent)({
props: ownPropsRef.current
}, 'onKeyDown', {
event
});
}, [isInNoGroup, isContextGroupOrSingle, onChangeHandler]);
const onClickHandler = (0, _react.useCallback)(event => {
if (ownPropsRef.current.readOnly) {
return event.preventDefault();
}
if (!isPlainGroup()) {
return;
}
const value = event.target.value;
const isChecked = event.target.checked;
callOnChange({
value,
checked: isChecked,
event
});
}, [isPlainGroup, callOnChange]);
const resolvedProps = {
...radioDefaultProps,
...(0, _componentHelper.removeUndefinedProps)({
...ownProps
})
};
const contextProps = (0, _componentHelper.extendExistingPropsWithContext)(resolvedProps, radioDefaultProps, groupContext);
const props = (0, _componentHelper.extendExistingPropsWithContext)(resolvedProps, radioDefaultProps, contextProps, {
skeleton: context === null || context === void 0 ? void 0 : context.skeleton
}, (0, _filterValidProps.pickFormElementProps)(context.formElement), context === null || context === void 0 ? void 0 : context.Radio);
const {
status,
statusState,
statusProps,
statusNoAnimation,
globalStatus,
suffix,
element,
label,
labelSrOnly,
labelPosition,
size,
readOnly,
skeleton,
className,
id: _id,
group: _group,
value: _value,
checked: _checked,
disabled: _disabled,
children,
onChange,
ref: _ref,
...rest
} = props;
for (const key of Object.keys(ownProps)) {
if (!(key in radioDefaultProps)) {
;
rest[key] = ownProps[key];
}
}
let checked = checkedState;
const {
value
} = props;
let {
group,
disabled
} = props;
const hasContext = typeof groupContext.name !== 'undefined';
if (hasContext) {
if (typeof groupContext.value !== 'undefined') {
checked = groupContext.value === value;
}
group = groupContext.name;
if (groupContext.disabled && disabled !== false) {
disabled = true;
}
} else if (typeof rest.name !== 'undefined') {
group = rest.name;
}
const showStatus = (0, _componentHelper.getStatusState)(status);
const mainParams = (0, _SpacingUtils.applySpacing)(props, {
className: (0, _clsx.default)('dnb-radio', className, status && `dnb-radio__status--${statusState}`, size && `dnb-radio--${size}`, label && `dnb-radio--label-position-${labelPosition || 'right'}`)
});
let inputParams = {
role: hasContext || group ? 'radio' : null,
type: hasContext || group ? 'radio' : 'checkbox'
};
if (!group) {
inputParams.type = 'checkbox';
inputParams.role = 'radio';
}
if (showStatus || suffix) {
inputParams['aria-describedby'] = (0, _componentHelper.combineDescribedBy)(inputParams, showStatus ? id + '-status' : null, suffix ? id + '-suffix' : null);
}
if (readOnly) {
inputParams['aria-readonly'] = inputParams.readOnly = true;
}
inputParams = Object.assign(inputParams, rest);
(0, _SkeletonHelper.skeletonDOMAttributes)(inputParams, skeleton, context);
(0, _componentHelper.validateDOMAttributes)(ownProps, inputParams);
const labelComp = label && (0, _jsxRuntime.jsx)(_FormLabel.default, {
id: id + '-label',
forId: id,
text: label,
disabled: disabled,
skeleton: skeleton,
srOnly: labelSrOnly,
vertical: false
});
const Element = element || 'input';
const combinedRef = (0, _react.useCallback)(el => {
;
inputRef.current = el;
if (typeof externalRef === 'function') {
externalRef(el);
} else if (externalRef) {
;
externalRef.current = el;
}
}, [externalRef]);
return (0, _jsxRuntime.jsx)("span", {
...mainParams,
children: (0, _jsxRuntime.jsxs)("span", {
className: "dnb-radio__order",
children: [labelPosition === 'left' && labelComp, (0, _jsxRuntime.jsxs)("span", {
className: "dnb-radio__inner",
children: [_AlignmentHelper || (_AlignmentHelper = (0, _jsxRuntime.jsx)(_AlignmentHelper2.default, {})), (0, _jsxRuntime.jsx)(_FormStatus.default, {
show: showStatus,
id: id + '-form-status',
globalStatus: globalStatus,
label: label,
textId: id + '-status',
widthSelector: id + ', ' + id + '-label',
text: status,
state: statusState,
noAnimation: statusNoAnimation,
skeleton: skeleton,
...statusProps
}), (0, _jsxRuntime.jsxs)("span", {
className: "dnb-radio__row",
children: [(0, _jsxRuntime.jsxs)("span", {
className: "dnb-radio__shell",
children: [(0, _jsxRuntime.jsx)(Element, {
type: "radio",
value: value,
id: id,
name: group,
className: "dnb-radio__input",
checked: checked,
"aria-checked": isPlainGroup() ? undefined : checked,
disabled: disabled,
ref: combinedRef,
...inputParams,
onChange: onChangeHandler,
onClick: onClickHandler,
onKeyDown: onKeyDownHandler
}), (0, _jsxRuntime.jsx)("span", {
className: (0, _clsx.default)('dnb-radio__button', (0, _SkeletonHelper.createSkeletonClass)('shape', skeleton, context)),
"aria-hidden": true
}), _span || (_span = (0, _jsxRuntime.jsx)("span", {
className: "dnb-radio__focus",
"aria-hidden": true
})), (0, _jsxRuntime.jsx)("span", {
className: (0, _clsx.default)('dnb-radio__dot', (0, _SkeletonHelper.createSkeletonClass)('font', skeleton, context)),
"aria-hidden": true
})]
}), labelPosition !== 'left' && labelComp, suffix && (0, _jsxRuntime.jsx)(_Suffix.default, {
className: "dnb-radio__suffix",
id: id + '-suffix',
context: props,
children: suffix
})]
})]
})]
})
});
}
const Radio = _react.default.memo(RadioInner);
Radio.Group = _RadioGroup.default;
Radio.parseChecked = parseChecked;
(0, _withComponentMarkers.default)(Radio, {
_formElement: true,
_supportsSpacingProps: true
});
var _default = exports.default = Radio;
//# sourceMappingURL=Radio.js.map