@simplybusiness/mobius 10.3.4 → 10.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/components/AddressLookup/AddressLookup.js +5 -4
- package/dist/cjs/components/AddressLookup/AddressLookup.js.map +2 -2
- package/dist/cjs/components/AddressLookup/index.js +5 -4
- package/dist/cjs/components/AddressLookup/index.js.map +2 -2
- package/dist/cjs/components/Alert/Alert.js +5 -4
- package/dist/cjs/components/Alert/Alert.js.map +2 -2
- package/dist/cjs/components/Alert/index.js +5 -4
- package/dist/cjs/components/Alert/index.js.map +2 -2
- package/dist/cjs/components/Checkbox/Checkbox.js +5 -4
- package/dist/cjs/components/Checkbox/Checkbox.js.map +2 -2
- package/dist/cjs/components/Checkbox/CheckboxGroup.js +5 -4
- package/dist/cjs/components/Checkbox/CheckboxGroup.js.map +2 -2
- package/dist/cjs/components/Checkbox/index.js +5 -4
- package/dist/cjs/components/Checkbox/index.js.map +2 -2
- package/dist/cjs/components/Combobox/Combobox.js +5 -4
- package/dist/cjs/components/Combobox/Combobox.js.map +2 -2
- package/dist/cjs/components/Combobox/index.js +5 -4
- package/dist/cjs/components/Combobox/index.js.map +2 -2
- package/dist/cjs/components/DateField/DateField.js +5 -4
- package/dist/cjs/components/DateField/DateField.js.map +2 -2
- package/dist/cjs/components/DateField/index.js +5 -4
- package/dist/cjs/components/DateField/index.js.map +2 -2
- package/dist/cjs/components/ErrorMessage/ErrorMessage.js +5 -4
- package/dist/cjs/components/ErrorMessage/ErrorMessage.js.map +2 -2
- package/dist/cjs/components/ErrorMessage/index.js +5 -4
- package/dist/cjs/components/ErrorMessage/index.js.map +2 -2
- package/dist/cjs/components/ExpandableText/ExpandableText.js +5 -4
- package/dist/cjs/components/ExpandableText/ExpandableText.js.map +2 -2
- package/dist/cjs/components/ExpandableText/index.js +5 -4
- package/dist/cjs/components/ExpandableText/index.js.map +2 -2
- package/dist/cjs/components/MaskedField/MaskedField.js +5 -4
- package/dist/cjs/components/MaskedField/MaskedField.js.map +2 -2
- package/dist/cjs/components/MaskedField/index.js +6 -5
- package/dist/cjs/components/MaskedField/index.js.map +2 -2
- package/dist/cjs/components/Modal/Modal.js +6 -0
- package/dist/cjs/components/Modal/Modal.js.map +2 -2
- package/dist/cjs/components/Modal/index.js +6 -0
- package/dist/cjs/components/Modal/index.js.map +2 -2
- package/dist/cjs/components/Modal/types.js.map +1 -1
- package/dist/cjs/components/NumberField/NumberField.js +5 -4
- package/dist/cjs/components/NumberField/NumberField.js.map +2 -2
- package/dist/cjs/components/NumberField/index.js +5 -4
- package/dist/cjs/components/NumberField/index.js.map +2 -2
- package/dist/cjs/components/PasswordField/PasswordField.js +5 -4
- package/dist/cjs/components/PasswordField/PasswordField.js.map +2 -2
- package/dist/cjs/components/PasswordField/index.js +5 -4
- package/dist/cjs/components/PasswordField/index.js.map +2 -2
- package/dist/cjs/components/Radio/Radio.js +5 -4
- package/dist/cjs/components/Radio/Radio.js.map +2 -2
- package/dist/cjs/components/Radio/RadioGroup.js +5 -4
- package/dist/cjs/components/Radio/RadioGroup.js.map +2 -2
- package/dist/cjs/components/Radio/index.js +5 -4
- package/dist/cjs/components/Radio/index.js.map +2 -2
- package/dist/cjs/components/Select/Select.js +5 -4
- package/dist/cjs/components/Select/Select.js.map +2 -2
- package/dist/cjs/components/Select/index.js +5 -4
- package/dist/cjs/components/Select/index.js.map +2 -2
- package/dist/cjs/components/TextArea/TextArea.js +5 -4
- package/dist/cjs/components/TextArea/TextArea.js.map +2 -2
- package/dist/cjs/components/TextArea/index.js +5 -4
- package/dist/cjs/components/TextArea/index.js.map +2 -2
- package/dist/cjs/components/TextField/TextField.js +5 -4
- package/dist/cjs/components/TextField/TextField.js.map +2 -2
- package/dist/cjs/components/TextField/index.js +5 -4
- package/dist/cjs/components/TextField/index.js.map +2 -2
- package/dist/cjs/components/TextOrHTML/TextOrHTML.js +5 -4
- package/dist/cjs/components/TextOrHTML/TextOrHTML.js.map +2 -2
- package/dist/cjs/components/TextOrHTML/index.js +5 -4
- package/dist/cjs/components/TextOrHTML/index.js.map +2 -2
- package/dist/cjs/components/index.js +12 -5
- package/dist/cjs/components/index.js.map +2 -2
- package/dist/cjs/index.js +12 -5
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/meta.json +114 -114
- package/dist/esm/{chunk-4WVJNNBK.js → chunk-2HUMNED2.js} +2 -2
- package/dist/esm/{chunk-N4WQ6522.js → chunk-2VEO5SSY.js} +2 -2
- package/dist/esm/{chunk-AFU7BFCD.js → chunk-576SEJGC.js} +3 -3
- package/dist/esm/{chunk-QPIA6BGW.js → chunk-6JCU4CGA.js} +2 -2
- package/dist/esm/{chunk-X6EPYQKX.js → chunk-F5ELD54X.js} +2 -2
- package/dist/esm/{chunk-ZN5TRIVZ.js → chunk-GV36OVX7.js} +2 -2
- package/dist/esm/{chunk-JNAQ76CR.js → chunk-HGNWNZ5E.js} +2 -2
- package/dist/esm/{chunk-ONDOONBM.js → chunk-HUSMC5GZ.js} +2 -2
- package/dist/esm/{chunk-UIIXVY6K.js → chunk-IQKS662C.js} +2 -2
- package/dist/esm/{chunk-KXLTGNKF.js → chunk-JJUTS5ET.js} +7 -1
- package/dist/esm/chunk-JJUTS5ET.js.map +7 -0
- package/dist/esm/{chunk-DYTHXKMX.js → chunk-KTJCAQT4.js} +6 -5
- package/dist/esm/chunk-KTJCAQT4.js.map +7 -0
- package/dist/esm/{chunk-5OFXPT4J.js → chunk-M62U4QGQ.js} +2 -2
- package/dist/esm/{chunk-UQVAEWY2.js → chunk-MZJT3USG.js} +2 -2
- package/dist/esm/{chunk-FKTDL7KO.js → chunk-OAG5T7NC.js} +2 -2
- package/dist/esm/{chunk-M2NDSQR5.js → chunk-P6YHEIFT.js} +2 -2
- package/dist/esm/{chunk-DZVBN6ZI.js → chunk-PEEQNAIN.js} +2 -2
- package/dist/esm/{chunk-P5VEI574.js → chunk-S4CU4XRB.js} +2 -2
- package/dist/esm/{chunk-4NBLO5WK.js → chunk-X4CMSAET.js} +2 -2
- package/dist/esm/{chunk-KQZ3MNK5.js → chunk-XNEQHHNV.js} +2 -2
- package/dist/esm/components/AddressLookup/AddressLookup.js +5 -5
- package/dist/esm/components/AddressLookup/index.js +5 -5
- package/dist/esm/components/Alert/Alert.js +2 -2
- package/dist/esm/components/Alert/index.js +2 -2
- package/dist/esm/components/Checkbox/Checkbox.js +3 -3
- package/dist/esm/components/Checkbox/CheckboxGroup.js +4 -4
- package/dist/esm/components/Checkbox/index.js +4 -4
- package/dist/esm/components/Combobox/Combobox.js +4 -4
- package/dist/esm/components/Combobox/index.js +4 -4
- package/dist/esm/components/DateField/DateField.js +4 -4
- package/dist/esm/components/DateField/index.js +4 -4
- package/dist/esm/components/ErrorMessage/ErrorMessage.js +2 -2
- package/dist/esm/components/ErrorMessage/index.js +2 -2
- package/dist/esm/components/ExpandableText/ExpandableText.js +2 -2
- package/dist/esm/components/ExpandableText/index.js +2 -2
- package/dist/esm/components/MaskedField/MaskedField.js +3 -3
- package/dist/esm/components/MaskedField/index.js +4 -4
- package/dist/esm/components/Modal/Modal.js +1 -1
- package/dist/esm/components/Modal/index.js +2 -2
- package/dist/esm/components/NumberField/NumberField.js +4 -4
- package/dist/esm/components/NumberField/index.js +4 -4
- package/dist/esm/components/PasswordField/PasswordField.js +4 -4
- package/dist/esm/components/PasswordField/index.js +4 -4
- package/dist/esm/components/Radio/Radio.js +3 -3
- package/dist/esm/components/Radio/RadioGroup.js +3 -3
- package/dist/esm/components/Radio/index.js +4 -4
- package/dist/esm/components/Select/Select.js +3 -3
- package/dist/esm/components/Select/index.js +3 -3
- package/dist/esm/components/TextArea/TextArea.js +3 -3
- package/dist/esm/components/TextArea/index.js +3 -3
- package/dist/esm/components/TextField/TextField.js +3 -3
- package/dist/esm/components/TextField/index.js +3 -3
- package/dist/esm/components/TextOrHTML/TextOrHTML.js +1 -1
- package/dist/esm/components/TextOrHTML/index.js +1 -1
- package/dist/esm/components/index.js +19 -19
- package/dist/esm/index.js +19 -19
- package/dist/esm/meta.json +208 -208
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/components/Modal/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/Modal/Modal.tsx +6 -0
- package/src/components/Modal/types.ts +1 -0
- package/src/components/TextOrHTML/TextOrHTML.test.tsx +45 -8
- package/src/components/TextOrHTML/TextOrHTML.tsx +7 -4
- package/dist/esm/chunk-DYTHXKMX.js.map +0 -7
- package/dist/esm/chunk-KXLTGNKF.js.map +0 -7
- /package/dist/esm/{chunk-4WVJNNBK.js.map → chunk-2HUMNED2.js.map} +0 -0
- /package/dist/esm/{chunk-N4WQ6522.js.map → chunk-2VEO5SSY.js.map} +0 -0
- /package/dist/esm/{chunk-AFU7BFCD.js.map → chunk-576SEJGC.js.map} +0 -0
- /package/dist/esm/{chunk-QPIA6BGW.js.map → chunk-6JCU4CGA.js.map} +0 -0
- /package/dist/esm/{chunk-X6EPYQKX.js.map → chunk-F5ELD54X.js.map} +0 -0
- /package/dist/esm/{chunk-ZN5TRIVZ.js.map → chunk-GV36OVX7.js.map} +0 -0
- /package/dist/esm/{chunk-JNAQ76CR.js.map → chunk-HGNWNZ5E.js.map} +0 -0
- /package/dist/esm/{chunk-ONDOONBM.js.map → chunk-HUSMC5GZ.js.map} +0 -0
- /package/dist/esm/{chunk-UIIXVY6K.js.map → chunk-IQKS662C.js.map} +0 -0
- /package/dist/esm/{chunk-5OFXPT4J.js.map → chunk-M62U4QGQ.js.map} +0 -0
- /package/dist/esm/{chunk-UQVAEWY2.js.map → chunk-MZJT3USG.js.map} +0 -0
- /package/dist/esm/{chunk-FKTDL7KO.js.map → chunk-OAG5T7NC.js.map} +0 -0
- /package/dist/esm/{chunk-M2NDSQR5.js.map → chunk-P6YHEIFT.js.map} +0 -0
- /package/dist/esm/{chunk-DZVBN6ZI.js.map → chunk-PEEQNAIN.js.map} +0 -0
- /package/dist/esm/{chunk-P5VEI574.js.map → chunk-S4CU4XRB.js.map} +0 -0
- /package/dist/esm/{chunk-4NBLO5WK.js.map → chunk-X4CMSAET.js.map} +0 -0
- /package/dist/esm/{chunk-KQZ3MNK5.js.map → chunk-XNEQHHNV.js.map} +0 -0
|
@@ -132,7 +132,8 @@ Text.displayName = "Text";
|
|
|
132
132
|
|
|
133
133
|
// src/components/TextOrHTML/TextOrHTML.tsx
|
|
134
134
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
135
|
-
var
|
|
135
|
+
var BLOCK_TAG = /<(div|p|ul|ol|li|h[1-6]|table|tr|td|th|blockquote|pre|hr|dl|dt|dd)[\s>/]/i;
|
|
136
|
+
var containsBlockHTML = (text) => BLOCK_TAG.test(text);
|
|
136
137
|
var containsHTML = (text) => /<[a-z/]/i.test(text) || /&(?:#\d+|#x[\da-f]+|[a-z]\w*);/i.test(text);
|
|
137
138
|
var buildTextClasses = (textProps, htmlClassName) => {
|
|
138
139
|
const { variant, elementType, spacing, className } = textProps;
|
|
@@ -155,9 +156,9 @@ var TextOrHTML = ({
|
|
|
155
156
|
autoDetect = false,
|
|
156
157
|
...textProps
|
|
157
158
|
}) => {
|
|
158
|
-
const
|
|
159
|
+
const hasBlockContent = autoDetect && containsBlockHTML(text);
|
|
159
160
|
const dangerousHTML = (0, import_react.useMemo)(() => ({ __html: text }), [text]);
|
|
160
|
-
if (autoDetect && !
|
|
161
|
+
if (autoDetect && !hasBlockContent) {
|
|
161
162
|
const { variant, spacing, elementType, className, ...domProps } = textProps;
|
|
162
163
|
const Element = getElementType(variant, elementType);
|
|
163
164
|
const classes = buildTextClasses(textProps, htmlClassName);
|
|
@@ -171,7 +172,7 @@ var TextOrHTML = ({
|
|
|
171
172
|
}
|
|
172
173
|
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Element, { ref, ...domProps, className: classes, children: text });
|
|
173
174
|
}
|
|
174
|
-
const DangerousComponent = htmlElementType ?? (
|
|
175
|
+
const DangerousComponent = htmlElementType ?? (hasBlockContent ? "div" : "span");
|
|
175
176
|
const dangerousElement = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
176
177
|
DangerousComponent,
|
|
177
178
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/Radio/Radio.tsx", "../../../../src/components/ErrorMessage/ErrorMessage.tsx", "../../../../src/components/Icon/Icon.tsx", "../../../../src/components/TextOrHTML/TextOrHTML.tsx", "../../../../src/components/Text/Text.tsx", "../../../../src/components/Label/Label.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport {\n Children,\n isValidElement,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { HTMLElementEvent } from \"../../types/events\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport \"./Radio.css\";\n\nexport type RadioElementType = HTMLInputElement;\n\nexport type RadioOverflowInfo = {\n vertical: boolean;\n horizontal: boolean;\n};\n\nexport type AriaRadioProps = {\n /**\n * Defines a string value that labels the current element.\n */\n \"aria-label\"?: string;\n /**\n * Identifies the element (or elements) that labels the current element.\n */\n \"aria-labelledby\"?: string;\n /**\n * Identifies the element (or elements) that describes the object.\n */\n \"aria-describedby\"?: string;\n /**\n * Identifies the element (or elements) that provide a detailed, extended description for the object.\n */\n \"aria-details\"?: string;\n};\n\nexport interface RadioProps\n extends DOMProps, AriaRadioProps, RefAttributes<RadioElementType> {\n children?: ReactNode;\n className?: string;\n label?: ReactNode;\n errorMessage?: string;\n value: string;\n isDisabled?: boolean;\n onChange?: (event: HTMLElementEvent<RadioElementType>) => void;\n defaultChecked?: boolean;\n /**\n * Callback fired when label overflow state changes.\n * Only invoked when the Radio is in horizontal orientation to prevent infinite loops with autoStack.\n * Provides information about vertical and horizontal overflow.\n */\n onOverflow?: (overflow: RadioOverflowInfo) => void;\n // Internal:** Do not use\n groupDisabled?: boolean;\n // Internal:** Do not use\n name?: string;\n // Internal:** Do not use\n selected?: string;\n // Internal:** Do not use\n setSelected?: React.Dispatch<React.SetStateAction<string>>;\n isRequired?: boolean;\n /**\n * **Internal:** Passed via cloneElement from RadioGroup.\n * @internal\n */\n orientation?: \"horizontal\" | \"vertical\";\n}\n\nconst Radio = ({ ref, ...props }: RadioProps) => {\n const {\n children,\n value,\n label,\n className,\n isDisabled,\n errorMessage,\n onChange,\n defaultChecked,\n groupDisabled,\n name,\n selected,\n setSelected,\n isRequired,\n onOverflow,\n orientation,\n ...otherProps\n } = props;\n const realDisabled = groupDisabled || isDisabled;\n const isMultiline = label && children;\n const isControlled = selected !== undefined;\n const isChecked = isControlled ? selected === value : defaultChecked;\n\n const contentRef = useRef<HTMLDivElement>(null);\n const prevOverflowRef = useRef<RadioOverflowInfo>({\n vertical: false,\n horizontal: false,\n });\n\n const hasIconFirst = useMemo(() => {\n if (!children || Children.count(children) === 0) return false;\n\n const firstChild = Children.toArray(children)[0];\n if (!isValidElement(firstChild)) return false;\n\n const props = firstChild.props as Record<string, unknown>;\n return \"icon\" in props && props.icon !== undefined;\n }, [children]);\n\n // Detect overflow and call callback\n useLayoutEffect(() => {\n if (!contentRef.current || !onOverflow) return;\n\n // Only detect overflow when in horizontal orientation\n // This prevents infinite loops when autoStack switches to vertical\n if (orientation === \"vertical\") {\n return;\n }\n\n const element = contentRef.current;\n\n // Check for content being cut off (true overflow)\n const scrollOverflowVertical = element.scrollHeight > element.clientHeight;\n const scrollOverflowHorizontal = element.scrollWidth > element.clientWidth;\n\n // Check for multi-line text wrapping by comparing height to single line height\n const styles = window.getComputedStyle(element);\n const lineHeight = parseFloat(styles.lineHeight);\n const fontSize = parseFloat(styles.fontSize);\n const singleLineHeight = isNaN(lineHeight) ? fontSize * 1.2 : lineHeight;\n\n // Tolerance multiplier to account for sub-pixel rendering and line-height variations.\n // If element height is greater than single line, text has wrapped.\n const WRAP_DETECTION_TOLERANCE = 1.1;\n const hasWrapped =\n element.clientHeight > singleLineHeight * WRAP_DETECTION_TOLERANCE;\n\n const vertical = scrollOverflowVertical || hasWrapped;\n const horizontal = scrollOverflowHorizontal;\n\n const newOverflowState = { vertical, horizontal };\n const prevOverflow = prevOverflowRef.current;\n\n // Only call callback if state actually changed\n if (\n newOverflowState.vertical !== prevOverflow.vertical ||\n newOverflowState.horizontal !== prevOverflow.horizontal\n ) {\n prevOverflowRef.current = newOverflowState;\n onOverflow(newOverflowState);\n }\n }, [label, children, onOverflow, orientation]);\n\n const radioClasses = {\n \"--is-disabled\": realDisabled,\n \"--is-selected\": selected === value,\n \"--is-multiline\": !!isMultiline,\n \"--is-required\": isRequired,\n };\n const containerClasses = classNames(\n \"mobius-radio__label\",\n radioClasses,\n className,\n { \"--has-icon-first\": hasIconFirst },\n );\n\n const inputClasses = classNames(\"mobius-radio__input\", radioClasses);\n\n // Exclude props that are passed via cloneElement in `<RadioGroup />`\n const { \"aria-describedby\": _ariaDescribedBy, ...rest } = otherProps;\n\n // Handle all interactions through onChange event\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n // Update internal state for RadioGroup\n if (setSelected) {\n setSelected(event.target.value);\n }\n\n // Call parent onChange callback\n if (onChange) {\n // Create an HTMLElementEvent-compatible object\n const adaptedEvent: HTMLElementEvent<HTMLInputElement> = {\n ...event.nativeEvent,\n target: event.target,\n };\n onChange(adaptedEvent);\n }\n };\n\n return (\n <>\n <Label className={containerClasses}>\n <input\n aria-describedby={otherProps[\"aria-describedby\"]}\n disabled={realDisabled}\n ref={ref}\n className={inputClasses}\n value={value}\n tabIndex={0}\n type=\"radio\"\n onChange={handleChange}\n {...(isControlled\n ? { checked: isChecked }\n : { defaultChecked: isChecked })}\n name={name}\n required={isRequired}\n {...rest}\n />\n {isMultiline ? (\n <div ref={contentRef} className=\"mobius-radio__content--multiline\">\n <div className=\"mobius-radio__content-first-line\">{label}</div>\n <div className=\"mobius-radio__extra-content\">{children}</div>\n </div>\n ) : (\n <div ref={contentRef} className=\"mobius-radio__content\">\n {label || children}\n </div>\n )}\n </Label>\n {errorMessage && <ErrorMessage errorMessage={errorMessage} />}\n </>\n );\n};\n\nRadio.displayName = \"Radio\";\nexport { Radio };\n", "import { error } from \"@simplybusiness/icons\";\nimport classNames from \"classnames/dedupe\";\nimport { Icon } from \"../Icon\";\nimport { TextOrHTML } from \"../TextOrHTML\";\nimport \"./ErrorMessage.css\";\n\nexport interface ErrorMessageProps {\n errorMessage?: string;\n id?: string;\n className?: string;\n}\n\nexport const ErrorMessage = ({\n id,\n errorMessage,\n className,\n}: ErrorMessageProps) => {\n const classes = classNames(\"mobius\", \"mobius-error-message\", className);\n\n if (!errorMessage) return null;\n\n return (\n <div id={id} className={classes} data-testid=\"ErrorMessage\" role=\"alert\">\n <Icon\n icon={error}\n className=\"mobius-error-message__icon\"\n aria-hidden=\"true\"\n />\n <TextOrHTML\n elementType=\"span\"\n className=\"mobius-error-message__text\"\n text={errorMessage}\n />\n </div>\n );\n};\n\nErrorMessage.displayName = \"ErrorMessage\";\n", "import classNames from \"classnames/dedupe\";\nimport type { IconProps } from \"./types\";\nimport \"./Icon.css\";\n\nconst ICON_PREFIX = \"mobius-icon\";\n\nconst capitaliseFirstLetter = (str: string) =>\n str.charAt(0).toUpperCase() + str.slice(1);\n\nexport function Icon({\n ref,\n icon,\n className,\n size = \"xs\",\n color,\n fixedWidth,\n spin,\n spinReverse,\n title,\n ...otherProps\n}: IconProps) {\n if (!icon) {\n throw new Error(\"Must specify icon object\");\n }\n\n const classes = classNames(\n \"mobius\",\n \"mobius-icon\",\n `svg-inline--${ICON_PREFIX}`,\n `--size-${size}`,\n className,\n {\n [`${ICON_PREFIX}-fw`]: fixedWidth,\n [`${ICON_PREFIX}-spin`]: spin || spinReverse,\n [`${ICON_PREFIX}-spin-reverse`]: spinReverse,\n },\n );\n\n const { iconName, width, height, svgPathData } = icon;\n const formattedIconName = iconName.split(\"-\").join(\" \");\n\n const defaultTitle = `${capitaliseFirstLetter(formattedIconName)} icon`;\n const titleText = title || defaultTitle;\n\n return (\n <svg\n ref={ref}\n focusable=\"false\"\n data-icon={iconName}\n className={classes}\n role=\"img\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox={`0 0 ${width} ${height}`}\n style={{ color }}\n {...otherProps}\n >\n <title>{titleText}</title>\n <path fill=\"currentColor\" d={svgPathData} />\n </svg>\n );\n}\n", "import classNames from \"classnames/dedupe\";\nimport type { RefAttributes } from \"react\";\nimport { useMemo } from \"react\";\nimport type { TextElementType, TextProps } from \"../Text/Text\";\nimport { Text, getElementType } from \"../Text/Text\";\n\nexport type HTMLElementType = \"span\" | \"div\";\n\nconst isBlockHTML = (text: string) => /^\\s*<[a-z]/i.test(text);\nconst containsHTML = (text: string) =>\n /<[a-z/]/i.test(text) || /&(?:#\\d+|#x[\\da-f]+|[a-z]\\w*);/i.test(text); // tag or entity\n\nconst buildTextClasses = (\n textProps: Omit<TextProps, \"children\">,\n htmlClassName?: string,\n) => {\n const { variant, elementType, spacing, className } = textProps;\n const variantType = variant || getElementType(variant, elementType);\n return classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n htmlClassName,\n );\n};\n\nexport interface TextOrHTMLProps\n extends Omit<TextProps, \"children\">, RefAttributes<TextElementType> {\n /** HTML string to be rendered with dangerouslySetInnerHTML */\n text: string;\n /** Custom class name for the dangerous HTML element */\n htmlClassName?: string;\n /** HTML element type for the dangerous HTML element */\n htmlElementType?: HTMLElementType;\n /** If true, wraps the dangerous HTML element inside a Text component */\n textWrapper?: boolean;\n /** If true, auto-detects whether text is HTML or plain text to determine wrapping and element type */\n autoDetect?: boolean;\n}\n\nconst TextOrHTML = ({\n ref,\n text,\n htmlClassName,\n htmlElementType,\n textWrapper = false,\n autoDetect = false,\n ...textProps\n}: TextOrHTMLProps) => {\n const textIsBlockHTML = autoDetect && isBlockHTML(text);\n\n // Memoize the dangerouslySetInnerHTML object to prevent unnecessary re-renders\n // See: https://github.com/facebook/react/issues/31660\n const dangerousHTML = useMemo(() => ({ __html: text }), [text]);\n\n // Non-block text with autoDetect: render directly on a Text-equivalent element,\n // avoiding unnecessary <span> nesting inside <p>.\n if (autoDetect && !textIsBlockHTML) {\n const { variant, spacing, elementType, className, ...domProps } = textProps;\n const Element = getElementType(variant, elementType);\n const classes = buildTextClasses(textProps, htmlClassName);\n\n return containsHTML(text) ? (\n <Element\n ref={ref}\n {...domProps}\n className={classes}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n ) : (\n <Element ref={ref} {...domProps} className={classes}>\n {text}\n </Element>\n );\n }\n\n const DangerousComponent =\n htmlElementType ?? (textIsBlockHTML ? \"div\" : \"span\");\n const dangerousElement = (\n <DangerousComponent\n className={htmlClassName}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n );\n\n if (textWrapper) {\n return (\n <Text ref={ref} {...textProps}>\n {dangerousElement}\n </Text>\n );\n }\n\n return dangerousElement;\n};\n\nTextOrHTML.displayName = \"TextOrHTML\";\nexport { TextOrHTML };\n", "import type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Text.css\";\n\nexport type TextElementType = HTMLHeadingElement | HTMLParagraphElement;\nexport type TextVariantType =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"body\"\n | \"small\"\n | \"legal\"\n | \"title\";\nexport type ElementType = \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"p\" | \"span\";\nexport interface TextProps extends DOMProps, RefAttributes<TextElementType> {\n /** HTML element for the text */\n elementType?: ElementType;\n /** Specify font size override */\n variant?: TextVariantType;\n /** Specify compact line height override */\n spacing?: \"loose\" | \"tight\";\n /** Custom class name for setting specific CSS */\n className?: string;\n children: ReactNode;\n style?: React.CSSProperties;\n}\n\nexport const getElementType = (\n variant: TextVariantType | undefined,\n elementType: ElementType | undefined,\n): ElementType => {\n // Explicit elementType always wins\n if (elementType) {\n return elementType;\n }\n // Infer element from variant\n if (variant && [\"h1\", \"h2\", \"h3\", \"h4\"].includes(variant)) {\n return variant as ElementType;\n }\n return \"p\";\n};\n\nconst Text = ({ ref, elementType, ...props }: TextProps) => {\n // Remove non-DOM props from element\n const { variant, className, spacing, ...otherProps } = props;\n\n // If a variant is supplied, set the class name and element type\n const Element: ElementType = getElementType(variant, elementType);\n const variantType = variant || Element;\n const classes = classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nText.displayName = \"Text\";\nexport { Text };\n", "import type React from \"react\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Label.css\";\n\nexport type LabelElementType = HTMLLabelElement;\nexport type IntrinsicLabel = Omit<\n React.JSX.IntrinsicElements[\"label\"],\n \"css\" | \"color\" | \"ref\"\n>;\n\nexport interface LabelProps\n extends IntrinsicLabel, DOMProps, RefAttributes<LabelElementType> {\n children?: ReactNode;\n className?: string;\n elementType?: \"label\" | \"span\";\n}\n\nconst Label = ({ ref, ...props }: LabelProps) => {\n const { elementType: Element = \"label\", children, ...otherProps } = props;\n\n const classes = classNames(\"mobius\", \"mobius-label\", props.className);\n otherProps.className = classes;\n\n return (\n <Element ref={ref} {...otherProps} className={classes}>\n {children}\n </Element>\n );\n};\n\nLabel.displayName = \"Label\";\nexport { Label };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAAA,iBAAuB;AAEvB,IAAAC,gBAMO;;;ACVP,mBAAsB;AACtB,IAAAC,iBAAuB;;;ACDvB,oBAAuB;AAEvB,kBAAO;AA2CH;AAzCJ,IAAM,cAAc;AAEpB,IAAM,wBAAwB,CAAC,QAC7B,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAEpC,SAAS,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAc;AACZ,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AAEA,QAAM,cAAU,cAAAC;AAAA,IACd;AAAA,IACA;AAAA,IACA,eAAe,WAAW;AAAA,IAC1B,UAAU,IAAI;AAAA,IACd;AAAA,IACA;AAAA,MACE,CAAC,GAAG,WAAW,KAAK,GAAG;AAAA,MACvB,CAAC,GAAG,WAAW,OAAO,GAAG,QAAQ;AAAA,MACjC,CAAC,GAAG,WAAW,eAAe,GAAG;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,EAAE,UAAU,OAAO,QAAQ,YAAY,IAAI;AACjD,QAAM,oBAAoB,SAAS,MAAM,GAAG,EAAE,KAAK,GAAG;AAEtD,QAAM,eAAe,GAAG,sBAAsB,iBAAiB,CAAC;AAChE,QAAM,YAAY,SAAS;AAE3B,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MACV,aAAW;AAAA,MACX,WAAW;AAAA,MACX,MAAK;AAAA,MACL,OAAM;AAAA,MACN,SAAS,OAAO,KAAK,IAAI,MAAM;AAAA,MAC/B,OAAO,EAAE,MAAM;AAAA,MACd,GAAG;AAAA,MAEJ;AAAA,oDAAC,WAAO,qBAAU;AAAA,QAClB,4CAAC,UAAK,MAAK,gBAAe,GAAG,aAAa;AAAA;AAAA;AAAA,EAC5C;AAEJ;;;AC5DA,IAAAC,iBAAuB;AAEvB,mBAAwB;;;ACDxB,IAAAC,iBAAuB;AAEvB,kBAAO;AAwDE,IAAAC,sBAAA;AA9BF,IAAM,iBAAiB,CAC5B,SACA,gBACgB;AAEhB,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,CAAC,MAAM,MAAM,MAAM,IAAI,EAAE,SAAS,OAAO,GAAG;AACzD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,IAAM,OAAO,CAAC,EAAE,KAAK,aAAa,GAAG,MAAM,MAAiB;AAE1D,QAAM,EAAE,SAAS,WAAW,SAAS,GAAG,WAAW,IAAI;AAGvD,QAAM,UAAuB,eAAe,SAAS,WAAW;AAChE,QAAM,cAAc,WAAW;AAC/B,QAAM,cAAU,eAAAC;AAAA,IACd;AAAA,IACA;AAAA,IACA,EAAE,CAAC,QAAQ,WAAW,EAAE,GAAG,YAAY;AAAA,IACvC,EAAE,CAAC,qBAAqB,OAAO,EAAE,GAAG,QAAQ;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO,6CAAC,WAAQ,KAAW,GAAG,YAAY,WAAW,SAAS;AAChE;AAEA,KAAK,cAAc;;;
|
|
4
|
+
"sourcesContent": ["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport {\n Children,\n isValidElement,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { HTMLElementEvent } from \"../../types/events\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport \"./Radio.css\";\n\nexport type RadioElementType = HTMLInputElement;\n\nexport type RadioOverflowInfo = {\n vertical: boolean;\n horizontal: boolean;\n};\n\nexport type AriaRadioProps = {\n /**\n * Defines a string value that labels the current element.\n */\n \"aria-label\"?: string;\n /**\n * Identifies the element (or elements) that labels the current element.\n */\n \"aria-labelledby\"?: string;\n /**\n * Identifies the element (or elements) that describes the object.\n */\n \"aria-describedby\"?: string;\n /**\n * Identifies the element (or elements) that provide a detailed, extended description for the object.\n */\n \"aria-details\"?: string;\n};\n\nexport interface RadioProps\n extends DOMProps, AriaRadioProps, RefAttributes<RadioElementType> {\n children?: ReactNode;\n className?: string;\n label?: ReactNode;\n errorMessage?: string;\n value: string;\n isDisabled?: boolean;\n onChange?: (event: HTMLElementEvent<RadioElementType>) => void;\n defaultChecked?: boolean;\n /**\n * Callback fired when label overflow state changes.\n * Only invoked when the Radio is in horizontal orientation to prevent infinite loops with autoStack.\n * Provides information about vertical and horizontal overflow.\n */\n onOverflow?: (overflow: RadioOverflowInfo) => void;\n // Internal:** Do not use\n groupDisabled?: boolean;\n // Internal:** Do not use\n name?: string;\n // Internal:** Do not use\n selected?: string;\n // Internal:** Do not use\n setSelected?: React.Dispatch<React.SetStateAction<string>>;\n isRequired?: boolean;\n /**\n * **Internal:** Passed via cloneElement from RadioGroup.\n * @internal\n */\n orientation?: \"horizontal\" | \"vertical\";\n}\n\nconst Radio = ({ ref, ...props }: RadioProps) => {\n const {\n children,\n value,\n label,\n className,\n isDisabled,\n errorMessage,\n onChange,\n defaultChecked,\n groupDisabled,\n name,\n selected,\n setSelected,\n isRequired,\n onOverflow,\n orientation,\n ...otherProps\n } = props;\n const realDisabled = groupDisabled || isDisabled;\n const isMultiline = label && children;\n const isControlled = selected !== undefined;\n const isChecked = isControlled ? selected === value : defaultChecked;\n\n const contentRef = useRef<HTMLDivElement>(null);\n const prevOverflowRef = useRef<RadioOverflowInfo>({\n vertical: false,\n horizontal: false,\n });\n\n const hasIconFirst = useMemo(() => {\n if (!children || Children.count(children) === 0) return false;\n\n const firstChild = Children.toArray(children)[0];\n if (!isValidElement(firstChild)) return false;\n\n const props = firstChild.props as Record<string, unknown>;\n return \"icon\" in props && props.icon !== undefined;\n }, [children]);\n\n // Detect overflow and call callback\n useLayoutEffect(() => {\n if (!contentRef.current || !onOverflow) return;\n\n // Only detect overflow when in horizontal orientation\n // This prevents infinite loops when autoStack switches to vertical\n if (orientation === \"vertical\") {\n return;\n }\n\n const element = contentRef.current;\n\n // Check for content being cut off (true overflow)\n const scrollOverflowVertical = element.scrollHeight > element.clientHeight;\n const scrollOverflowHorizontal = element.scrollWidth > element.clientWidth;\n\n // Check for multi-line text wrapping by comparing height to single line height\n const styles = window.getComputedStyle(element);\n const lineHeight = parseFloat(styles.lineHeight);\n const fontSize = parseFloat(styles.fontSize);\n const singleLineHeight = isNaN(lineHeight) ? fontSize * 1.2 : lineHeight;\n\n // Tolerance multiplier to account for sub-pixel rendering and line-height variations.\n // If element height is greater than single line, text has wrapped.\n const WRAP_DETECTION_TOLERANCE = 1.1;\n const hasWrapped =\n element.clientHeight > singleLineHeight * WRAP_DETECTION_TOLERANCE;\n\n const vertical = scrollOverflowVertical || hasWrapped;\n const horizontal = scrollOverflowHorizontal;\n\n const newOverflowState = { vertical, horizontal };\n const prevOverflow = prevOverflowRef.current;\n\n // Only call callback if state actually changed\n if (\n newOverflowState.vertical !== prevOverflow.vertical ||\n newOverflowState.horizontal !== prevOverflow.horizontal\n ) {\n prevOverflowRef.current = newOverflowState;\n onOverflow(newOverflowState);\n }\n }, [label, children, onOverflow, orientation]);\n\n const radioClasses = {\n \"--is-disabled\": realDisabled,\n \"--is-selected\": selected === value,\n \"--is-multiline\": !!isMultiline,\n \"--is-required\": isRequired,\n };\n const containerClasses = classNames(\n \"mobius-radio__label\",\n radioClasses,\n className,\n { \"--has-icon-first\": hasIconFirst },\n );\n\n const inputClasses = classNames(\"mobius-radio__input\", radioClasses);\n\n // Exclude props that are passed via cloneElement in `<RadioGroup />`\n const { \"aria-describedby\": _ariaDescribedBy, ...rest } = otherProps;\n\n // Handle all interactions through onChange event\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n // Update internal state for RadioGroup\n if (setSelected) {\n setSelected(event.target.value);\n }\n\n // Call parent onChange callback\n if (onChange) {\n // Create an HTMLElementEvent-compatible object\n const adaptedEvent: HTMLElementEvent<HTMLInputElement> = {\n ...event.nativeEvent,\n target: event.target,\n };\n onChange(adaptedEvent);\n }\n };\n\n return (\n <>\n <Label className={containerClasses}>\n <input\n aria-describedby={otherProps[\"aria-describedby\"]}\n disabled={realDisabled}\n ref={ref}\n className={inputClasses}\n value={value}\n tabIndex={0}\n type=\"radio\"\n onChange={handleChange}\n {...(isControlled\n ? { checked: isChecked }\n : { defaultChecked: isChecked })}\n name={name}\n required={isRequired}\n {...rest}\n />\n {isMultiline ? (\n <div ref={contentRef} className=\"mobius-radio__content--multiline\">\n <div className=\"mobius-radio__content-first-line\">{label}</div>\n <div className=\"mobius-radio__extra-content\">{children}</div>\n </div>\n ) : (\n <div ref={contentRef} className=\"mobius-radio__content\">\n {label || children}\n </div>\n )}\n </Label>\n {errorMessage && <ErrorMessage errorMessage={errorMessage} />}\n </>\n );\n};\n\nRadio.displayName = \"Radio\";\nexport { Radio };\n", "import { error } from \"@simplybusiness/icons\";\nimport classNames from \"classnames/dedupe\";\nimport { Icon } from \"../Icon\";\nimport { TextOrHTML } from \"../TextOrHTML\";\nimport \"./ErrorMessage.css\";\n\nexport interface ErrorMessageProps {\n errorMessage?: string;\n id?: string;\n className?: string;\n}\n\nexport const ErrorMessage = ({\n id,\n errorMessage,\n className,\n}: ErrorMessageProps) => {\n const classes = classNames(\"mobius\", \"mobius-error-message\", className);\n\n if (!errorMessage) return null;\n\n return (\n <div id={id} className={classes} data-testid=\"ErrorMessage\" role=\"alert\">\n <Icon\n icon={error}\n className=\"mobius-error-message__icon\"\n aria-hidden=\"true\"\n />\n <TextOrHTML\n elementType=\"span\"\n className=\"mobius-error-message__text\"\n text={errorMessage}\n />\n </div>\n );\n};\n\nErrorMessage.displayName = \"ErrorMessage\";\n", "import classNames from \"classnames/dedupe\";\nimport type { IconProps } from \"./types\";\nimport \"./Icon.css\";\n\nconst ICON_PREFIX = \"mobius-icon\";\n\nconst capitaliseFirstLetter = (str: string) =>\n str.charAt(0).toUpperCase() + str.slice(1);\n\nexport function Icon({\n ref,\n icon,\n className,\n size = \"xs\",\n color,\n fixedWidth,\n spin,\n spinReverse,\n title,\n ...otherProps\n}: IconProps) {\n if (!icon) {\n throw new Error(\"Must specify icon object\");\n }\n\n const classes = classNames(\n \"mobius\",\n \"mobius-icon\",\n `svg-inline--${ICON_PREFIX}`,\n `--size-${size}`,\n className,\n {\n [`${ICON_PREFIX}-fw`]: fixedWidth,\n [`${ICON_PREFIX}-spin`]: spin || spinReverse,\n [`${ICON_PREFIX}-spin-reverse`]: spinReverse,\n },\n );\n\n const { iconName, width, height, svgPathData } = icon;\n const formattedIconName = iconName.split(\"-\").join(\" \");\n\n const defaultTitle = `${capitaliseFirstLetter(formattedIconName)} icon`;\n const titleText = title || defaultTitle;\n\n return (\n <svg\n ref={ref}\n focusable=\"false\"\n data-icon={iconName}\n className={classes}\n role=\"img\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox={`0 0 ${width} ${height}`}\n style={{ color }}\n {...otherProps}\n >\n <title>{titleText}</title>\n <path fill=\"currentColor\" d={svgPathData} />\n </svg>\n );\n}\n", "import classNames from \"classnames/dedupe\";\nimport type { RefAttributes } from \"react\";\nimport { useMemo } from \"react\";\nimport type { TextElementType, TextProps } from \"../Text/Text\";\nimport { Text, getElementType } from \"../Text/Text\";\n\nexport type HTMLElementType = \"span\" | \"div\";\n\n// Block-level tags that cannot be nested inside <p>.\nconst BLOCK_TAG =\n /<(div|p|ul|ol|li|h[1-6]|table|tr|td|th|blockquote|pre|hr|dl|dt|dd)[\\s>/]/i;\nconst containsBlockHTML = (text: string) => BLOCK_TAG.test(text);\nconst containsHTML = (text: string) =>\n /<[a-z/]/i.test(text) || /&(?:#\\d+|#x[\\da-f]+|[a-z]\\w*);/i.test(text); // tag or entity\n\nconst buildTextClasses = (\n textProps: Omit<TextProps, \"children\">,\n htmlClassName?: string,\n) => {\n const { variant, elementType, spacing, className } = textProps;\n const variantType = variant || getElementType(variant, elementType);\n return classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n htmlClassName,\n );\n};\n\nexport interface TextOrHTMLProps\n extends Omit<TextProps, \"children\">, RefAttributes<TextElementType> {\n /** HTML string to be rendered with dangerouslySetInnerHTML */\n text: string;\n /** Custom class name for the dangerous HTML element */\n htmlClassName?: string;\n /** HTML element type for the dangerous HTML element */\n htmlElementType?: HTMLElementType;\n /** If true, wraps the dangerous HTML element inside a Text component */\n textWrapper?: boolean;\n /** If true, auto-detects whether text is HTML or plain text to determine wrapping and element type */\n autoDetect?: boolean;\n}\n\nconst TextOrHTML = ({\n ref,\n text,\n htmlClassName,\n htmlElementType,\n textWrapper = false,\n autoDetect = false,\n ...textProps\n}: TextOrHTMLProps) => {\n const hasBlockContent = autoDetect && containsBlockHTML(text);\n\n // Memoize the dangerouslySetInnerHTML object to prevent unnecessary re-renders\n // See: https://github.com/facebook/react/issues/31660\n const dangerousHTML = useMemo(() => ({ __html: text }), [text]);\n\n // Non-block text with autoDetect: render directly on a Text-equivalent element,\n // avoiding unnecessary <span> nesting inside <p>.\n if (autoDetect && !hasBlockContent) {\n const { variant, spacing, elementType, className, ...domProps } = textProps;\n const Element = getElementType(variant, elementType);\n const classes = buildTextClasses(textProps, htmlClassName);\n\n return containsHTML(text) ? (\n <Element\n ref={ref}\n {...domProps}\n className={classes}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n ) : (\n <Element ref={ref} {...domProps} className={classes}>\n {text}\n </Element>\n );\n }\n\n const DangerousComponent =\n htmlElementType ?? (hasBlockContent ? \"div\" : \"span\");\n const dangerousElement = (\n <DangerousComponent\n className={htmlClassName}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n );\n\n if (textWrapper) {\n return (\n <Text ref={ref} {...textProps}>\n {dangerousElement}\n </Text>\n );\n }\n\n return dangerousElement;\n};\n\nTextOrHTML.displayName = \"TextOrHTML\";\nexport { TextOrHTML };\n", "import type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Text.css\";\n\nexport type TextElementType = HTMLHeadingElement | HTMLParagraphElement;\nexport type TextVariantType =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"body\"\n | \"small\"\n | \"legal\"\n | \"title\";\nexport type ElementType = \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"p\" | \"span\";\nexport interface TextProps extends DOMProps, RefAttributes<TextElementType> {\n /** HTML element for the text */\n elementType?: ElementType;\n /** Specify font size override */\n variant?: TextVariantType;\n /** Specify compact line height override */\n spacing?: \"loose\" | \"tight\";\n /** Custom class name for setting specific CSS */\n className?: string;\n children: ReactNode;\n style?: React.CSSProperties;\n}\n\nexport const getElementType = (\n variant: TextVariantType | undefined,\n elementType: ElementType | undefined,\n): ElementType => {\n // Explicit elementType always wins\n if (elementType) {\n return elementType;\n }\n // Infer element from variant\n if (variant && [\"h1\", \"h2\", \"h3\", \"h4\"].includes(variant)) {\n return variant as ElementType;\n }\n return \"p\";\n};\n\nconst Text = ({ ref, elementType, ...props }: TextProps) => {\n // Remove non-DOM props from element\n const { variant, className, spacing, ...otherProps } = props;\n\n // If a variant is supplied, set the class name and element type\n const Element: ElementType = getElementType(variant, elementType);\n const variantType = variant || Element;\n const classes = classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nText.displayName = \"Text\";\nexport { Text };\n", "import type React from \"react\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Label.css\";\n\nexport type LabelElementType = HTMLLabelElement;\nexport type IntrinsicLabel = Omit<\n React.JSX.IntrinsicElements[\"label\"],\n \"css\" | \"color\" | \"ref\"\n>;\n\nexport interface LabelProps\n extends IntrinsicLabel, DOMProps, RefAttributes<LabelElementType> {\n children?: ReactNode;\n className?: string;\n elementType?: \"label\" | \"span\";\n}\n\nconst Label = ({ ref, ...props }: LabelProps) => {\n const { elementType: Element = \"label\", children, ...otherProps } = props;\n\n const classes = classNames(\"mobius\", \"mobius-label\", props.className);\n otherProps.className = classes;\n\n return (\n <Element ref={ref} {...otherProps} className={classes}>\n {children}\n </Element>\n );\n};\n\nLabel.displayName = \"Label\";\nexport { Label };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_dedupe", "import_react", "import_dedupe", "classNames", "import_dedupe", "import_dedupe", "import_jsx_runtime", "classNames", "import_jsx_runtime", "classNames", "import_jsx_runtime", "classNames", "import_dedupe", "import_jsx_runtime", "classNames", "import_jsx_runtime", "props", "classNames"]
|
|
7
7
|
}
|
|
@@ -149,7 +149,8 @@ Text.displayName = "Text";
|
|
|
149
149
|
|
|
150
150
|
// src/components/TextOrHTML/TextOrHTML.tsx
|
|
151
151
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
152
|
-
var
|
|
152
|
+
var BLOCK_TAG = /<(div|p|ul|ol|li|h[1-6]|table|tr|td|th|blockquote|pre|hr|dl|dt|dd)[\s>/]/i;
|
|
153
|
+
var containsBlockHTML = (text) => BLOCK_TAG.test(text);
|
|
153
154
|
var containsHTML = (text) => /<[a-z/]/i.test(text) || /&(?:#\d+|#x[\da-f]+|[a-z]\w*);/i.test(text);
|
|
154
155
|
var buildTextClasses = (textProps, htmlClassName) => {
|
|
155
156
|
const { variant, elementType, spacing, className } = textProps;
|
|
@@ -172,9 +173,9 @@ var TextOrHTML = ({
|
|
|
172
173
|
autoDetect = false,
|
|
173
174
|
...textProps
|
|
174
175
|
}) => {
|
|
175
|
-
const
|
|
176
|
+
const hasBlockContent = autoDetect && containsBlockHTML(text);
|
|
176
177
|
const dangerousHTML = (0, import_react.useMemo)(() => ({ __html: text }), [text]);
|
|
177
|
-
if (autoDetect && !
|
|
178
|
+
if (autoDetect && !hasBlockContent) {
|
|
178
179
|
const { variant, spacing, elementType, className, ...domProps } = textProps;
|
|
179
180
|
const Element = getElementType(variant, elementType);
|
|
180
181
|
const classes = buildTextClasses(textProps, htmlClassName);
|
|
@@ -188,7 +189,7 @@ var TextOrHTML = ({
|
|
|
188
189
|
}
|
|
189
190
|
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Element, { ref, ...domProps, className: classes, children: text });
|
|
190
191
|
}
|
|
191
|
-
const DangerousComponent = htmlElementType ?? (
|
|
192
|
+
const DangerousComponent = htmlElementType ?? (hasBlockContent ? "div" : "span");
|
|
192
193
|
const dangerousElement = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
193
194
|
DangerousComponent,
|
|
194
195
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/Radio/RadioGroup.tsx", "../../../../src/utils/spaceDelimitedList.ts", "../../../../src/hooks/useValidationClasses/useValidationClasses.ts", "../../../../src/components/ErrorMessage/ErrorMessage.tsx", "../../../../src/components/Icon/Icon.tsx", "../../../../src/components/TextOrHTML/TextOrHTML.tsx", "../../../../src/components/Text/Text.tsx", "../../../../src/components/Label/Label.tsx", "../../../../src/components/Stack/Stack.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport type { ReactElement, ReactNode, RefAttributes } from \"react\";\nimport {\n Children,\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { useValidationClasses } from \"../../hooks\";\nimport type { Validation } from \"../../types\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { HTMLElementEvent } from \"../../types/events\";\nimport { spaceDelimitedList } from \"../../utils/spaceDelimitedList\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Stack } from \"../Stack\";\nimport type { RadioOverflowInfo } from \"./Radio\";\n\nexport type RadioGroupElementType = HTMLDivElement;\n\nexport interface RadioGroupProps\n extends DOMProps, Validation, RefAttributes<RadioGroupElementType> {\n children: ReactNode;\n className?: string;\n orientation?: \"horizontal\" | \"vertical\";\n errorMessage?: string;\n // Callback that fires when select changes\n onChange?: (event: HTMLElementEvent<HTMLInputElement>) => void;\n /**\n * Automatically change orientation from horizontal to vertical when any Radio label overflows.\n * Only applies when orientation is set to \"horizontal\".\n */\n autoStack?: boolean;\n // Defines a string value that labels the current element.\n \"aria-label\"?: string;\n // Identifies the element (or elements) that labels the current element.\n \"aria-labelledby\"?: string;\n // Identifies the element that provides an error message for the object.\n \"aria-errormessage\"?: string;\n // Identifies the element (or elements) that describes the object.\n \"aria-describedby\"?: string;\n // Whether user input is required on the input before form submission.\n isRequired?: boolean;\n // Whether the input is disabled.\n isDisabled?: boolean;\n // Whether the input can be selected but not changed by the user.\n isReadOnly?: boolean;\n // The default value (uncontrolled).\n defaultValue?: string;\n // The content to display as the label.\n label?: ReactNode;\n /**\n * The value of the radio button, used when submitting an HTML form.\n * See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio#Value).\n */\n value?: string;\n name?: string;\n}\n\nconst getDefaultVal = (children: ReactNode, defaultValue?: string) => {\n if (Array.isArray(children) && defaultValue) {\n const option = children?.find(item => item.props.value === defaultValue);\n\n if (!option) return \"\";\n\n return option.props.value;\n }\n\n return \"\";\n};\n\nconst RadioGroup = ({ ref, ...props }: RadioGroupProps) => {\n const {\n label,\n isDisabled = false,\n isRequired,\n isInvalid,\n orientation = \"vertical\",\n className,\n errorMessage,\n children,\n defaultValue,\n value,\n isReadOnly,\n name,\n onChange,\n autoStack = false,\n ...rest\n } = props;\n const defaultSelected = getDefaultVal(children, value || defaultValue);\n const [selected, setSelected] = useState<string>(defaultSelected);\n const overflowsRef = useRef<Record<string, RadioOverflowInfo>>({});\n const [hasOverflow, setHasOverflow] = useState(false);\n\n // Handle controlled behavior - update state when value prop changes\n useEffect(() => {\n if (value !== undefined) {\n setSelected(value);\n }\n }, [value]);\n\n // Handle overflow detection and auto-stack if needed\n const handleOverflow = useCallback(\n (radioValue: string, overflow: RadioOverflowInfo) => {\n overflowsRef.current = {\n ...overflowsRef.current,\n [radioValue]: overflow,\n };\n\n // Check if any radio has overflow\n const anyOverflow = Object.values(overflowsRef.current).some(\n o => o.vertical || o.horizontal,\n );\n\n if (anyOverflow !== hasOverflow) {\n setHasOverflow(anyOverflow);\n }\n },\n [hasOverflow],\n );\n\n // Determine effective orientation (auto-stack if needed)\n const effectiveOrientation =\n autoStack && orientation === \"horizontal\" && hasOverflow\n ? \"vertical\"\n : orientation;\n\n const validationClasses = useValidationClasses({ isInvalid });\n const radioClasses = {\n \"--is-disabled\": isDisabled,\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n [`--is-${effectiveOrientation}`]: true,\n [className || \"\"]: true,\n };\n const radioGroupClasses = classNames(\n \"mobius\",\n \"mobius-radio-group\",\n radioClasses,\n validationClasses,\n );\n const radioWrapperClasses = classNames(\"mobius-radio__wrapper\", {\n [`--is-${effectiveOrientation}`]: true,\n });\n const labelClasses = classNames(radioClasses, validationClasses);\n const errorMessageId = useId();\n const defaultNameAttrId = useId();\n const nameAttribute = name || defaultNameAttrId;\n const shouldErrorMessageShow = errorMessage ? errorMessageId : undefined;\n const describedBy = spaceDelimitedList([\n shouldErrorMessageShow,\n props[\"aria-describedby\"],\n ]);\n const labelId = useId();\n\n return (\n <div\n {...rest}\n aria-describedby={describedBy}\n aria-disabled={isDisabled}\n aria-errormessage={shouldErrorMessageShow}\n aria-invalid={isInvalid}\n aria-label={props[\"aria-label\"]}\n aria-labelledby={props[\"aria-labelledby\"] || labelId}\n aria-orientation={effectiveOrientation}\n aria-readonly={isReadOnly}\n aria-required={isRequired}\n ref={ref}\n className={radioGroupClasses}\n role=\"radiogroup\"\n >\n <Stack gap=\"xs\">\n {label && (\n <Label htmlFor={name} id={labelId} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className={radioWrapperClasses}>\n {Children.map(children, child => {\n if (isValidElement(child)) {\n const childValue = (child.props as { value?: string }).value;\n return cloneElement(\n child as ReactElement,\n {\n orientation: effectiveOrientation,\n groupDisabled: isDisabled,\n name: nameAttribute,\n selected: selected || defaultSelected, // in case state does not update\n setSelected,\n isRequired,\n \"aria-describedby\": describedBy,\n onChange,\n onOverflow: childValue\n ? (overflow: RadioOverflowInfo) =>\n handleOverflow(childValue, overflow)\n : undefined,\n } as Record<string, unknown>,\n );\n }\n\n return child;\n })}\n </div>\n <ErrorMessage id={errorMessageId} errorMessage={errorMessage} />\n </Stack>\n </div>\n );\n};\n\nRadioGroup.displayName = \"RadioGroup\";\nexport { RadioGroup };\n", "export function spaceDelimitedList(\n list: (string | null | undefined)[],\n): string | undefined {\n return list.filter(Boolean).join(\" \") || undefined;\n}\n", "import type { Validation } from \"../../types\";\n\nexport type GetValidationClassesProps = Pick<Validation, \"isInvalid\">;\n\nexport const useValidationClasses = (props: GetValidationClassesProps) => {\n const { isInvalid } = props;\n\n if (isInvalid) {\n return \"--is-invalid\";\n }\n\n if (isInvalid === false) {\n return \"--is-valid\";\n }\n\n return \"\";\n};\n", "import { error } from \"@simplybusiness/icons\";\nimport classNames from \"classnames/dedupe\";\nimport { Icon } from \"../Icon\";\nimport { TextOrHTML } from \"../TextOrHTML\";\nimport \"./ErrorMessage.css\";\n\nexport interface ErrorMessageProps {\n errorMessage?: string;\n id?: string;\n className?: string;\n}\n\nexport const ErrorMessage = ({\n id,\n errorMessage,\n className,\n}: ErrorMessageProps) => {\n const classes = classNames(\"mobius\", \"mobius-error-message\", className);\n\n if (!errorMessage) return null;\n\n return (\n <div id={id} className={classes} data-testid=\"ErrorMessage\" role=\"alert\">\n <Icon\n icon={error}\n className=\"mobius-error-message__icon\"\n aria-hidden=\"true\"\n />\n <TextOrHTML\n elementType=\"span\"\n className=\"mobius-error-message__text\"\n text={errorMessage}\n />\n </div>\n );\n};\n\nErrorMessage.displayName = \"ErrorMessage\";\n", "import classNames from \"classnames/dedupe\";\nimport type { IconProps } from \"./types\";\nimport \"./Icon.css\";\n\nconst ICON_PREFIX = \"mobius-icon\";\n\nconst capitaliseFirstLetter = (str: string) =>\n str.charAt(0).toUpperCase() + str.slice(1);\n\nexport function Icon({\n ref,\n icon,\n className,\n size = \"xs\",\n color,\n fixedWidth,\n spin,\n spinReverse,\n title,\n ...otherProps\n}: IconProps) {\n if (!icon) {\n throw new Error(\"Must specify icon object\");\n }\n\n const classes = classNames(\n \"mobius\",\n \"mobius-icon\",\n `svg-inline--${ICON_PREFIX}`,\n `--size-${size}`,\n className,\n {\n [`${ICON_PREFIX}-fw`]: fixedWidth,\n [`${ICON_PREFIX}-spin`]: spin || spinReverse,\n [`${ICON_PREFIX}-spin-reverse`]: spinReverse,\n },\n );\n\n const { iconName, width, height, svgPathData } = icon;\n const formattedIconName = iconName.split(\"-\").join(\" \");\n\n const defaultTitle = `${capitaliseFirstLetter(formattedIconName)} icon`;\n const titleText = title || defaultTitle;\n\n return (\n <svg\n ref={ref}\n focusable=\"false\"\n data-icon={iconName}\n className={classes}\n role=\"img\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox={`0 0 ${width} ${height}`}\n style={{ color }}\n {...otherProps}\n >\n <title>{titleText}</title>\n <path fill=\"currentColor\" d={svgPathData} />\n </svg>\n );\n}\n", "import classNames from \"classnames/dedupe\";\nimport type { RefAttributes } from \"react\";\nimport { useMemo } from \"react\";\nimport type { TextElementType, TextProps } from \"../Text/Text\";\nimport { Text, getElementType } from \"../Text/Text\";\n\nexport type HTMLElementType = \"span\" | \"div\";\n\nconst isBlockHTML = (text: string) => /^\\s*<[a-z]/i.test(text);\nconst containsHTML = (text: string) =>\n /<[a-z/]/i.test(text) || /&(?:#\\d+|#x[\\da-f]+|[a-z]\\w*);/i.test(text); // tag or entity\n\nconst buildTextClasses = (\n textProps: Omit<TextProps, \"children\">,\n htmlClassName?: string,\n) => {\n const { variant, elementType, spacing, className } = textProps;\n const variantType = variant || getElementType(variant, elementType);\n return classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n htmlClassName,\n );\n};\n\nexport interface TextOrHTMLProps\n extends Omit<TextProps, \"children\">, RefAttributes<TextElementType> {\n /** HTML string to be rendered with dangerouslySetInnerHTML */\n text: string;\n /** Custom class name for the dangerous HTML element */\n htmlClassName?: string;\n /** HTML element type for the dangerous HTML element */\n htmlElementType?: HTMLElementType;\n /** If true, wraps the dangerous HTML element inside a Text component */\n textWrapper?: boolean;\n /** If true, auto-detects whether text is HTML or plain text to determine wrapping and element type */\n autoDetect?: boolean;\n}\n\nconst TextOrHTML = ({\n ref,\n text,\n htmlClassName,\n htmlElementType,\n textWrapper = false,\n autoDetect = false,\n ...textProps\n}: TextOrHTMLProps) => {\n const textIsBlockHTML = autoDetect && isBlockHTML(text);\n\n // Memoize the dangerouslySetInnerHTML object to prevent unnecessary re-renders\n // See: https://github.com/facebook/react/issues/31660\n const dangerousHTML = useMemo(() => ({ __html: text }), [text]);\n\n // Non-block text with autoDetect: render directly on a Text-equivalent element,\n // avoiding unnecessary <span> nesting inside <p>.\n if (autoDetect && !textIsBlockHTML) {\n const { variant, spacing, elementType, className, ...domProps } = textProps;\n const Element = getElementType(variant, elementType);\n const classes = buildTextClasses(textProps, htmlClassName);\n\n return containsHTML(text) ? (\n <Element\n ref={ref}\n {...domProps}\n className={classes}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n ) : (\n <Element ref={ref} {...domProps} className={classes}>\n {text}\n </Element>\n );\n }\n\n const DangerousComponent =\n htmlElementType ?? (textIsBlockHTML ? \"div\" : \"span\");\n const dangerousElement = (\n <DangerousComponent\n className={htmlClassName}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n );\n\n if (textWrapper) {\n return (\n <Text ref={ref} {...textProps}>\n {dangerousElement}\n </Text>\n );\n }\n\n return dangerousElement;\n};\n\nTextOrHTML.displayName = \"TextOrHTML\";\nexport { TextOrHTML };\n", "import type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Text.css\";\n\nexport type TextElementType = HTMLHeadingElement | HTMLParagraphElement;\nexport type TextVariantType =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"body\"\n | \"small\"\n | \"legal\"\n | \"title\";\nexport type ElementType = \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"p\" | \"span\";\nexport interface TextProps extends DOMProps, RefAttributes<TextElementType> {\n /** HTML element for the text */\n elementType?: ElementType;\n /** Specify font size override */\n variant?: TextVariantType;\n /** Specify compact line height override */\n spacing?: \"loose\" | \"tight\";\n /** Custom class name for setting specific CSS */\n className?: string;\n children: ReactNode;\n style?: React.CSSProperties;\n}\n\nexport const getElementType = (\n variant: TextVariantType | undefined,\n elementType: ElementType | undefined,\n): ElementType => {\n // Explicit elementType always wins\n if (elementType) {\n return elementType;\n }\n // Infer element from variant\n if (variant && [\"h1\", \"h2\", \"h3\", \"h4\"].includes(variant)) {\n return variant as ElementType;\n }\n return \"p\";\n};\n\nconst Text = ({ ref, elementType, ...props }: TextProps) => {\n // Remove non-DOM props from element\n const { variant, className, spacing, ...otherProps } = props;\n\n // If a variant is supplied, set the class name and element type\n const Element: ElementType = getElementType(variant, elementType);\n const variantType = variant || Element;\n const classes = classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nText.displayName = \"Text\";\nexport { Text };\n", "import type React from \"react\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Label.css\";\n\nexport type LabelElementType = HTMLLabelElement;\nexport type IntrinsicLabel = Omit<\n React.JSX.IntrinsicElements[\"label\"],\n \"css\" | \"color\" | \"ref\"\n>;\n\nexport interface LabelProps\n extends IntrinsicLabel, DOMProps, RefAttributes<LabelElementType> {\n children?: ReactNode;\n className?: string;\n elementType?: \"label\" | \"span\";\n}\n\nconst Label = ({ ref, ...props }: LabelProps) => {\n const { elementType: Element = \"label\", children, ...otherProps } = props;\n\n const classes = classNames(\"mobius\", \"mobius-label\", props.className);\n otherProps.className = classes;\n\n return (\n <Element ref={ref} {...otherProps} className={classes}>\n {children}\n </Element>\n );\n};\n\nLabel.displayName = \"Label\";\nexport { Label };\n", "import type { Ref, RefAttributes, ReactNode } from \"react\";\nimport type React from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { SpacingType } from \"../../types\";\nimport \"./Stack.css\";\n\nexport type StackElementType = HTMLDivElement;\n\nexport interface StackProps extends DOMProps, RefAttributes<StackElementType> {\n children?: ReactNode;\n /** How big a gap between items */\n gap?: SpacingType;\n /** Custom class name for setting specific CSS */\n className?: string;\n elementType?: React.ElementType;\n}\n\nexport type StackRef = Ref<StackElementType>;\n\nexport const Stack = ({ ref, ...props }: StackProps) => {\n const { elementType: Element = \"div\", gap, ...otherProps } = props;\n\n const classes = classNames(\n \"mobius\",\n \"mobius-stack\",\n {\n [`--gap-${gap}`]: gap,\n },\n otherProps.className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nStack.displayName = \"Stack\";\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAAA,iBAAuB;AAEvB,IAAAC,gBASO;;;ACbA,SAAS,mBACd,MACoB;AACpB,SAAO,KAAK,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK;AAC3C;;;ACAO,IAAM,uBAAuB,CAAC,UAAqC;AACxE,QAAM,EAAE,UAAU,IAAI;AAEtB,MAAI,WAAW;AACb,WAAO;AAAA,EACT;AAEA,MAAI,cAAc,OAAO;AACvB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AChBA,mBAAsB;AACtB,IAAAC,iBAAuB;;;ACDvB,oBAAuB;AAEvB,kBAAO;AA2CH;AAzCJ,IAAM,cAAc;AAEpB,IAAM,wBAAwB,CAAC,QAC7B,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAEpC,SAAS,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAc;AACZ,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AAEA,QAAM,cAAU,cAAAC;AAAA,IACd;AAAA,IACA;AAAA,IACA,eAAe,WAAW;AAAA,IAC1B,UAAU,IAAI;AAAA,IACd;AAAA,IACA;AAAA,MACE,CAAC,GAAG,WAAW,KAAK,GAAG;AAAA,MACvB,CAAC,GAAG,WAAW,OAAO,GAAG,QAAQ;AAAA,MACjC,CAAC,GAAG,WAAW,eAAe,GAAG;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,EAAE,UAAU,OAAO,QAAQ,YAAY,IAAI;AACjD,QAAM,oBAAoB,SAAS,MAAM,GAAG,EAAE,KAAK,GAAG;AAEtD,QAAM,eAAe,GAAG,sBAAsB,iBAAiB,CAAC;AAChE,QAAM,YAAY,SAAS;AAE3B,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MACV,aAAW;AAAA,MACX,WAAW;AAAA,MACX,MAAK;AAAA,MACL,OAAM;AAAA,MACN,SAAS,OAAO,KAAK,IAAI,MAAM;AAAA,MAC/B,OAAO,EAAE,MAAM;AAAA,MACd,GAAG;AAAA,MAEJ;AAAA,oDAAC,WAAO,qBAAU;AAAA,QAClB,4CAAC,UAAK,MAAK,gBAAe,GAAG,aAAa;AAAA;AAAA;AAAA,EAC5C;AAEJ;;;AC5DA,IAAAC,iBAAuB;AAEvB,mBAAwB;;;ACDxB,IAAAC,iBAAuB;AAEvB,kBAAO;AAwDE,IAAAC,sBAAA;AA9BF,IAAM,iBAAiB,CAC5B,SACA,gBACgB;AAEhB,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,CAAC,MAAM,MAAM,MAAM,IAAI,EAAE,SAAS,OAAO,GAAG;AACzD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,IAAM,OAAO,CAAC,EAAE,KAAK,aAAa,GAAG,MAAM,MAAiB;AAE1D,QAAM,EAAE,SAAS,WAAW,SAAS,GAAG,WAAW,IAAI;AAGvD,QAAM,UAAuB,eAAe,SAAS,WAAW;AAChE,QAAM,cAAc,WAAW;AAC/B,QAAM,cAAU,eAAAC;AAAA,IACd;AAAA,IACA;AAAA,IACA,EAAE,CAAC,QAAQ,WAAW,EAAE,GAAG,YAAY;AAAA,IACvC,EAAE,CAAC,qBAAqB,OAAO,EAAE,GAAG,QAAQ;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO,6CAAC,WAAQ,KAAW,GAAG,YAAY,WAAW,SAAS;AAChE;AAEA,KAAK,cAAc;;;
|
|
4
|
+
"sourcesContent": ["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport type { ReactElement, ReactNode, RefAttributes } from \"react\";\nimport {\n Children,\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { useValidationClasses } from \"../../hooks\";\nimport type { Validation } from \"../../types\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { HTMLElementEvent } from \"../../types/events\";\nimport { spaceDelimitedList } from \"../../utils/spaceDelimitedList\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Stack } from \"../Stack\";\nimport type { RadioOverflowInfo } from \"./Radio\";\n\nexport type RadioGroupElementType = HTMLDivElement;\n\nexport interface RadioGroupProps\n extends DOMProps, Validation, RefAttributes<RadioGroupElementType> {\n children: ReactNode;\n className?: string;\n orientation?: \"horizontal\" | \"vertical\";\n errorMessage?: string;\n // Callback that fires when select changes\n onChange?: (event: HTMLElementEvent<HTMLInputElement>) => void;\n /**\n * Automatically change orientation from horizontal to vertical when any Radio label overflows.\n * Only applies when orientation is set to \"horizontal\".\n */\n autoStack?: boolean;\n // Defines a string value that labels the current element.\n \"aria-label\"?: string;\n // Identifies the element (or elements) that labels the current element.\n \"aria-labelledby\"?: string;\n // Identifies the element that provides an error message for the object.\n \"aria-errormessage\"?: string;\n // Identifies the element (or elements) that describes the object.\n \"aria-describedby\"?: string;\n // Whether user input is required on the input before form submission.\n isRequired?: boolean;\n // Whether the input is disabled.\n isDisabled?: boolean;\n // Whether the input can be selected but not changed by the user.\n isReadOnly?: boolean;\n // The default value (uncontrolled).\n defaultValue?: string;\n // The content to display as the label.\n label?: ReactNode;\n /**\n * The value of the radio button, used when submitting an HTML form.\n * See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio#Value).\n */\n value?: string;\n name?: string;\n}\n\nconst getDefaultVal = (children: ReactNode, defaultValue?: string) => {\n if (Array.isArray(children) && defaultValue) {\n const option = children?.find(item => item.props.value === defaultValue);\n\n if (!option) return \"\";\n\n return option.props.value;\n }\n\n return \"\";\n};\n\nconst RadioGroup = ({ ref, ...props }: RadioGroupProps) => {\n const {\n label,\n isDisabled = false,\n isRequired,\n isInvalid,\n orientation = \"vertical\",\n className,\n errorMessage,\n children,\n defaultValue,\n value,\n isReadOnly,\n name,\n onChange,\n autoStack = false,\n ...rest\n } = props;\n const defaultSelected = getDefaultVal(children, value || defaultValue);\n const [selected, setSelected] = useState<string>(defaultSelected);\n const overflowsRef = useRef<Record<string, RadioOverflowInfo>>({});\n const [hasOverflow, setHasOverflow] = useState(false);\n\n // Handle controlled behavior - update state when value prop changes\n useEffect(() => {\n if (value !== undefined) {\n setSelected(value);\n }\n }, [value]);\n\n // Handle overflow detection and auto-stack if needed\n const handleOverflow = useCallback(\n (radioValue: string, overflow: RadioOverflowInfo) => {\n overflowsRef.current = {\n ...overflowsRef.current,\n [radioValue]: overflow,\n };\n\n // Check if any radio has overflow\n const anyOverflow = Object.values(overflowsRef.current).some(\n o => o.vertical || o.horizontal,\n );\n\n if (anyOverflow !== hasOverflow) {\n setHasOverflow(anyOverflow);\n }\n },\n [hasOverflow],\n );\n\n // Determine effective orientation (auto-stack if needed)\n const effectiveOrientation =\n autoStack && orientation === \"horizontal\" && hasOverflow\n ? \"vertical\"\n : orientation;\n\n const validationClasses = useValidationClasses({ isInvalid });\n const radioClasses = {\n \"--is-disabled\": isDisabled,\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n [`--is-${effectiveOrientation}`]: true,\n [className || \"\"]: true,\n };\n const radioGroupClasses = classNames(\n \"mobius\",\n \"mobius-radio-group\",\n radioClasses,\n validationClasses,\n );\n const radioWrapperClasses = classNames(\"mobius-radio__wrapper\", {\n [`--is-${effectiveOrientation}`]: true,\n });\n const labelClasses = classNames(radioClasses, validationClasses);\n const errorMessageId = useId();\n const defaultNameAttrId = useId();\n const nameAttribute = name || defaultNameAttrId;\n const shouldErrorMessageShow = errorMessage ? errorMessageId : undefined;\n const describedBy = spaceDelimitedList([\n shouldErrorMessageShow,\n props[\"aria-describedby\"],\n ]);\n const labelId = useId();\n\n return (\n <div\n {...rest}\n aria-describedby={describedBy}\n aria-disabled={isDisabled}\n aria-errormessage={shouldErrorMessageShow}\n aria-invalid={isInvalid}\n aria-label={props[\"aria-label\"]}\n aria-labelledby={props[\"aria-labelledby\"] || labelId}\n aria-orientation={effectiveOrientation}\n aria-readonly={isReadOnly}\n aria-required={isRequired}\n ref={ref}\n className={radioGroupClasses}\n role=\"radiogroup\"\n >\n <Stack gap=\"xs\">\n {label && (\n <Label htmlFor={name} id={labelId} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className={radioWrapperClasses}>\n {Children.map(children, child => {\n if (isValidElement(child)) {\n const childValue = (child.props as { value?: string }).value;\n return cloneElement(\n child as ReactElement,\n {\n orientation: effectiveOrientation,\n groupDisabled: isDisabled,\n name: nameAttribute,\n selected: selected || defaultSelected, // in case state does not update\n setSelected,\n isRequired,\n \"aria-describedby\": describedBy,\n onChange,\n onOverflow: childValue\n ? (overflow: RadioOverflowInfo) =>\n handleOverflow(childValue, overflow)\n : undefined,\n } as Record<string, unknown>,\n );\n }\n\n return child;\n })}\n </div>\n <ErrorMessage id={errorMessageId} errorMessage={errorMessage} />\n </Stack>\n </div>\n );\n};\n\nRadioGroup.displayName = \"RadioGroup\";\nexport { RadioGroup };\n", "export function spaceDelimitedList(\n list: (string | null | undefined)[],\n): string | undefined {\n return list.filter(Boolean).join(\" \") || undefined;\n}\n", "import type { Validation } from \"../../types\";\n\nexport type GetValidationClassesProps = Pick<Validation, \"isInvalid\">;\n\nexport const useValidationClasses = (props: GetValidationClassesProps) => {\n const { isInvalid } = props;\n\n if (isInvalid) {\n return \"--is-invalid\";\n }\n\n if (isInvalid === false) {\n return \"--is-valid\";\n }\n\n return \"\";\n};\n", "import { error } from \"@simplybusiness/icons\";\nimport classNames from \"classnames/dedupe\";\nimport { Icon } from \"../Icon\";\nimport { TextOrHTML } from \"../TextOrHTML\";\nimport \"./ErrorMessage.css\";\n\nexport interface ErrorMessageProps {\n errorMessage?: string;\n id?: string;\n className?: string;\n}\n\nexport const ErrorMessage = ({\n id,\n errorMessage,\n className,\n}: ErrorMessageProps) => {\n const classes = classNames(\"mobius\", \"mobius-error-message\", className);\n\n if (!errorMessage) return null;\n\n return (\n <div id={id} className={classes} data-testid=\"ErrorMessage\" role=\"alert\">\n <Icon\n icon={error}\n className=\"mobius-error-message__icon\"\n aria-hidden=\"true\"\n />\n <TextOrHTML\n elementType=\"span\"\n className=\"mobius-error-message__text\"\n text={errorMessage}\n />\n </div>\n );\n};\n\nErrorMessage.displayName = \"ErrorMessage\";\n", "import classNames from \"classnames/dedupe\";\nimport type { IconProps } from \"./types\";\nimport \"./Icon.css\";\n\nconst ICON_PREFIX = \"mobius-icon\";\n\nconst capitaliseFirstLetter = (str: string) =>\n str.charAt(0).toUpperCase() + str.slice(1);\n\nexport function Icon({\n ref,\n icon,\n className,\n size = \"xs\",\n color,\n fixedWidth,\n spin,\n spinReverse,\n title,\n ...otherProps\n}: IconProps) {\n if (!icon) {\n throw new Error(\"Must specify icon object\");\n }\n\n const classes = classNames(\n \"mobius\",\n \"mobius-icon\",\n `svg-inline--${ICON_PREFIX}`,\n `--size-${size}`,\n className,\n {\n [`${ICON_PREFIX}-fw`]: fixedWidth,\n [`${ICON_PREFIX}-spin`]: spin || spinReverse,\n [`${ICON_PREFIX}-spin-reverse`]: spinReverse,\n },\n );\n\n const { iconName, width, height, svgPathData } = icon;\n const formattedIconName = iconName.split(\"-\").join(\" \");\n\n const defaultTitle = `${capitaliseFirstLetter(formattedIconName)} icon`;\n const titleText = title || defaultTitle;\n\n return (\n <svg\n ref={ref}\n focusable=\"false\"\n data-icon={iconName}\n className={classes}\n role=\"img\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox={`0 0 ${width} ${height}`}\n style={{ color }}\n {...otherProps}\n >\n <title>{titleText}</title>\n <path fill=\"currentColor\" d={svgPathData} />\n </svg>\n );\n}\n", "import classNames from \"classnames/dedupe\";\nimport type { RefAttributes } from \"react\";\nimport { useMemo } from \"react\";\nimport type { TextElementType, TextProps } from \"../Text/Text\";\nimport { Text, getElementType } from \"../Text/Text\";\n\nexport type HTMLElementType = \"span\" | \"div\";\n\n// Block-level tags that cannot be nested inside <p>.\nconst BLOCK_TAG =\n /<(div|p|ul|ol|li|h[1-6]|table|tr|td|th|blockquote|pre|hr|dl|dt|dd)[\\s>/]/i;\nconst containsBlockHTML = (text: string) => BLOCK_TAG.test(text);\nconst containsHTML = (text: string) =>\n /<[a-z/]/i.test(text) || /&(?:#\\d+|#x[\\da-f]+|[a-z]\\w*);/i.test(text); // tag or entity\n\nconst buildTextClasses = (\n textProps: Omit<TextProps, \"children\">,\n htmlClassName?: string,\n) => {\n const { variant, elementType, spacing, className } = textProps;\n const variantType = variant || getElementType(variant, elementType);\n return classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n htmlClassName,\n );\n};\n\nexport interface TextOrHTMLProps\n extends Omit<TextProps, \"children\">, RefAttributes<TextElementType> {\n /** HTML string to be rendered with dangerouslySetInnerHTML */\n text: string;\n /** Custom class name for the dangerous HTML element */\n htmlClassName?: string;\n /** HTML element type for the dangerous HTML element */\n htmlElementType?: HTMLElementType;\n /** If true, wraps the dangerous HTML element inside a Text component */\n textWrapper?: boolean;\n /** If true, auto-detects whether text is HTML or plain text to determine wrapping and element type */\n autoDetect?: boolean;\n}\n\nconst TextOrHTML = ({\n ref,\n text,\n htmlClassName,\n htmlElementType,\n textWrapper = false,\n autoDetect = false,\n ...textProps\n}: TextOrHTMLProps) => {\n const hasBlockContent = autoDetect && containsBlockHTML(text);\n\n // Memoize the dangerouslySetInnerHTML object to prevent unnecessary re-renders\n // See: https://github.com/facebook/react/issues/31660\n const dangerousHTML = useMemo(() => ({ __html: text }), [text]);\n\n // Non-block text with autoDetect: render directly on a Text-equivalent element,\n // avoiding unnecessary <span> nesting inside <p>.\n if (autoDetect && !hasBlockContent) {\n const { variant, spacing, elementType, className, ...domProps } = textProps;\n const Element = getElementType(variant, elementType);\n const classes = buildTextClasses(textProps, htmlClassName);\n\n return containsHTML(text) ? (\n <Element\n ref={ref}\n {...domProps}\n className={classes}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n ) : (\n <Element ref={ref} {...domProps} className={classes}>\n {text}\n </Element>\n );\n }\n\n const DangerousComponent =\n htmlElementType ?? (hasBlockContent ? \"div\" : \"span\");\n const dangerousElement = (\n <DangerousComponent\n className={htmlClassName}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n );\n\n if (textWrapper) {\n return (\n <Text ref={ref} {...textProps}>\n {dangerousElement}\n </Text>\n );\n }\n\n return dangerousElement;\n};\n\nTextOrHTML.displayName = \"TextOrHTML\";\nexport { TextOrHTML };\n", "import type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Text.css\";\n\nexport type TextElementType = HTMLHeadingElement | HTMLParagraphElement;\nexport type TextVariantType =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"body\"\n | \"small\"\n | \"legal\"\n | \"title\";\nexport type ElementType = \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"p\" | \"span\";\nexport interface TextProps extends DOMProps, RefAttributes<TextElementType> {\n /** HTML element for the text */\n elementType?: ElementType;\n /** Specify font size override */\n variant?: TextVariantType;\n /** Specify compact line height override */\n spacing?: \"loose\" | \"tight\";\n /** Custom class name for setting specific CSS */\n className?: string;\n children: ReactNode;\n style?: React.CSSProperties;\n}\n\nexport const getElementType = (\n variant: TextVariantType | undefined,\n elementType: ElementType | undefined,\n): ElementType => {\n // Explicit elementType always wins\n if (elementType) {\n return elementType;\n }\n // Infer element from variant\n if (variant && [\"h1\", \"h2\", \"h3\", \"h4\"].includes(variant)) {\n return variant as ElementType;\n }\n return \"p\";\n};\n\nconst Text = ({ ref, elementType, ...props }: TextProps) => {\n // Remove non-DOM props from element\n const { variant, className, spacing, ...otherProps } = props;\n\n // If a variant is supplied, set the class name and element type\n const Element: ElementType = getElementType(variant, elementType);\n const variantType = variant || Element;\n const classes = classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nText.displayName = \"Text\";\nexport { Text };\n", "import type React from \"react\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Label.css\";\n\nexport type LabelElementType = HTMLLabelElement;\nexport type IntrinsicLabel = Omit<\n React.JSX.IntrinsicElements[\"label\"],\n \"css\" | \"color\" | \"ref\"\n>;\n\nexport interface LabelProps\n extends IntrinsicLabel, DOMProps, RefAttributes<LabelElementType> {\n children?: ReactNode;\n className?: string;\n elementType?: \"label\" | \"span\";\n}\n\nconst Label = ({ ref, ...props }: LabelProps) => {\n const { elementType: Element = \"label\", children, ...otherProps } = props;\n\n const classes = classNames(\"mobius\", \"mobius-label\", props.className);\n otherProps.className = classes;\n\n return (\n <Element ref={ref} {...otherProps} className={classes}>\n {children}\n </Element>\n );\n};\n\nLabel.displayName = \"Label\";\nexport { Label };\n", "import type { Ref, RefAttributes, ReactNode } from \"react\";\nimport type React from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { SpacingType } from \"../../types\";\nimport \"./Stack.css\";\n\nexport type StackElementType = HTMLDivElement;\n\nexport interface StackProps extends DOMProps, RefAttributes<StackElementType> {\n children?: ReactNode;\n /** How big a gap between items */\n gap?: SpacingType;\n /** Custom class name for setting specific CSS */\n className?: string;\n elementType?: React.ElementType;\n}\n\nexport type StackRef = Ref<StackElementType>;\n\nexport const Stack = ({ ref, ...props }: StackProps) => {\n const { elementType: Element = \"div\", gap, ...otherProps } = props;\n\n const classes = classNames(\n \"mobius\",\n \"mobius-stack\",\n {\n [`--gap-${gap}`]: gap,\n },\n otherProps.className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nStack.displayName = \"Stack\";\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_dedupe", "import_react", "import_dedupe", "classNames", "import_dedupe", "import_dedupe", "import_jsx_runtime", "classNames", "import_jsx_runtime", "classNames", "import_jsx_runtime", "classNames", "import_dedupe", "import_jsx_runtime", "classNames", "import_dedupe", "import_jsx_runtime", "classNames", "import_jsx_runtime", "classNames"]
|
|
7
7
|
}
|
|
@@ -134,7 +134,8 @@ Text.displayName = "Text";
|
|
|
134
134
|
|
|
135
135
|
// src/components/TextOrHTML/TextOrHTML.tsx
|
|
136
136
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
137
|
-
var
|
|
137
|
+
var BLOCK_TAG = /<(div|p|ul|ol|li|h[1-6]|table|tr|td|th|blockquote|pre|hr|dl|dt|dd)[\s>/]/i;
|
|
138
|
+
var containsBlockHTML = (text) => BLOCK_TAG.test(text);
|
|
138
139
|
var containsHTML = (text) => /<[a-z/]/i.test(text) || /&(?:#\d+|#x[\da-f]+|[a-z]\w*);/i.test(text);
|
|
139
140
|
var buildTextClasses = (textProps, htmlClassName) => {
|
|
140
141
|
const { variant, elementType, spacing, className } = textProps;
|
|
@@ -157,9 +158,9 @@ var TextOrHTML = ({
|
|
|
157
158
|
autoDetect = false,
|
|
158
159
|
...textProps
|
|
159
160
|
}) => {
|
|
160
|
-
const
|
|
161
|
+
const hasBlockContent = autoDetect && containsBlockHTML(text);
|
|
161
162
|
const dangerousHTML = (0, import_react.useMemo)(() => ({ __html: text }), [text]);
|
|
162
|
-
if (autoDetect && !
|
|
163
|
+
if (autoDetect && !hasBlockContent) {
|
|
163
164
|
const { variant, spacing, elementType, className, ...domProps } = textProps;
|
|
164
165
|
const Element = getElementType(variant, elementType);
|
|
165
166
|
const classes = buildTextClasses(textProps, htmlClassName);
|
|
@@ -173,7 +174,7 @@ var TextOrHTML = ({
|
|
|
173
174
|
}
|
|
174
175
|
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Element, { ref, ...domProps, className: classes, children: text });
|
|
175
176
|
}
|
|
176
|
-
const DangerousComponent = htmlElementType ?? (
|
|
177
|
+
const DangerousComponent = htmlElementType ?? (hasBlockContent ? "div" : "span");
|
|
177
178
|
const dangerousElement = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
178
179
|
DangerousComponent,
|
|
179
180
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/Radio/index.tsx", "../../../../src/components/Radio/Radio.tsx", "../../../../src/components/ErrorMessage/ErrorMessage.tsx", "../../../../src/components/Icon/Icon.tsx", "../../../../src/components/TextOrHTML/TextOrHTML.tsx", "../../../../src/components/Text/Text.tsx", "../../../../src/components/Label/Label.tsx", "../../../../src/components/Radio/RadioGroup.tsx", "../../../../src/utils/spaceDelimitedList.ts", "../../../../src/hooks/useValidationClasses/useValidationClasses.ts", "../../../../src/components/Stack/Stack.tsx"],
|
|
4
|
-
"sourcesContent": ["export * from \"./Radio\";\nexport * from \"./RadioGroup\";\n", "\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport {\n Children,\n isValidElement,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { HTMLElementEvent } from \"../../types/events\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport \"./Radio.css\";\n\nexport type RadioElementType = HTMLInputElement;\n\nexport type RadioOverflowInfo = {\n vertical: boolean;\n horizontal: boolean;\n};\n\nexport type AriaRadioProps = {\n /**\n * Defines a string value that labels the current element.\n */\n \"aria-label\"?: string;\n /**\n * Identifies the element (or elements) that labels the current element.\n */\n \"aria-labelledby\"?: string;\n /**\n * Identifies the element (or elements) that describes the object.\n */\n \"aria-describedby\"?: string;\n /**\n * Identifies the element (or elements) that provide a detailed, extended description for the object.\n */\n \"aria-details\"?: string;\n};\n\nexport interface RadioProps\n extends DOMProps, AriaRadioProps, RefAttributes<RadioElementType> {\n children?: ReactNode;\n className?: string;\n label?: ReactNode;\n errorMessage?: string;\n value: string;\n isDisabled?: boolean;\n onChange?: (event: HTMLElementEvent<RadioElementType>) => void;\n defaultChecked?: boolean;\n /**\n * Callback fired when label overflow state changes.\n * Only invoked when the Radio is in horizontal orientation to prevent infinite loops with autoStack.\n * Provides information about vertical and horizontal overflow.\n */\n onOverflow?: (overflow: RadioOverflowInfo) => void;\n // Internal:** Do not use\n groupDisabled?: boolean;\n // Internal:** Do not use\n name?: string;\n // Internal:** Do not use\n selected?: string;\n // Internal:** Do not use\n setSelected?: React.Dispatch<React.SetStateAction<string>>;\n isRequired?: boolean;\n /**\n * **Internal:** Passed via cloneElement from RadioGroup.\n * @internal\n */\n orientation?: \"horizontal\" | \"vertical\";\n}\n\nconst Radio = ({ ref, ...props }: RadioProps) => {\n const {\n children,\n value,\n label,\n className,\n isDisabled,\n errorMessage,\n onChange,\n defaultChecked,\n groupDisabled,\n name,\n selected,\n setSelected,\n isRequired,\n onOverflow,\n orientation,\n ...otherProps\n } = props;\n const realDisabled = groupDisabled || isDisabled;\n const isMultiline = label && children;\n const isControlled = selected !== undefined;\n const isChecked = isControlled ? selected === value : defaultChecked;\n\n const contentRef = useRef<HTMLDivElement>(null);\n const prevOverflowRef = useRef<RadioOverflowInfo>({\n vertical: false,\n horizontal: false,\n });\n\n const hasIconFirst = useMemo(() => {\n if (!children || Children.count(children) === 0) return false;\n\n const firstChild = Children.toArray(children)[0];\n if (!isValidElement(firstChild)) return false;\n\n const props = firstChild.props as Record<string, unknown>;\n return \"icon\" in props && props.icon !== undefined;\n }, [children]);\n\n // Detect overflow and call callback\n useLayoutEffect(() => {\n if (!contentRef.current || !onOverflow) return;\n\n // Only detect overflow when in horizontal orientation\n // This prevents infinite loops when autoStack switches to vertical\n if (orientation === \"vertical\") {\n return;\n }\n\n const element = contentRef.current;\n\n // Check for content being cut off (true overflow)\n const scrollOverflowVertical = element.scrollHeight > element.clientHeight;\n const scrollOverflowHorizontal = element.scrollWidth > element.clientWidth;\n\n // Check for multi-line text wrapping by comparing height to single line height\n const styles = window.getComputedStyle(element);\n const lineHeight = parseFloat(styles.lineHeight);\n const fontSize = parseFloat(styles.fontSize);\n const singleLineHeight = isNaN(lineHeight) ? fontSize * 1.2 : lineHeight;\n\n // Tolerance multiplier to account for sub-pixel rendering and line-height variations.\n // If element height is greater than single line, text has wrapped.\n const WRAP_DETECTION_TOLERANCE = 1.1;\n const hasWrapped =\n element.clientHeight > singleLineHeight * WRAP_DETECTION_TOLERANCE;\n\n const vertical = scrollOverflowVertical || hasWrapped;\n const horizontal = scrollOverflowHorizontal;\n\n const newOverflowState = { vertical, horizontal };\n const prevOverflow = prevOverflowRef.current;\n\n // Only call callback if state actually changed\n if (\n newOverflowState.vertical !== prevOverflow.vertical ||\n newOverflowState.horizontal !== prevOverflow.horizontal\n ) {\n prevOverflowRef.current = newOverflowState;\n onOverflow(newOverflowState);\n }\n }, [label, children, onOverflow, orientation]);\n\n const radioClasses = {\n \"--is-disabled\": realDisabled,\n \"--is-selected\": selected === value,\n \"--is-multiline\": !!isMultiline,\n \"--is-required\": isRequired,\n };\n const containerClasses = classNames(\n \"mobius-radio__label\",\n radioClasses,\n className,\n { \"--has-icon-first\": hasIconFirst },\n );\n\n const inputClasses = classNames(\"mobius-radio__input\", radioClasses);\n\n // Exclude props that are passed via cloneElement in `<RadioGroup />`\n const { \"aria-describedby\": _ariaDescribedBy, ...rest } = otherProps;\n\n // Handle all interactions through onChange event\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n // Update internal state for RadioGroup\n if (setSelected) {\n setSelected(event.target.value);\n }\n\n // Call parent onChange callback\n if (onChange) {\n // Create an HTMLElementEvent-compatible object\n const adaptedEvent: HTMLElementEvent<HTMLInputElement> = {\n ...event.nativeEvent,\n target: event.target,\n };\n onChange(adaptedEvent);\n }\n };\n\n return (\n <>\n <Label className={containerClasses}>\n <input\n aria-describedby={otherProps[\"aria-describedby\"]}\n disabled={realDisabled}\n ref={ref}\n className={inputClasses}\n value={value}\n tabIndex={0}\n type=\"radio\"\n onChange={handleChange}\n {...(isControlled\n ? { checked: isChecked }\n : { defaultChecked: isChecked })}\n name={name}\n required={isRequired}\n {...rest}\n />\n {isMultiline ? (\n <div ref={contentRef} className=\"mobius-radio__content--multiline\">\n <div className=\"mobius-radio__content-first-line\">{label}</div>\n <div className=\"mobius-radio__extra-content\">{children}</div>\n </div>\n ) : (\n <div ref={contentRef} className=\"mobius-radio__content\">\n {label || children}\n </div>\n )}\n </Label>\n {errorMessage && <ErrorMessage errorMessage={errorMessage} />}\n </>\n );\n};\n\nRadio.displayName = \"Radio\";\nexport { Radio };\n", "import { error } from \"@simplybusiness/icons\";\nimport classNames from \"classnames/dedupe\";\nimport { Icon } from \"../Icon\";\nimport { TextOrHTML } from \"../TextOrHTML\";\nimport \"./ErrorMessage.css\";\n\nexport interface ErrorMessageProps {\n errorMessage?: string;\n id?: string;\n className?: string;\n}\n\nexport const ErrorMessage = ({\n id,\n errorMessage,\n className,\n}: ErrorMessageProps) => {\n const classes = classNames(\"mobius\", \"mobius-error-message\", className);\n\n if (!errorMessage) return null;\n\n return (\n <div id={id} className={classes} data-testid=\"ErrorMessage\" role=\"alert\">\n <Icon\n icon={error}\n className=\"mobius-error-message__icon\"\n aria-hidden=\"true\"\n />\n <TextOrHTML\n elementType=\"span\"\n className=\"mobius-error-message__text\"\n text={errorMessage}\n />\n </div>\n );\n};\n\nErrorMessage.displayName = \"ErrorMessage\";\n", "import classNames from \"classnames/dedupe\";\nimport type { IconProps } from \"./types\";\nimport \"./Icon.css\";\n\nconst ICON_PREFIX = \"mobius-icon\";\n\nconst capitaliseFirstLetter = (str: string) =>\n str.charAt(0).toUpperCase() + str.slice(1);\n\nexport function Icon({\n ref,\n icon,\n className,\n size = \"xs\",\n color,\n fixedWidth,\n spin,\n spinReverse,\n title,\n ...otherProps\n}: IconProps) {\n if (!icon) {\n throw new Error(\"Must specify icon object\");\n }\n\n const classes = classNames(\n \"mobius\",\n \"mobius-icon\",\n `svg-inline--${ICON_PREFIX}`,\n `--size-${size}`,\n className,\n {\n [`${ICON_PREFIX}-fw`]: fixedWidth,\n [`${ICON_PREFIX}-spin`]: spin || spinReverse,\n [`${ICON_PREFIX}-spin-reverse`]: spinReverse,\n },\n );\n\n const { iconName, width, height, svgPathData } = icon;\n const formattedIconName = iconName.split(\"-\").join(\" \");\n\n const defaultTitle = `${capitaliseFirstLetter(formattedIconName)} icon`;\n const titleText = title || defaultTitle;\n\n return (\n <svg\n ref={ref}\n focusable=\"false\"\n data-icon={iconName}\n className={classes}\n role=\"img\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox={`0 0 ${width} ${height}`}\n style={{ color }}\n {...otherProps}\n >\n <title>{titleText}</title>\n <path fill=\"currentColor\" d={svgPathData} />\n </svg>\n );\n}\n", "import classNames from \"classnames/dedupe\";\nimport type { RefAttributes } from \"react\";\nimport { useMemo } from \"react\";\nimport type { TextElementType, TextProps } from \"../Text/Text\";\nimport { Text, getElementType } from \"../Text/Text\";\n\nexport type HTMLElementType = \"span\" | \"div\";\n\nconst isBlockHTML = (text: string) => /^\\s*<[a-z]/i.test(text);\nconst containsHTML = (text: string) =>\n /<[a-z/]/i.test(text) || /&(?:#\\d+|#x[\\da-f]+|[a-z]\\w*);/i.test(text); // tag or entity\n\nconst buildTextClasses = (\n textProps: Omit<TextProps, \"children\">,\n htmlClassName?: string,\n) => {\n const { variant, elementType, spacing, className } = textProps;\n const variantType = variant || getElementType(variant, elementType);\n return classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n htmlClassName,\n );\n};\n\nexport interface TextOrHTMLProps\n extends Omit<TextProps, \"children\">, RefAttributes<TextElementType> {\n /** HTML string to be rendered with dangerouslySetInnerHTML */\n text: string;\n /** Custom class name for the dangerous HTML element */\n htmlClassName?: string;\n /** HTML element type for the dangerous HTML element */\n htmlElementType?: HTMLElementType;\n /** If true, wraps the dangerous HTML element inside a Text component */\n textWrapper?: boolean;\n /** If true, auto-detects whether text is HTML or plain text to determine wrapping and element type */\n autoDetect?: boolean;\n}\n\nconst TextOrHTML = ({\n ref,\n text,\n htmlClassName,\n htmlElementType,\n textWrapper = false,\n autoDetect = false,\n ...textProps\n}: TextOrHTMLProps) => {\n const textIsBlockHTML = autoDetect && isBlockHTML(text);\n\n // Memoize the dangerouslySetInnerHTML object to prevent unnecessary re-renders\n // See: https://github.com/facebook/react/issues/31660\n const dangerousHTML = useMemo(() => ({ __html: text }), [text]);\n\n // Non-block text with autoDetect: render directly on a Text-equivalent element,\n // avoiding unnecessary <span> nesting inside <p>.\n if (autoDetect && !textIsBlockHTML) {\n const { variant, spacing, elementType, className, ...domProps } = textProps;\n const Element = getElementType(variant, elementType);\n const classes = buildTextClasses(textProps, htmlClassName);\n\n return containsHTML(text) ? (\n <Element\n ref={ref}\n {...domProps}\n className={classes}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n ) : (\n <Element ref={ref} {...domProps} className={classes}>\n {text}\n </Element>\n );\n }\n\n const DangerousComponent =\n htmlElementType ?? (textIsBlockHTML ? \"div\" : \"span\");\n const dangerousElement = (\n <DangerousComponent\n className={htmlClassName}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n );\n\n if (textWrapper) {\n return (\n <Text ref={ref} {...textProps}>\n {dangerousElement}\n </Text>\n );\n }\n\n return dangerousElement;\n};\n\nTextOrHTML.displayName = \"TextOrHTML\";\nexport { TextOrHTML };\n", "import type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Text.css\";\n\nexport type TextElementType = HTMLHeadingElement | HTMLParagraphElement;\nexport type TextVariantType =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"body\"\n | \"small\"\n | \"legal\"\n | \"title\";\nexport type ElementType = \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"p\" | \"span\";\nexport interface TextProps extends DOMProps, RefAttributes<TextElementType> {\n /** HTML element for the text */\n elementType?: ElementType;\n /** Specify font size override */\n variant?: TextVariantType;\n /** Specify compact line height override */\n spacing?: \"loose\" | \"tight\";\n /** Custom class name for setting specific CSS */\n className?: string;\n children: ReactNode;\n style?: React.CSSProperties;\n}\n\nexport const getElementType = (\n variant: TextVariantType | undefined,\n elementType: ElementType | undefined,\n): ElementType => {\n // Explicit elementType always wins\n if (elementType) {\n return elementType;\n }\n // Infer element from variant\n if (variant && [\"h1\", \"h2\", \"h3\", \"h4\"].includes(variant)) {\n return variant as ElementType;\n }\n return \"p\";\n};\n\nconst Text = ({ ref, elementType, ...props }: TextProps) => {\n // Remove non-DOM props from element\n const { variant, className, spacing, ...otherProps } = props;\n\n // If a variant is supplied, set the class name and element type\n const Element: ElementType = getElementType(variant, elementType);\n const variantType = variant || Element;\n const classes = classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nText.displayName = \"Text\";\nexport { Text };\n", "import type React from \"react\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Label.css\";\n\nexport type LabelElementType = HTMLLabelElement;\nexport type IntrinsicLabel = Omit<\n React.JSX.IntrinsicElements[\"label\"],\n \"css\" | \"color\" | \"ref\"\n>;\n\nexport interface LabelProps\n extends IntrinsicLabel, DOMProps, RefAttributes<LabelElementType> {\n children?: ReactNode;\n className?: string;\n elementType?: \"label\" | \"span\";\n}\n\nconst Label = ({ ref, ...props }: LabelProps) => {\n const { elementType: Element = \"label\", children, ...otherProps } = props;\n\n const classes = classNames(\"mobius\", \"mobius-label\", props.className);\n otherProps.className = classes;\n\n return (\n <Element ref={ref} {...otherProps} className={classes}>\n {children}\n </Element>\n );\n};\n\nLabel.displayName = \"Label\";\nexport { Label };\n", "\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport type { ReactElement, ReactNode, RefAttributes } from \"react\";\nimport {\n Children,\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { useValidationClasses } from \"../../hooks\";\nimport type { Validation } from \"../../types\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { HTMLElementEvent } from \"../../types/events\";\nimport { spaceDelimitedList } from \"../../utils/spaceDelimitedList\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Stack } from \"../Stack\";\nimport type { RadioOverflowInfo } from \"./Radio\";\n\nexport type RadioGroupElementType = HTMLDivElement;\n\nexport interface RadioGroupProps\n extends DOMProps, Validation, RefAttributes<RadioGroupElementType> {\n children: ReactNode;\n className?: string;\n orientation?: \"horizontal\" | \"vertical\";\n errorMessage?: string;\n // Callback that fires when select changes\n onChange?: (event: HTMLElementEvent<HTMLInputElement>) => void;\n /**\n * Automatically change orientation from horizontal to vertical when any Radio label overflows.\n * Only applies when orientation is set to \"horizontal\".\n */\n autoStack?: boolean;\n // Defines a string value that labels the current element.\n \"aria-label\"?: string;\n // Identifies the element (or elements) that labels the current element.\n \"aria-labelledby\"?: string;\n // Identifies the element that provides an error message for the object.\n \"aria-errormessage\"?: string;\n // Identifies the element (or elements) that describes the object.\n \"aria-describedby\"?: string;\n // Whether user input is required on the input before form submission.\n isRequired?: boolean;\n // Whether the input is disabled.\n isDisabled?: boolean;\n // Whether the input can be selected but not changed by the user.\n isReadOnly?: boolean;\n // The default value (uncontrolled).\n defaultValue?: string;\n // The content to display as the label.\n label?: ReactNode;\n /**\n * The value of the radio button, used when submitting an HTML form.\n * See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio#Value).\n */\n value?: string;\n name?: string;\n}\n\nconst getDefaultVal = (children: ReactNode, defaultValue?: string) => {\n if (Array.isArray(children) && defaultValue) {\n const option = children?.find(item => item.props.value === defaultValue);\n\n if (!option) return \"\";\n\n return option.props.value;\n }\n\n return \"\";\n};\n\nconst RadioGroup = ({ ref, ...props }: RadioGroupProps) => {\n const {\n label,\n isDisabled = false,\n isRequired,\n isInvalid,\n orientation = \"vertical\",\n className,\n errorMessage,\n children,\n defaultValue,\n value,\n isReadOnly,\n name,\n onChange,\n autoStack = false,\n ...rest\n } = props;\n const defaultSelected = getDefaultVal(children, value || defaultValue);\n const [selected, setSelected] = useState<string>(defaultSelected);\n const overflowsRef = useRef<Record<string, RadioOverflowInfo>>({});\n const [hasOverflow, setHasOverflow] = useState(false);\n\n // Handle controlled behavior - update state when value prop changes\n useEffect(() => {\n if (value !== undefined) {\n setSelected(value);\n }\n }, [value]);\n\n // Handle overflow detection and auto-stack if needed\n const handleOverflow = useCallback(\n (radioValue: string, overflow: RadioOverflowInfo) => {\n overflowsRef.current = {\n ...overflowsRef.current,\n [radioValue]: overflow,\n };\n\n // Check if any radio has overflow\n const anyOverflow = Object.values(overflowsRef.current).some(\n o => o.vertical || o.horizontal,\n );\n\n if (anyOverflow !== hasOverflow) {\n setHasOverflow(anyOverflow);\n }\n },\n [hasOverflow],\n );\n\n // Determine effective orientation (auto-stack if needed)\n const effectiveOrientation =\n autoStack && orientation === \"horizontal\" && hasOverflow\n ? \"vertical\"\n : orientation;\n\n const validationClasses = useValidationClasses({ isInvalid });\n const radioClasses = {\n \"--is-disabled\": isDisabled,\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n [`--is-${effectiveOrientation}`]: true,\n [className || \"\"]: true,\n };\n const radioGroupClasses = classNames(\n \"mobius\",\n \"mobius-radio-group\",\n radioClasses,\n validationClasses,\n );\n const radioWrapperClasses = classNames(\"mobius-radio__wrapper\", {\n [`--is-${effectiveOrientation}`]: true,\n });\n const labelClasses = classNames(radioClasses, validationClasses);\n const errorMessageId = useId();\n const defaultNameAttrId = useId();\n const nameAttribute = name || defaultNameAttrId;\n const shouldErrorMessageShow = errorMessage ? errorMessageId : undefined;\n const describedBy = spaceDelimitedList([\n shouldErrorMessageShow,\n props[\"aria-describedby\"],\n ]);\n const labelId = useId();\n\n return (\n <div\n {...rest}\n aria-describedby={describedBy}\n aria-disabled={isDisabled}\n aria-errormessage={shouldErrorMessageShow}\n aria-invalid={isInvalid}\n aria-label={props[\"aria-label\"]}\n aria-labelledby={props[\"aria-labelledby\"] || labelId}\n aria-orientation={effectiveOrientation}\n aria-readonly={isReadOnly}\n aria-required={isRequired}\n ref={ref}\n className={radioGroupClasses}\n role=\"radiogroup\"\n >\n <Stack gap=\"xs\">\n {label && (\n <Label htmlFor={name} id={labelId} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className={radioWrapperClasses}>\n {Children.map(children, child => {\n if (isValidElement(child)) {\n const childValue = (child.props as { value?: string }).value;\n return cloneElement(\n child as ReactElement,\n {\n orientation: effectiveOrientation,\n groupDisabled: isDisabled,\n name: nameAttribute,\n selected: selected || defaultSelected, // in case state does not update\n setSelected,\n isRequired,\n \"aria-describedby\": describedBy,\n onChange,\n onOverflow: childValue\n ? (overflow: RadioOverflowInfo) =>\n handleOverflow(childValue, overflow)\n : undefined,\n } as Record<string, unknown>,\n );\n }\n\n return child;\n })}\n </div>\n <ErrorMessage id={errorMessageId} errorMessage={errorMessage} />\n </Stack>\n </div>\n );\n};\n\nRadioGroup.displayName = \"RadioGroup\";\nexport { RadioGroup };\n", "export function spaceDelimitedList(\n list: (string | null | undefined)[],\n): string | undefined {\n return list.filter(Boolean).join(\" \") || undefined;\n}\n", "import type { Validation } from \"../../types\";\n\nexport type GetValidationClassesProps = Pick<Validation, \"isInvalid\">;\n\nexport const useValidationClasses = (props: GetValidationClassesProps) => {\n const { isInvalid } = props;\n\n if (isInvalid) {\n return \"--is-invalid\";\n }\n\n if (isInvalid === false) {\n return \"--is-valid\";\n }\n\n return \"\";\n};\n", "import type { Ref, RefAttributes, ReactNode } from \"react\";\nimport type React from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { SpacingType } from \"../../types\";\nimport \"./Stack.css\";\n\nexport type StackElementType = HTMLDivElement;\n\nexport interface StackProps extends DOMProps, RefAttributes<StackElementType> {\n children?: ReactNode;\n /** How big a gap between items */\n gap?: SpacingType;\n /** Custom class name for setting specific CSS */\n className?: string;\n elementType?: React.ElementType;\n}\n\nexport type StackRef = Ref<StackElementType>;\n\nexport const Stack = ({ ref, ...props }: StackProps) => {\n const { elementType: Element = \"div\", gap, ...otherProps } = props;\n\n const classes = classNames(\n \"mobius\",\n \"mobius-stack\",\n {\n [`--gap-${gap}`]: gap,\n },\n otherProps.className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nStack.displayName = \"Stack\";\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAAA,iBAAuB;AAEvB,IAAAC,gBAMO;;;ACVP,mBAAsB;AACtB,IAAAC,iBAAuB;;;ACDvB,oBAAuB;AAEvB,kBAAO;AA2CH;AAzCJ,IAAM,cAAc;AAEpB,IAAM,wBAAwB,CAAC,QAC7B,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAEpC,SAAS,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAc;AACZ,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AAEA,QAAM,cAAU,cAAAC;AAAA,IACd;AAAA,IACA;AAAA,IACA,eAAe,WAAW;AAAA,IAC1B,UAAU,IAAI;AAAA,IACd;AAAA,IACA;AAAA,MACE,CAAC,GAAG,WAAW,KAAK,GAAG;AAAA,MACvB,CAAC,GAAG,WAAW,OAAO,GAAG,QAAQ;AAAA,MACjC,CAAC,GAAG,WAAW,eAAe,GAAG;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,EAAE,UAAU,OAAO,QAAQ,YAAY,IAAI;AACjD,QAAM,oBAAoB,SAAS,MAAM,GAAG,EAAE,KAAK,GAAG;AAEtD,QAAM,eAAe,GAAG,sBAAsB,iBAAiB,CAAC;AAChE,QAAM,YAAY,SAAS;AAE3B,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MACV,aAAW;AAAA,MACX,WAAW;AAAA,MACX,MAAK;AAAA,MACL,OAAM;AAAA,MACN,SAAS,OAAO,KAAK,IAAI,MAAM;AAAA,MAC/B,OAAO,EAAE,MAAM;AAAA,MACd,GAAG;AAAA,MAEJ;AAAA,oDAAC,WAAO,qBAAU;AAAA,QAClB,4CAAC,UAAK,MAAK,gBAAe,GAAG,aAAa;AAAA;AAAA;AAAA,EAC5C;AAEJ;;;AC5DA,IAAAC,iBAAuB;AAEvB,mBAAwB;;;ACDxB,IAAAC,iBAAuB;AAEvB,kBAAO;AAwDE,IAAAC,sBAAA;AA9BF,IAAM,iBAAiB,CAC5B,SACA,gBACgB;AAEhB,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,CAAC,MAAM,MAAM,MAAM,IAAI,EAAE,SAAS,OAAO,GAAG;AACzD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,IAAM,OAAO,CAAC,EAAE,KAAK,aAAa,GAAG,MAAM,MAAiB;AAE1D,QAAM,EAAE,SAAS,WAAW,SAAS,GAAG,WAAW,IAAI;AAGvD,QAAM,UAAuB,eAAe,SAAS,WAAW;AAChE,QAAM,cAAc,WAAW;AAC/B,QAAM,cAAU,eAAAC;AAAA,IACd;AAAA,IACA;AAAA,IACA,EAAE,CAAC,QAAQ,WAAW,EAAE,GAAG,YAAY;AAAA,IACvC,EAAE,CAAC,qBAAqB,OAAO,EAAE,GAAG,QAAQ;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO,6CAAC,WAAQ,KAAW,GAAG,YAAY,WAAW,SAAS;AAChE;AAEA,KAAK,cAAc;;;
|
|
4
|
+
"sourcesContent": ["export * from \"./Radio\";\nexport * from \"./RadioGroup\";\n", "\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport {\n Children,\n isValidElement,\n useLayoutEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { HTMLElementEvent } from \"../../types/events\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport \"./Radio.css\";\n\nexport type RadioElementType = HTMLInputElement;\n\nexport type RadioOverflowInfo = {\n vertical: boolean;\n horizontal: boolean;\n};\n\nexport type AriaRadioProps = {\n /**\n * Defines a string value that labels the current element.\n */\n \"aria-label\"?: string;\n /**\n * Identifies the element (or elements) that labels the current element.\n */\n \"aria-labelledby\"?: string;\n /**\n * Identifies the element (or elements) that describes the object.\n */\n \"aria-describedby\"?: string;\n /**\n * Identifies the element (or elements) that provide a detailed, extended description for the object.\n */\n \"aria-details\"?: string;\n};\n\nexport interface RadioProps\n extends DOMProps, AriaRadioProps, RefAttributes<RadioElementType> {\n children?: ReactNode;\n className?: string;\n label?: ReactNode;\n errorMessage?: string;\n value: string;\n isDisabled?: boolean;\n onChange?: (event: HTMLElementEvent<RadioElementType>) => void;\n defaultChecked?: boolean;\n /**\n * Callback fired when label overflow state changes.\n * Only invoked when the Radio is in horizontal orientation to prevent infinite loops with autoStack.\n * Provides information about vertical and horizontal overflow.\n */\n onOverflow?: (overflow: RadioOverflowInfo) => void;\n // Internal:** Do not use\n groupDisabled?: boolean;\n // Internal:** Do not use\n name?: string;\n // Internal:** Do not use\n selected?: string;\n // Internal:** Do not use\n setSelected?: React.Dispatch<React.SetStateAction<string>>;\n isRequired?: boolean;\n /**\n * **Internal:** Passed via cloneElement from RadioGroup.\n * @internal\n */\n orientation?: \"horizontal\" | \"vertical\";\n}\n\nconst Radio = ({ ref, ...props }: RadioProps) => {\n const {\n children,\n value,\n label,\n className,\n isDisabled,\n errorMessage,\n onChange,\n defaultChecked,\n groupDisabled,\n name,\n selected,\n setSelected,\n isRequired,\n onOverflow,\n orientation,\n ...otherProps\n } = props;\n const realDisabled = groupDisabled || isDisabled;\n const isMultiline = label && children;\n const isControlled = selected !== undefined;\n const isChecked = isControlled ? selected === value : defaultChecked;\n\n const contentRef = useRef<HTMLDivElement>(null);\n const prevOverflowRef = useRef<RadioOverflowInfo>({\n vertical: false,\n horizontal: false,\n });\n\n const hasIconFirst = useMemo(() => {\n if (!children || Children.count(children) === 0) return false;\n\n const firstChild = Children.toArray(children)[0];\n if (!isValidElement(firstChild)) return false;\n\n const props = firstChild.props as Record<string, unknown>;\n return \"icon\" in props && props.icon !== undefined;\n }, [children]);\n\n // Detect overflow and call callback\n useLayoutEffect(() => {\n if (!contentRef.current || !onOverflow) return;\n\n // Only detect overflow when in horizontal orientation\n // This prevents infinite loops when autoStack switches to vertical\n if (orientation === \"vertical\") {\n return;\n }\n\n const element = contentRef.current;\n\n // Check for content being cut off (true overflow)\n const scrollOverflowVertical = element.scrollHeight > element.clientHeight;\n const scrollOverflowHorizontal = element.scrollWidth > element.clientWidth;\n\n // Check for multi-line text wrapping by comparing height to single line height\n const styles = window.getComputedStyle(element);\n const lineHeight = parseFloat(styles.lineHeight);\n const fontSize = parseFloat(styles.fontSize);\n const singleLineHeight = isNaN(lineHeight) ? fontSize * 1.2 : lineHeight;\n\n // Tolerance multiplier to account for sub-pixel rendering and line-height variations.\n // If element height is greater than single line, text has wrapped.\n const WRAP_DETECTION_TOLERANCE = 1.1;\n const hasWrapped =\n element.clientHeight > singleLineHeight * WRAP_DETECTION_TOLERANCE;\n\n const vertical = scrollOverflowVertical || hasWrapped;\n const horizontal = scrollOverflowHorizontal;\n\n const newOverflowState = { vertical, horizontal };\n const prevOverflow = prevOverflowRef.current;\n\n // Only call callback if state actually changed\n if (\n newOverflowState.vertical !== prevOverflow.vertical ||\n newOverflowState.horizontal !== prevOverflow.horizontal\n ) {\n prevOverflowRef.current = newOverflowState;\n onOverflow(newOverflowState);\n }\n }, [label, children, onOverflow, orientation]);\n\n const radioClasses = {\n \"--is-disabled\": realDisabled,\n \"--is-selected\": selected === value,\n \"--is-multiline\": !!isMultiline,\n \"--is-required\": isRequired,\n };\n const containerClasses = classNames(\n \"mobius-radio__label\",\n radioClasses,\n className,\n { \"--has-icon-first\": hasIconFirst },\n );\n\n const inputClasses = classNames(\"mobius-radio__input\", radioClasses);\n\n // Exclude props that are passed via cloneElement in `<RadioGroup />`\n const { \"aria-describedby\": _ariaDescribedBy, ...rest } = otherProps;\n\n // Handle all interactions through onChange event\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n // Update internal state for RadioGroup\n if (setSelected) {\n setSelected(event.target.value);\n }\n\n // Call parent onChange callback\n if (onChange) {\n // Create an HTMLElementEvent-compatible object\n const adaptedEvent: HTMLElementEvent<HTMLInputElement> = {\n ...event.nativeEvent,\n target: event.target,\n };\n onChange(adaptedEvent);\n }\n };\n\n return (\n <>\n <Label className={containerClasses}>\n <input\n aria-describedby={otherProps[\"aria-describedby\"]}\n disabled={realDisabled}\n ref={ref}\n className={inputClasses}\n value={value}\n tabIndex={0}\n type=\"radio\"\n onChange={handleChange}\n {...(isControlled\n ? { checked: isChecked }\n : { defaultChecked: isChecked })}\n name={name}\n required={isRequired}\n {...rest}\n />\n {isMultiline ? (\n <div ref={contentRef} className=\"mobius-radio__content--multiline\">\n <div className=\"mobius-radio__content-first-line\">{label}</div>\n <div className=\"mobius-radio__extra-content\">{children}</div>\n </div>\n ) : (\n <div ref={contentRef} className=\"mobius-radio__content\">\n {label || children}\n </div>\n )}\n </Label>\n {errorMessage && <ErrorMessage errorMessage={errorMessage} />}\n </>\n );\n};\n\nRadio.displayName = \"Radio\";\nexport { Radio };\n", "import { error } from \"@simplybusiness/icons\";\nimport classNames from \"classnames/dedupe\";\nimport { Icon } from \"../Icon\";\nimport { TextOrHTML } from \"../TextOrHTML\";\nimport \"./ErrorMessage.css\";\n\nexport interface ErrorMessageProps {\n errorMessage?: string;\n id?: string;\n className?: string;\n}\n\nexport const ErrorMessage = ({\n id,\n errorMessage,\n className,\n}: ErrorMessageProps) => {\n const classes = classNames(\"mobius\", \"mobius-error-message\", className);\n\n if (!errorMessage) return null;\n\n return (\n <div id={id} className={classes} data-testid=\"ErrorMessage\" role=\"alert\">\n <Icon\n icon={error}\n className=\"mobius-error-message__icon\"\n aria-hidden=\"true\"\n />\n <TextOrHTML\n elementType=\"span\"\n className=\"mobius-error-message__text\"\n text={errorMessage}\n />\n </div>\n );\n};\n\nErrorMessage.displayName = \"ErrorMessage\";\n", "import classNames from \"classnames/dedupe\";\nimport type { IconProps } from \"./types\";\nimport \"./Icon.css\";\n\nconst ICON_PREFIX = \"mobius-icon\";\n\nconst capitaliseFirstLetter = (str: string) =>\n str.charAt(0).toUpperCase() + str.slice(1);\n\nexport function Icon({\n ref,\n icon,\n className,\n size = \"xs\",\n color,\n fixedWidth,\n spin,\n spinReverse,\n title,\n ...otherProps\n}: IconProps) {\n if (!icon) {\n throw new Error(\"Must specify icon object\");\n }\n\n const classes = classNames(\n \"mobius\",\n \"mobius-icon\",\n `svg-inline--${ICON_PREFIX}`,\n `--size-${size}`,\n className,\n {\n [`${ICON_PREFIX}-fw`]: fixedWidth,\n [`${ICON_PREFIX}-spin`]: spin || spinReverse,\n [`${ICON_PREFIX}-spin-reverse`]: spinReverse,\n },\n );\n\n const { iconName, width, height, svgPathData } = icon;\n const formattedIconName = iconName.split(\"-\").join(\" \");\n\n const defaultTitle = `${capitaliseFirstLetter(formattedIconName)} icon`;\n const titleText = title || defaultTitle;\n\n return (\n <svg\n ref={ref}\n focusable=\"false\"\n data-icon={iconName}\n className={classes}\n role=\"img\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox={`0 0 ${width} ${height}`}\n style={{ color }}\n {...otherProps}\n >\n <title>{titleText}</title>\n <path fill=\"currentColor\" d={svgPathData} />\n </svg>\n );\n}\n", "import classNames from \"classnames/dedupe\";\nimport type { RefAttributes } from \"react\";\nimport { useMemo } from \"react\";\nimport type { TextElementType, TextProps } from \"../Text/Text\";\nimport { Text, getElementType } from \"../Text/Text\";\n\nexport type HTMLElementType = \"span\" | \"div\";\n\n// Block-level tags that cannot be nested inside <p>.\nconst BLOCK_TAG =\n /<(div|p|ul|ol|li|h[1-6]|table|tr|td|th|blockquote|pre|hr|dl|dt|dd)[\\s>/]/i;\nconst containsBlockHTML = (text: string) => BLOCK_TAG.test(text);\nconst containsHTML = (text: string) =>\n /<[a-z/]/i.test(text) || /&(?:#\\d+|#x[\\da-f]+|[a-z]\\w*);/i.test(text); // tag or entity\n\nconst buildTextClasses = (\n textProps: Omit<TextProps, \"children\">,\n htmlClassName?: string,\n) => {\n const { variant, elementType, spacing, className } = textProps;\n const variantType = variant || getElementType(variant, elementType);\n return classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n htmlClassName,\n );\n};\n\nexport interface TextOrHTMLProps\n extends Omit<TextProps, \"children\">, RefAttributes<TextElementType> {\n /** HTML string to be rendered with dangerouslySetInnerHTML */\n text: string;\n /** Custom class name for the dangerous HTML element */\n htmlClassName?: string;\n /** HTML element type for the dangerous HTML element */\n htmlElementType?: HTMLElementType;\n /** If true, wraps the dangerous HTML element inside a Text component */\n textWrapper?: boolean;\n /** If true, auto-detects whether text is HTML or plain text to determine wrapping and element type */\n autoDetect?: boolean;\n}\n\nconst TextOrHTML = ({\n ref,\n text,\n htmlClassName,\n htmlElementType,\n textWrapper = false,\n autoDetect = false,\n ...textProps\n}: TextOrHTMLProps) => {\n const hasBlockContent = autoDetect && containsBlockHTML(text);\n\n // Memoize the dangerouslySetInnerHTML object to prevent unnecessary re-renders\n // See: https://github.com/facebook/react/issues/31660\n const dangerousHTML = useMemo(() => ({ __html: text }), [text]);\n\n // Non-block text with autoDetect: render directly on a Text-equivalent element,\n // avoiding unnecessary <span> nesting inside <p>.\n if (autoDetect && !hasBlockContent) {\n const { variant, spacing, elementType, className, ...domProps } = textProps;\n const Element = getElementType(variant, elementType);\n const classes = buildTextClasses(textProps, htmlClassName);\n\n return containsHTML(text) ? (\n <Element\n ref={ref}\n {...domProps}\n className={classes}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n ) : (\n <Element ref={ref} {...domProps} className={classes}>\n {text}\n </Element>\n );\n }\n\n const DangerousComponent =\n htmlElementType ?? (hasBlockContent ? \"div\" : \"span\");\n const dangerousElement = (\n <DangerousComponent\n className={htmlClassName}\n dangerouslySetInnerHTML={dangerousHTML}\n />\n );\n\n if (textWrapper) {\n return (\n <Text ref={ref} {...textProps}>\n {dangerousElement}\n </Text>\n );\n }\n\n return dangerousElement;\n};\n\nTextOrHTML.displayName = \"TextOrHTML\";\nexport { TextOrHTML };\n", "import type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Text.css\";\n\nexport type TextElementType = HTMLHeadingElement | HTMLParagraphElement;\nexport type TextVariantType =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"body\"\n | \"small\"\n | \"legal\"\n | \"title\";\nexport type ElementType = \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"p\" | \"span\";\nexport interface TextProps extends DOMProps, RefAttributes<TextElementType> {\n /** HTML element for the text */\n elementType?: ElementType;\n /** Specify font size override */\n variant?: TextVariantType;\n /** Specify compact line height override */\n spacing?: \"loose\" | \"tight\";\n /** Custom class name for setting specific CSS */\n className?: string;\n children: ReactNode;\n style?: React.CSSProperties;\n}\n\nexport const getElementType = (\n variant: TextVariantType | undefined,\n elementType: ElementType | undefined,\n): ElementType => {\n // Explicit elementType always wins\n if (elementType) {\n return elementType;\n }\n // Infer element from variant\n if (variant && [\"h1\", \"h2\", \"h3\", \"h4\"].includes(variant)) {\n return variant as ElementType;\n }\n return \"p\";\n};\n\nconst Text = ({ ref, elementType, ...props }: TextProps) => {\n // Remove non-DOM props from element\n const { variant, className, spacing, ...otherProps } = props;\n\n // If a variant is supplied, set the class name and element type\n const Element: ElementType = getElementType(variant, elementType);\n const variantType = variant || Element;\n const classes = classNames(\n \"mobius\",\n \"mobius-text\",\n { [`--is-${variantType}`]: variantType },\n { [`--has-line-height-${spacing}`]: spacing },\n className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nText.displayName = \"Text\";\nexport { Text };\n", "import type React from \"react\";\nimport type { ReactNode, RefAttributes } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport \"./Label.css\";\n\nexport type LabelElementType = HTMLLabelElement;\nexport type IntrinsicLabel = Omit<\n React.JSX.IntrinsicElements[\"label\"],\n \"css\" | \"color\" | \"ref\"\n>;\n\nexport interface LabelProps\n extends IntrinsicLabel, DOMProps, RefAttributes<LabelElementType> {\n children?: ReactNode;\n className?: string;\n elementType?: \"label\" | \"span\";\n}\n\nconst Label = ({ ref, ...props }: LabelProps) => {\n const { elementType: Element = \"label\", children, ...otherProps } = props;\n\n const classes = classNames(\"mobius\", \"mobius-label\", props.className);\n otherProps.className = classes;\n\n return (\n <Element ref={ref} {...otherProps} className={classes}>\n {children}\n </Element>\n );\n};\n\nLabel.displayName = \"Label\";\nexport { Label };\n", "\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport type { ReactElement, ReactNode, RefAttributes } from \"react\";\nimport {\n Children,\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { useValidationClasses } from \"../../hooks\";\nimport type { Validation } from \"../../types\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { HTMLElementEvent } from \"../../types/events\";\nimport { spaceDelimitedList } from \"../../utils/spaceDelimitedList\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Stack } from \"../Stack\";\nimport type { RadioOverflowInfo } from \"./Radio\";\n\nexport type RadioGroupElementType = HTMLDivElement;\n\nexport interface RadioGroupProps\n extends DOMProps, Validation, RefAttributes<RadioGroupElementType> {\n children: ReactNode;\n className?: string;\n orientation?: \"horizontal\" | \"vertical\";\n errorMessage?: string;\n // Callback that fires when select changes\n onChange?: (event: HTMLElementEvent<HTMLInputElement>) => void;\n /**\n * Automatically change orientation from horizontal to vertical when any Radio label overflows.\n * Only applies when orientation is set to \"horizontal\".\n */\n autoStack?: boolean;\n // Defines a string value that labels the current element.\n \"aria-label\"?: string;\n // Identifies the element (or elements) that labels the current element.\n \"aria-labelledby\"?: string;\n // Identifies the element that provides an error message for the object.\n \"aria-errormessage\"?: string;\n // Identifies the element (or elements) that describes the object.\n \"aria-describedby\"?: string;\n // Whether user input is required on the input before form submission.\n isRequired?: boolean;\n // Whether the input is disabled.\n isDisabled?: boolean;\n // Whether the input can be selected but not changed by the user.\n isReadOnly?: boolean;\n // The default value (uncontrolled).\n defaultValue?: string;\n // The content to display as the label.\n label?: ReactNode;\n /**\n * The value of the radio button, used when submitting an HTML form.\n * See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio#Value).\n */\n value?: string;\n name?: string;\n}\n\nconst getDefaultVal = (children: ReactNode, defaultValue?: string) => {\n if (Array.isArray(children) && defaultValue) {\n const option = children?.find(item => item.props.value === defaultValue);\n\n if (!option) return \"\";\n\n return option.props.value;\n }\n\n return \"\";\n};\n\nconst RadioGroup = ({ ref, ...props }: RadioGroupProps) => {\n const {\n label,\n isDisabled = false,\n isRequired,\n isInvalid,\n orientation = \"vertical\",\n className,\n errorMessage,\n children,\n defaultValue,\n value,\n isReadOnly,\n name,\n onChange,\n autoStack = false,\n ...rest\n } = props;\n const defaultSelected = getDefaultVal(children, value || defaultValue);\n const [selected, setSelected] = useState<string>(defaultSelected);\n const overflowsRef = useRef<Record<string, RadioOverflowInfo>>({});\n const [hasOverflow, setHasOverflow] = useState(false);\n\n // Handle controlled behavior - update state when value prop changes\n useEffect(() => {\n if (value !== undefined) {\n setSelected(value);\n }\n }, [value]);\n\n // Handle overflow detection and auto-stack if needed\n const handleOverflow = useCallback(\n (radioValue: string, overflow: RadioOverflowInfo) => {\n overflowsRef.current = {\n ...overflowsRef.current,\n [radioValue]: overflow,\n };\n\n // Check if any radio has overflow\n const anyOverflow = Object.values(overflowsRef.current).some(\n o => o.vertical || o.horizontal,\n );\n\n if (anyOverflow !== hasOverflow) {\n setHasOverflow(anyOverflow);\n }\n },\n [hasOverflow],\n );\n\n // Determine effective orientation (auto-stack if needed)\n const effectiveOrientation =\n autoStack && orientation === \"horizontal\" && hasOverflow\n ? \"vertical\"\n : orientation;\n\n const validationClasses = useValidationClasses({ isInvalid });\n const radioClasses = {\n \"--is-disabled\": isDisabled,\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n [`--is-${effectiveOrientation}`]: true,\n [className || \"\"]: true,\n };\n const radioGroupClasses = classNames(\n \"mobius\",\n \"mobius-radio-group\",\n radioClasses,\n validationClasses,\n );\n const radioWrapperClasses = classNames(\"mobius-radio__wrapper\", {\n [`--is-${effectiveOrientation}`]: true,\n });\n const labelClasses = classNames(radioClasses, validationClasses);\n const errorMessageId = useId();\n const defaultNameAttrId = useId();\n const nameAttribute = name || defaultNameAttrId;\n const shouldErrorMessageShow = errorMessage ? errorMessageId : undefined;\n const describedBy = spaceDelimitedList([\n shouldErrorMessageShow,\n props[\"aria-describedby\"],\n ]);\n const labelId = useId();\n\n return (\n <div\n {...rest}\n aria-describedby={describedBy}\n aria-disabled={isDisabled}\n aria-errormessage={shouldErrorMessageShow}\n aria-invalid={isInvalid}\n aria-label={props[\"aria-label\"]}\n aria-labelledby={props[\"aria-labelledby\"] || labelId}\n aria-orientation={effectiveOrientation}\n aria-readonly={isReadOnly}\n aria-required={isRequired}\n ref={ref}\n className={radioGroupClasses}\n role=\"radiogroup\"\n >\n <Stack gap=\"xs\">\n {label && (\n <Label htmlFor={name} id={labelId} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className={radioWrapperClasses}>\n {Children.map(children, child => {\n if (isValidElement(child)) {\n const childValue = (child.props as { value?: string }).value;\n return cloneElement(\n child as ReactElement,\n {\n orientation: effectiveOrientation,\n groupDisabled: isDisabled,\n name: nameAttribute,\n selected: selected || defaultSelected, // in case state does not update\n setSelected,\n isRequired,\n \"aria-describedby\": describedBy,\n onChange,\n onOverflow: childValue\n ? (overflow: RadioOverflowInfo) =>\n handleOverflow(childValue, overflow)\n : undefined,\n } as Record<string, unknown>,\n );\n }\n\n return child;\n })}\n </div>\n <ErrorMessage id={errorMessageId} errorMessage={errorMessage} />\n </Stack>\n </div>\n );\n};\n\nRadioGroup.displayName = \"RadioGroup\";\nexport { RadioGroup };\n", "export function spaceDelimitedList(\n list: (string | null | undefined)[],\n): string | undefined {\n return list.filter(Boolean).join(\" \") || undefined;\n}\n", "import type { Validation } from \"../../types\";\n\nexport type GetValidationClassesProps = Pick<Validation, \"isInvalid\">;\n\nexport const useValidationClasses = (props: GetValidationClassesProps) => {\n const { isInvalid } = props;\n\n if (isInvalid) {\n return \"--is-invalid\";\n }\n\n if (isInvalid === false) {\n return \"--is-valid\";\n }\n\n return \"\";\n};\n", "import type { Ref, RefAttributes, ReactNode } from \"react\";\nimport type React from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport type { DOMProps } from \"../../types/dom\";\nimport type { SpacingType } from \"../../types\";\nimport \"./Stack.css\";\n\nexport type StackElementType = HTMLDivElement;\n\nexport interface StackProps extends DOMProps, RefAttributes<StackElementType> {\n children?: ReactNode;\n /** How big a gap between items */\n gap?: SpacingType;\n /** Custom class name for setting specific CSS */\n className?: string;\n elementType?: React.ElementType;\n}\n\nexport type StackRef = Ref<StackElementType>;\n\nexport const Stack = ({ ref, ...props }: StackProps) => {\n const { elementType: Element = \"div\", gap, ...otherProps } = props;\n\n const classes = classNames(\n \"mobius\",\n \"mobius-stack\",\n {\n [`--gap-${gap}`]: gap,\n },\n otherProps.className,\n );\n\n return <Element ref={ref} {...otherProps} className={classes} />;\n};\n\nStack.displayName = \"Stack\";\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_dedupe", "import_react", "import_dedupe", "classNames", "import_dedupe", "import_dedupe", "import_jsx_runtime", "classNames", "import_jsx_runtime", "classNames", "import_jsx_runtime", "classNames", "import_dedupe", "import_jsx_runtime", "classNames", "import_jsx_runtime", "props", "classNames", "import_dedupe", "import_react", "import_dedupe", "import_jsx_runtime", "classNames", "import_jsx_runtime", "classNames"]
|
|
7
7
|
}
|
|
@@ -188,7 +188,8 @@ Text.displayName = "Text";
|
|
|
188
188
|
|
|
189
189
|
// src/components/TextOrHTML/TextOrHTML.tsx
|
|
190
190
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
191
|
-
var
|
|
191
|
+
var BLOCK_TAG = /<(div|p|ul|ol|li|h[1-6]|table|tr|td|th|blockquote|pre|hr|dl|dt|dd)[\s>/]/i;
|
|
192
|
+
var containsBlockHTML = (text) => BLOCK_TAG.test(text);
|
|
192
193
|
var containsHTML = (text) => /<[a-z/]/i.test(text) || /&(?:#\d+|#x[\da-f]+|[a-z]\w*);/i.test(text);
|
|
193
194
|
var buildTextClasses = (textProps, htmlClassName) => {
|
|
194
195
|
const { variant, elementType, spacing, className } = textProps;
|
|
@@ -211,9 +212,9 @@ var TextOrHTML = ({
|
|
|
211
212
|
autoDetect = false,
|
|
212
213
|
...textProps
|
|
213
214
|
}) => {
|
|
214
|
-
const
|
|
215
|
+
const hasBlockContent = autoDetect && containsBlockHTML(text);
|
|
215
216
|
const dangerousHTML = (0, import_react2.useMemo)(() => ({ __html: text }), [text]);
|
|
216
|
-
if (autoDetect && !
|
|
217
|
+
if (autoDetect && !hasBlockContent) {
|
|
217
218
|
const { variant, spacing, elementType, className, ...domProps } = textProps;
|
|
218
219
|
const Element = getElementType(variant, elementType);
|
|
219
220
|
const classes = buildTextClasses(textProps, htmlClassName);
|
|
@@ -227,7 +228,7 @@ var TextOrHTML = ({
|
|
|
227
228
|
}
|
|
228
229
|
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Element, { ref, ...domProps, className: classes, children: text });
|
|
229
230
|
}
|
|
230
|
-
const DangerousComponent = htmlElementType ?? (
|
|
231
|
+
const DangerousComponent = htmlElementType ?? (hasBlockContent ? "div" : "span");
|
|
231
232
|
const dangerousElement = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
232
233
|
DangerousComponent,
|
|
233
234
|
{
|