@plexui/ui 0.20.14 → 0.20.16
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/dist/es/components/FieldError/FieldError.js +1 -1
- package/dist/es/components/FieldError/FieldError.js.map +1 -1
- package/dist/es/components/FloatingLabelInput/FloatingLabelInput.js +2 -2
- package/dist/es/components/FloatingLabelInput/FloatingLabelInput.js.map +1 -1
- package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.js +2 -2
- package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.js.map +1 -1
- package/dist/es/components/Tabs/Tabs.js +9 -8
- package/dist/es/components/Tabs/Tabs.js.map +1 -1
- package/dist/types/components/FloatingLabelInput/FloatingLabelInput.d.ts +22 -0
- package/dist/types/components/FloatingLabelSelect/FloatingLabelSelect.d.ts +22 -0
- package/package.json +1 -1
|
@@ -3,6 +3,6 @@ import clsx from "clsx";
|
|
|
3
3
|
import { ExclamationMarkCircle } from "../Icon/index.js";
|
|
4
4
|
import s from "@plexui/styles/components/FieldError/FieldError.module.css";
|
|
5
5
|
export function FieldError({ children, className, id, icon = true }) {
|
|
6
|
-
return (
|
|
6
|
+
return (_jsx("div", { className: clsx(s.FieldError, className), id: id, role: "alert", children: _jsxs("div", { className: s.Inner, children: [icon && _jsx(ExclamationMarkCircle, { className: s.Icon }), _jsx("span", { children: children })] }) }));
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=FieldError.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldError.js","sourceRoot":"","sources":["../../../../src/components/FieldError/FieldError.tsx"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,CAAC,MAAM,4DAA4D,CAAA;AAc1E,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI,EAAmB;IAClF,OAAO,CACL,
|
|
1
|
+
{"version":3,"file":"FieldError.js","sourceRoot":"","sources":["../../../../src/components/FieldError/FieldError.tsx"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,CAAC,MAAM,4DAA4D,CAAA;AAc1E,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI,EAAmB;IAClF,OAAO,CACL,cAAK,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAC,OAAO,YACjE,eAAK,SAAS,EAAE,CAAC,CAAC,KAAK,aACpB,IAAI,IAAI,KAAC,qBAAqB,IAAC,SAAS,EAAE,CAAC,CAAC,IAAI,GAAI,EACrD,yBAAO,QAAQ,GAAQ,IACnB,GACF,CACP,CAAA;AACH,CAAC","sourcesContent":["import clsx from \"clsx\"\n\nimport { ExclamationMarkCircle } from \"../Icon\"\n\nimport s from \"@plexui/styles/components/FieldError/FieldError.module.css\"\n\nexport type FieldErrorProps = {\n children: React.ReactNode\n className?: string\n id?: string\n /**\n * Shows the error icon before the message. Turn it off where the message\n * stands alone, such as under a centered code input.\n * @default true\n */\n icon?: boolean\n}\n\nexport function FieldError({ children, className, id, icon = true }: FieldErrorProps) {\n return (\n <div className={clsx(s.FieldError, className)} id={id} role=\"alert\">\n <div className={s.Inner}>\n {icon && <ExclamationMarkCircle className={s.Icon} />}\n <span>{children}</span>\n </div>\n </div>\n )\n}\n"]}
|
|
@@ -20,7 +20,7 @@ const textareaProps = (props) => {
|
|
|
20
20
|
return rest;
|
|
21
21
|
};
|
|
22
22
|
export const FloatingLabelInput = forwardRef(function FloatingLabelInput(props, ref) {
|
|
23
|
-
const { label, description, errorMessage, "invalid": invalidProp, disabled = false, readOnly = false, onClear, onAutofill, allowAutofillExtensions = false, startAdornment, endAdornment, revealable: revealableProp, onRevealedChange, multiline = false, rows = 2, className, "id": idProp, name, type = "text", value, defaultValue, onChange, onFocus, onBlur, onAnimationStart, "aria-describedby": ariaDescribedByProp, ...restProps } = props;
|
|
23
|
+
const { label, description, errorMessage, "invalid": invalidProp, disabled = false, readOnly = false, onClear, onAutofill, allowAutofillExtensions = false, startAdornment, endAdornment, revealable: revealableProp, onRevealedChange, multiline = false, rows = 2, labelPlacement = "border", pill = true, className, "id": idProp, name, type = "text", value, defaultValue, onChange, onFocus, onBlur, onAnimationStart, "aria-describedby": ariaDescribedByProp, ...restProps } = props;
|
|
24
24
|
const inputRef = useRef(null);
|
|
25
25
|
const generatedId = useId();
|
|
26
26
|
const inputId = idProp || `floating-label-input-${generatedId}`;
|
|
@@ -115,7 +115,7 @@ export const FloatingLabelInput = forwardRef(function FloatingLabelInput(props,
|
|
|
115
115
|
return next;
|
|
116
116
|
});
|
|
117
117
|
}, [onRevealedChange]);
|
|
118
|
-
return (_jsxs("div", { className: clsx(s.Root, className), children: [_jsxs("div", { className: clsx(s.FieldFootprint, {
|
|
118
|
+
return (_jsxs("div", { className: clsx(s.Root, className), "data-label-placement": labelPlacement === "inside" ? "inside" : undefined, "data-pill": pill && labelPlacement !== "inside" ? "" : undefined, children: [_jsxs("div", { className: clsx(s.FieldFootprint, {
|
|
119
119
|
[s.HasValue]: hasValue || !!startAdornment,
|
|
120
120
|
}), "data-focused": focused ? "" : undefined, "data-has-value": hasValue ? "" : undefined, "data-invalid": invalid ? "" : undefined, "data-disabled": disabled ? "" : undefined, "data-readonly": readOnly ? "" : undefined, "data-multiline": multiline ? "" : undefined, onMouseDown: handleContainerMouseDown, children: [_jsx("label", { className: s.TypeableLabel, htmlFor: inputId, children: _jsx("div", { className: s.LabelPositioner, children: _jsx("div", { className: s.LabelText, children: label }) }) }), startAdornment && (_jsx("div", { className: s.StartAdornment, children: startAdornment })), multiline ? (_jsx("textarea", { ...textareaProps(restProps), ref: mergeRefs([ref, inputRef]), id: inputId, name: name, rows: rows, className: s.Textarea, value: value, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur })) : (_jsx("input", { ...restProps, ref: mergeRefs([ref, inputRef]), id: inputId, name: name, type: effectiveType, className: s.Input, value: value, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, onAnimationStart: handleAnimationStart, "data-lpignore": allowAutofillExtensions ? undefined : true, "data-1p-ignore": allowAutofillExtensions ? undefined : true })), endAdornment && (_jsx("div", { className: s.EndAdornment, children: endAdornment })), showClearButton && (_jsx("button", { type: "button", "aria-label": "Clear input", className: s.ClearButton, onClick: handleClear, children: _jsx(X, {}) })), showRevealButton && (_jsx("button", { type: "button", "aria-label": revealed ? "Hide" : "Show", className: s.RevealButton, onClick: handleRevealToggle, children: revealed ? _jsx(EyeOff, {}) : _jsx(Eye, {}) }))] }), errorMessage && (_jsx("div", { id: errorId, className: s.ErrorMessage, role: "alert", children: errorMessage })), description && (_jsx("div", { id: descriptionId, className: s.Description, children: description }))] }));
|
|
121
121
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingLabelInput.js","sourceRoot":"","sources":["../../../../src/components/FloatingLabelInput/FloatingLabelInput.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { forwardRef, useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\n\nimport { Eye, EyeOff, X } from \"../Icon\"\n\nimport s from \"@plexui/styles/components/FloatingLabelInput/FloatingLabelInput.module.css\"\n\nexport type FloatingLabelInputProps = {\n /**\n * Label text for the floating label\n */\n label: string\n /**\n * Error message to display below the input\n */\n errorMessage?: string\n /**\n * Mark the input as invalid\n * @default false (or true if errorMessage is provided)\n */\n invalid?: boolean\n /**\n * Disables the input visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Makes the input read-only\n * @default false\n */\n readOnly?: boolean\n /**\n * Callback invoked when the clear button is clicked\n */\n onClear?: () => void\n /**\n * Callback invoked when the input is autofilled by the browser\n */\n onAutofill?: () => void\n /**\n * Allow autofill extensions to appear in the input\n * @default false\n */\n allowAutofillExtensions?: boolean\n /**\n * Helper/description text displayed below the input.\n * Shown alongside the error message when both are present.\n */\n description?: React.ReactNode\n /**\n * Content rendered before the input.\n */\n startAdornment?: React.ReactNode\n /**\n * Content rendered after the input, before the clear button.\n * For password fields the reveal toggle is built in — see `revealable`.\n */\n endAdornment?: React.ReactNode\n /**\n * Render a built-in reveal/hide toggle (eye icon) inside the field.\n * For `type=\"password\"` it swaps the input between `password` and `text`.\n * Defaults to `true` for password inputs that don't supply their own\n * `endAdornment`. Pass it explicitly to add the toggle to other sensitive\n * fields (e.g. a masked SSN) and react to it via `onRevealedChange`.\n * @default true when type=\"password\" and no endAdornment is provided\n */\n revealable?: boolean\n /**\n * Called with the new revealed state each time the reveal toggle is clicked.\n */\n onRevealedChange?: (revealed: boolean) => void\n /**\n * Render as a multi-line textarea instead of a single-line input.\n * @default false\n */\n multiline?: boolean\n /**\n * Number of visible text lines when `multiline` is true.\n * @default 2\n */\n rows?: number\n} & React.InputHTMLAttributes<HTMLInputElement>\n\n// Attributes that only mean something on <input>; everything else (required,\n// maxLength, placeholder, key and clipboard handlers, aria-*, data-*) also\n// applies to the multiline <textarea>\nconst INPUT_ONLY_PROPS = [\n \"accept\", \"alt\", \"capture\", \"checked\", \"height\", \"list\", \"max\", \"min\", \"multiple\",\n \"pattern\", \"size\", \"src\", \"step\", \"width\", \"formAction\", \"formEncType\",\n \"formMethod\", \"formNoValidate\", \"formTarget\",\n] as const\n\nconst textareaProps = (props: Record<string, unknown>) => {\n const rest = { ...props }\n for (const key of INPUT_ONLY_PROPS) delete rest[key]\n return rest\n}\n\nexport const FloatingLabelInput = forwardRef<HTMLInputElement, FloatingLabelInputProps>(\n function FloatingLabelInput(props, ref) {\n const {\n label,\n description,\n errorMessage,\n \"invalid\": invalidProp,\n disabled = false,\n readOnly = false,\n onClear,\n onAutofill,\n allowAutofillExtensions = false,\n startAdornment,\n endAdornment,\n revealable: revealableProp,\n onRevealedChange,\n multiline = false,\n rows = 2,\n className,\n \"id\": idProp,\n name,\n type = \"text\",\n value,\n defaultValue,\n onChange,\n onFocus,\n onBlur,\n onAnimationStart,\n \"aria-describedby\": ariaDescribedByProp,\n ...restProps\n } = props\n\n const inputRef = useRef<HTMLInputElement | null>(null)\n const generatedId = useId()\n const inputId = idProp || `floating-label-input-${generatedId}`\n const descriptionId = description ? `${inputId}-description` : undefined\n const errorId = errorMessage ? `${inputId}-error` : undefined\n\n const [focused, setFocused] = useState(false)\n const [hasValue, setHasValue] = useState(() => {\n return !!(value !== undefined ? value : defaultValue)\n })\n const [revealed, setRevealed] = useState(false)\n\n // Sync hasValue with controlled value prop\n useEffect(() => {\n if (value !== undefined) {\n setHasValue(!!value)\n }\n }, [value])\n\n const autoResize = useCallback(() => {\n const el = inputRef.current\n if (!multiline || !el) return\n el.style.height = \"auto\"\n el.style.height = `${el.scrollHeight}px`\n }, [multiline])\n\n // Also resize when a controlled value or rows changes without a keystroke\n useLayoutEffect(() => {\n autoResize()\n }, [autoResize, value, rows])\n\n const invalid = invalidProp ?? !!errorMessage\n\n // Determine if clear button should be shown\n const showClearButton = !!onClear && hasValue && !disabled && !readOnly\n\n // Built-in password reveal toggle\n const isPassword = type === \"password\"\n const revealable = revealableProp ?? (isPassword && !endAdornment)\n const showRevealButton = revealable && !disabled\n const effectiveType = isPassword && revealed ? \"text\" : type\n\n // Merge aria-describedby with error id\n const ariaDescribedBy =\n [ariaDescribedByProp, errorId, descriptionId].filter(Boolean).join(\" \") || undefined\n // An explicit aria-invalid (e.g. from Field) wins over the computed state\n const ariaInvalid = restProps[\"aria-invalid\"] ?? (invalid ? true : undefined)\n\n // Handle clicks on the container to focus the input\n const handleContainerMouseDown = useCallback((evt: React.MouseEvent<HTMLDivElement>) => {\n const input = inputRef.current\n if (!evt.target || !(evt.target instanceof Element) || !input) {\n return\n }\n if (input.contains(evt.target)) {\n return\n }\n if (evt.target.closest(\"button, [type='button'], [role='button']\")) {\n return\n }\n evt.preventDefault()\n if (document.activeElement !== input) {\n input.focus()\n }\n // email, number and other types without the selection API throw on setSelectionRange\n if (input.selectionStart === null) return\n const length = input.value.length\n input.setSelectionRange(length, length)\n }, [])\n\n // The clear button unmounts once the value is gone, so keep focus in the field\n const handleClear = useCallback(\n (evt: React.MouseEvent<HTMLButtonElement>) => {\n inputRef.current?.focus()\n ;(onClear as React.MouseEventHandler<HTMLButtonElement> | undefined)?.(evt)\n },\n [onClear],\n )\n\n const handleFocus = useCallback(\n (evt: React.FocusEvent<HTMLInputElement>) => {\n setFocused(true)\n onFocus?.(evt)\n },\n [onFocus],\n )\n\n const handleBlur = useCallback(\n (evt: React.FocusEvent<HTMLInputElement>) => {\n setFocused(false)\n onBlur?.(evt)\n },\n [onBlur],\n )\n\n const handleChange = useCallback(\n (evt: React.ChangeEvent<HTMLInputElement>) => {\n setHasValue(!!evt.currentTarget.value)\n onChange?.(evt)\n autoResize()\n },\n [onChange, autoResize],\n )\n\n const handleAnimationStart = useCallback(\n (evt: React.AnimationEvent<HTMLInputElement>) => {\n onAnimationStart?.(evt)\n // Detect browser autofill\n if (evt.animationName === \"native-autofill-in\") {\n setHasValue(true)\n onAutofill?.()\n }\n },\n [onAnimationStart, onAutofill],\n )\n\n const handleRevealToggle = useCallback(() => {\n setRevealed((prev) => {\n const next = !prev\n onRevealedChange?.(next)\n return next\n })\n }, [onRevealedChange])\n\n return (\n <div className={clsx(s.Root, className)}>\n <div\n className={clsx(s.FieldFootprint, {\n [s.HasValue]: hasValue || !!startAdornment,\n })}\n data-focused={focused ? \"\" : undefined}\n data-has-value={hasValue ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n data-readonly={readOnly ? \"\" : undefined}\n data-multiline={multiline ? \"\" : undefined}\n onMouseDown={handleContainerMouseDown}\n >\n <label className={s.TypeableLabel} htmlFor={inputId}>\n <div className={s.LabelPositioner}>\n <div className={s.LabelText}>{label}</div>\n </div>\n </label>\n {startAdornment && (\n <div className={s.StartAdornment}>{startAdornment}</div>\n )}\n {multiline ? (\n <textarea\n {...(textareaProps(restProps) as React.TextareaHTMLAttributes<HTMLTextAreaElement>)}\n ref={mergeRefs([ref, inputRef]) as React.Ref<HTMLTextAreaElement>}\n id={inputId}\n name={name}\n rows={rows}\n className={s.Textarea}\n value={value}\n defaultValue={defaultValue}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={ariaInvalid}\n aria-describedby={ariaDescribedBy}\n onChange={handleChange as unknown as React.ChangeEventHandler<HTMLTextAreaElement>}\n onFocus={handleFocus as unknown as React.FocusEventHandler<HTMLTextAreaElement>}\n onBlur={handleBlur as unknown as React.FocusEventHandler<HTMLTextAreaElement>}\n />\n ) : (\n <input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n id={inputId}\n name={name}\n type={effectiveType}\n className={s.Input}\n value={value}\n defaultValue={defaultValue}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={ariaInvalid}\n aria-describedby={ariaDescribedBy}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onAnimationStart={handleAnimationStart}\n data-lpignore={allowAutofillExtensions ? undefined : true}\n data-1p-ignore={allowAutofillExtensions ? undefined : true}\n />\n )}\n {endAdornment && (\n <div className={s.EndAdornment}>\n {endAdornment}\n </div>\n )}\n {showClearButton && (\n <button\n type=\"button\"\n aria-label=\"Clear input\"\n className={s.ClearButton}\n onClick={handleClear}\n >\n <X />\n </button>\n )}\n {showRevealButton && (\n <button\n type=\"button\"\n aria-label={revealed ? \"Hide\" : \"Show\"}\n className={s.RevealButton}\n onClick={handleRevealToggle}\n >\n {revealed ? <EyeOff /> : <Eye />}\n </button>\n )}\n </div>\n {errorMessage && (\n <div id={errorId} className={s.ErrorMessage} role=\"alert\">\n {errorMessage}\n </div>\n )}\n {description && (\n <div id={descriptionId} className={s.Description}>\n {description}\n </div>\n )}\n </div>\n )\n },\n)\n\nFloatingLabelInput.displayName = \"FloatingLabelInput\"\n"]}
|
|
1
|
+
{"version":3,"file":"FloatingLabelInput.js","sourceRoot":"","sources":["../../../../src/components/FloatingLabelInput/FloatingLabelInput.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { forwardRef, useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\n\nimport { Eye, EyeOff, X } from \"../Icon\"\n\nimport s from \"@plexui/styles/components/FloatingLabelInput/FloatingLabelInput.module.css\"\n\nexport type FloatingLabelInputProps = {\n /**\n * Label text for the floating label\n */\n label: string\n /**\n * Error message to display below the input\n */\n errorMessage?: string\n /**\n * Mark the input as invalid\n * @default false (or true if errorMessage is provided)\n */\n invalid?: boolean\n /**\n * Disables the input visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Makes the input read-only\n * @default false\n */\n readOnly?: boolean\n /**\n * Callback invoked when the clear button is clicked\n */\n onClear?: () => void\n /**\n * Callback invoked when the input is autofilled by the browser\n */\n onAutofill?: () => void\n /**\n * Allow autofill extensions to appear in the input\n * @default false\n */\n allowAutofillExtensions?: boolean\n /**\n * Helper/description text displayed below the input.\n * Shown alongside the error message when both are present.\n */\n description?: React.ReactNode\n /**\n * Content rendered before the input.\n */\n startAdornment?: React.ReactNode\n /**\n * Content rendered after the input, before the clear button.\n * For password fields the reveal toggle is built in — see `revealable`.\n */\n endAdornment?: React.ReactNode\n /**\n * Render a built-in reveal/hide toggle (eye icon) inside the field.\n * For `type=\"password\"` it swaps the input between `password` and `text`.\n * Defaults to `true` for password inputs that don't supply their own\n * `endAdornment`. Pass it explicitly to add the toggle to other sensitive\n * fields (e.g. a masked SSN) and react to it via `onRevealedChange`.\n * @default true when type=\"password\" and no endAdornment is provided\n */\n revealable?: boolean\n /**\n * Called with the new revealed state each time the reveal toggle is clicked.\n */\n onRevealedChange?: (revealed: boolean) => void\n /**\n * Render as a multi-line textarea instead of a single-line input.\n * @default false\n */\n multiline?: boolean\n /**\n * Number of visible text lines when `multiline` is true.\n * @default 2\n */\n rows?: number\n /**\n * Where the label rests once it floats: on the border, or inside the box\n * with the value under it. `inside` always takes the rounded box.\n * @default \"border\"\n */\n labelPlacement?: \"border\" | \"inside\"\n /**\n * Pill shape. `false` takes the rounded box of the other fields.\n * @default true\n */\n pill?: boolean\n} & React.InputHTMLAttributes<HTMLInputElement>\n\n// Attributes that only mean something on <input>; everything else (required,\n// maxLength, placeholder, key and clipboard handlers, aria-*, data-*) also\n// applies to the multiline <textarea>\nconst INPUT_ONLY_PROPS = [\n \"accept\", \"alt\", \"capture\", \"checked\", \"height\", \"list\", \"max\", \"min\", \"multiple\",\n \"pattern\", \"size\", \"src\", \"step\", \"width\", \"formAction\", \"formEncType\",\n \"formMethod\", \"formNoValidate\", \"formTarget\",\n] as const\n\nconst textareaProps = (props: Record<string, unknown>) => {\n const rest = { ...props }\n for (const key of INPUT_ONLY_PROPS) delete rest[key]\n return rest\n}\n\nexport const FloatingLabelInput = forwardRef<HTMLInputElement, FloatingLabelInputProps>(\n function FloatingLabelInput(props, ref) {\n const {\n label,\n description,\n errorMessage,\n \"invalid\": invalidProp,\n disabled = false,\n readOnly = false,\n onClear,\n onAutofill,\n allowAutofillExtensions = false,\n startAdornment,\n endAdornment,\n revealable: revealableProp,\n onRevealedChange,\n multiline = false,\n rows = 2,\n labelPlacement = \"border\",\n pill = true,\n className,\n \"id\": idProp,\n name,\n type = \"text\",\n value,\n defaultValue,\n onChange,\n onFocus,\n onBlur,\n onAnimationStart,\n \"aria-describedby\": ariaDescribedByProp,\n ...restProps\n } = props\n\n const inputRef = useRef<HTMLInputElement | null>(null)\n const generatedId = useId()\n const inputId = idProp || `floating-label-input-${generatedId}`\n const descriptionId = description ? `${inputId}-description` : undefined\n const errorId = errorMessage ? `${inputId}-error` : undefined\n\n const [focused, setFocused] = useState(false)\n const [hasValue, setHasValue] = useState(() => {\n return !!(value !== undefined ? value : defaultValue)\n })\n const [revealed, setRevealed] = useState(false)\n\n // Sync hasValue with controlled value prop\n useEffect(() => {\n if (value !== undefined) {\n setHasValue(!!value)\n }\n }, [value])\n\n const autoResize = useCallback(() => {\n const el = inputRef.current\n if (!multiline || !el) return\n el.style.height = \"auto\"\n el.style.height = `${el.scrollHeight}px`\n }, [multiline])\n\n // Also resize when a controlled value or rows changes without a keystroke\n useLayoutEffect(() => {\n autoResize()\n }, [autoResize, value, rows])\n\n const invalid = invalidProp ?? !!errorMessage\n\n // Determine if clear button should be shown\n const showClearButton = !!onClear && hasValue && !disabled && !readOnly\n\n // Built-in password reveal toggle\n const isPassword = type === \"password\"\n const revealable = revealableProp ?? (isPassword && !endAdornment)\n const showRevealButton = revealable && !disabled\n const effectiveType = isPassword && revealed ? \"text\" : type\n\n // Merge aria-describedby with error id\n const ariaDescribedBy =\n [ariaDescribedByProp, errorId, descriptionId].filter(Boolean).join(\" \") || undefined\n // An explicit aria-invalid (e.g. from Field) wins over the computed state\n const ariaInvalid = restProps[\"aria-invalid\"] ?? (invalid ? true : undefined)\n\n // Handle clicks on the container to focus the input\n const handleContainerMouseDown = useCallback((evt: React.MouseEvent<HTMLDivElement>) => {\n const input = inputRef.current\n if (!evt.target || !(evt.target instanceof Element) || !input) {\n return\n }\n if (input.contains(evt.target)) {\n return\n }\n if (evt.target.closest(\"button, [type='button'], [role='button']\")) {\n return\n }\n evt.preventDefault()\n if (document.activeElement !== input) {\n input.focus()\n }\n // email, number and other types without the selection API throw on setSelectionRange\n if (input.selectionStart === null) return\n const length = input.value.length\n input.setSelectionRange(length, length)\n }, [])\n\n // The clear button unmounts once the value is gone, so keep focus in the field\n const handleClear = useCallback(\n (evt: React.MouseEvent<HTMLButtonElement>) => {\n inputRef.current?.focus()\n ;(onClear as React.MouseEventHandler<HTMLButtonElement> | undefined)?.(evt)\n },\n [onClear],\n )\n\n const handleFocus = useCallback(\n (evt: React.FocusEvent<HTMLInputElement>) => {\n setFocused(true)\n onFocus?.(evt)\n },\n [onFocus],\n )\n\n const handleBlur = useCallback(\n (evt: React.FocusEvent<HTMLInputElement>) => {\n setFocused(false)\n onBlur?.(evt)\n },\n [onBlur],\n )\n\n const handleChange = useCallback(\n (evt: React.ChangeEvent<HTMLInputElement>) => {\n setHasValue(!!evt.currentTarget.value)\n onChange?.(evt)\n autoResize()\n },\n [onChange, autoResize],\n )\n\n const handleAnimationStart = useCallback(\n (evt: React.AnimationEvent<HTMLInputElement>) => {\n onAnimationStart?.(evt)\n // Detect browser autofill\n if (evt.animationName === \"native-autofill-in\") {\n setHasValue(true)\n onAutofill?.()\n }\n },\n [onAnimationStart, onAutofill],\n )\n\n const handleRevealToggle = useCallback(() => {\n setRevealed((prev) => {\n const next = !prev\n onRevealedChange?.(next)\n return next\n })\n }, [onRevealedChange])\n\n return (\n <div\n className={clsx(s.Root, className)}\n data-label-placement={labelPlacement === \"inside\" ? \"inside\" : undefined}\n data-pill={pill && labelPlacement !== \"inside\" ? \"\" : undefined}\n >\n <div\n className={clsx(s.FieldFootprint, {\n [s.HasValue]: hasValue || !!startAdornment,\n })}\n data-focused={focused ? \"\" : undefined}\n data-has-value={hasValue ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n data-readonly={readOnly ? \"\" : undefined}\n data-multiline={multiline ? \"\" : undefined}\n onMouseDown={handleContainerMouseDown}\n >\n <label className={s.TypeableLabel} htmlFor={inputId}>\n <div className={s.LabelPositioner}>\n <div className={s.LabelText}>{label}</div>\n </div>\n </label>\n {startAdornment && (\n <div className={s.StartAdornment}>{startAdornment}</div>\n )}\n {multiline ? (\n <textarea\n {...(textareaProps(restProps) as React.TextareaHTMLAttributes<HTMLTextAreaElement>)}\n ref={mergeRefs([ref, inputRef]) as React.Ref<HTMLTextAreaElement>}\n id={inputId}\n name={name}\n rows={rows}\n className={s.Textarea}\n value={value}\n defaultValue={defaultValue}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={ariaInvalid}\n aria-describedby={ariaDescribedBy}\n onChange={handleChange as unknown as React.ChangeEventHandler<HTMLTextAreaElement>}\n onFocus={handleFocus as unknown as React.FocusEventHandler<HTMLTextAreaElement>}\n onBlur={handleBlur as unknown as React.FocusEventHandler<HTMLTextAreaElement>}\n />\n ) : (\n <input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n id={inputId}\n name={name}\n type={effectiveType}\n className={s.Input}\n value={value}\n defaultValue={defaultValue}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={ariaInvalid}\n aria-describedby={ariaDescribedBy}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onAnimationStart={handleAnimationStart}\n data-lpignore={allowAutofillExtensions ? undefined : true}\n data-1p-ignore={allowAutofillExtensions ? undefined : true}\n />\n )}\n {endAdornment && (\n <div className={s.EndAdornment}>\n {endAdornment}\n </div>\n )}\n {showClearButton && (\n <button\n type=\"button\"\n aria-label=\"Clear input\"\n className={s.ClearButton}\n onClick={handleClear}\n >\n <X />\n </button>\n )}\n {showRevealButton && (\n <button\n type=\"button\"\n aria-label={revealed ? \"Hide\" : \"Show\"}\n className={s.RevealButton}\n onClick={handleRevealToggle}\n >\n {revealed ? <EyeOff /> : <Eye />}\n </button>\n )}\n </div>\n {errorMessage && (\n <div id={errorId} className={s.ErrorMessage} role=\"alert\">\n {errorMessage}\n </div>\n )}\n {description && (\n <div id={descriptionId} className={s.Description}>\n {description}\n </div>\n )}\n </div>\n )\n },\n)\n\nFloatingLabelInput.displayName = \"FloatingLabelInput\"\n"]}
|
|
@@ -6,7 +6,7 @@ import { Button } from "../Button/index.js";
|
|
|
6
6
|
import { Dropdown, X } from "../Icon/index.js";
|
|
7
7
|
import s from "@plexui/styles/components/FloatingLabelSelect/FloatingLabelSelect.module.css";
|
|
8
8
|
export const FloatingLabelSelect = forwardRef(function FloatingLabelSelect(props, ref) {
|
|
9
|
-
const { label, selected = false, errorMessage, "invalid": invalidProp, disabled = false, open = false, onInteract, onClearClick, children, className, "aria-describedby": ariaDescribedByProp, onKeyDown, ...restProps } = props;
|
|
9
|
+
const { label, selected = false, errorMessage, "invalid": invalidProp, disabled = false, open = false, onInteract, onClearClick, labelPlacement = "border", pill = true, children, className, "aria-describedby": ariaDescribedByProp, onKeyDown, ...restProps } = props;
|
|
10
10
|
const generatedId = useId();
|
|
11
11
|
const errorId = `floating-label-select-${generatedId}-error`;
|
|
12
12
|
const invalid = invalidProp ?? !!errorMessage;
|
|
@@ -58,7 +58,7 @@ export const FloatingLabelSelect = forwardRef(function FloatingLabelSelect(props
|
|
|
58
58
|
evt.preventDefault();
|
|
59
59
|
onClearClick?.();
|
|
60
60
|
}, [onClearClick]);
|
|
61
|
-
return (_jsxs("div", { className: clsx(s.Root, className), children: [_jsxs("div", {
|
|
61
|
+
return (_jsxs("div", { className: clsx(s.Root, className), "data-label-placement": labelPlacement === "inside" ? "inside" : undefined, "data-pill": pill && labelPlacement !== "inside" ? "" : undefined, children: [_jsxs("div", {
|
|
62
62
|
// The ref is the focusable field: a wrapping trigger returns focus to it and anchors to it
|
|
63
63
|
ref: ref, className: clsx(s.FieldFootprint, {
|
|
64
64
|
[s.HasValue]: selected,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingLabelSelect.js","sourceRoot":"","sources":["../../../../src/components/FloatingLabelSelect/FloatingLabelSelect.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { forwardRef, useCallback, useId } from \"react\"\n\nimport { Button } from \"../Button\"\nimport { Dropdown, X } from \"../Icon\"\n\nimport s from \"@plexui/styles/components/FloatingLabelSelect/FloatingLabelSelect.module.css\"\n\nexport type FloatingLabelSelectProps = {\n label: string\n selected?: boolean\n errorMessage?: string\n invalid?: boolean\n disabled?: boolean\n open?: boolean\n onInteract?: () => void\n onClearClick?: () => void\n children?: React.ReactNode\n className?: string\n \"aria-describedby\"?: string\n} & Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"children\" | \"role\" | \"tabIndex\" | \"aria-describedby\"\n>\n\nexport const FloatingLabelSelect = forwardRef<HTMLDivElement, FloatingLabelSelectProps>(\n function FloatingLabelSelect(props, ref) {\n const {\n label,\n selected = false,\n errorMessage,\n \"invalid\": invalidProp,\n disabled = false,\n open = false,\n onInteract,\n onClearClick,\n children,\n className,\n \"aria-describedby\": ariaDescribedByProp,\n onKeyDown,\n ...restProps\n } = props\n\n const generatedId = useId()\n const errorId = `floating-label-select-${generatedId}-error`\n\n const invalid = invalidProp ?? !!errorMessage\n\n const showClearButton = !!onClearClick && selected && !disabled\n\n const ariaDescribedBy =\n [ariaDescribedByProp, errorMessage ? errorId : undefined].filter(Boolean).join(\" \") ||\n undefined\n\n const handlePointerDown = useCallback(\n (evt: React.PointerEvent<HTMLDivElement>) => {\n if (evt.button === 2 || disabled) return\n evt.preventDefault()\n onInteract?.()\n },\n [disabled, onInteract],\n )\n\n const handleKeyDown = useCallback(\n (evt: React.KeyboardEvent<HTMLDivElement>) => {\n // Enter and Space on a nested control (the clear button) activate that\n // control: neither this handler nor a wrapping trigger's may take them\n if (evt.target !== evt.currentTarget && (evt.key === \" \" || evt.key === \"Enter\")) return\n onKeyDown?.(evt)\n // A handler that prevented the default (the caller's, or a wrapping\n // Menu.Trigger's that opened its menu) cancels the built-in handling\n if (disabled || evt.defaultPrevented) return\n\n switch (evt.key) {\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \" \":\n case \"Enter\":\n // Enter activates the field only without onInteract, as it\n // would the button a wrapping trigger usually renders\n if (evt.key === \"Enter\" && onInteract) break\n evt.stopPropagation()\n evt.preventDefault()\n if (onInteract) {\n onInteract()\n } else {\n // A wrapping trigger (Select's `trigger`, a Popover.Trigger) opens on click\n evt.currentTarget.click()\n }\n break\n }\n },\n [disabled, onInteract, onKeyDown],\n )\n\n const handleClearPointerDown = useCallback((evt: React.PointerEvent<HTMLButtonElement>) => {\n evt.stopPropagation()\n }, [])\n\n const handleClearClick = useCallback(\n (evt: React.MouseEvent<HTMLButtonElement>) => {\n evt.stopPropagation()\n evt.preventDefault()\n onClearClick?.()\n },\n [onClearClick],\n )\n\n return (\n <div className={clsx(s.Root, className)}>\n <div\n // The ref is the focusable field: a wrapping trigger returns focus to it and anchors to it\n ref={ref}\n className={clsx(s.FieldFootprint, {\n [s.HasValue]: selected,\n })}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n data-open={open ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-invalid={invalid ? true : undefined}\n aria-describedby={ariaDescribedBy}\n aria-disabled={disabled || undefined}\n onPointerDown={handlePointerDown}\n onKeyDown={handleKeyDown}\n {...restProps}\n >\n <div className={s.TypeableLabel}>\n <div className={s.LabelPositioner}>\n <div className={s.LabelText}>{label}</div>\n </div>\n </div>\n <span className={s.Content}>{selected ? children : null}</span>\n <div className={s.IndicatorWrapper}>\n {showClearButton && (\n <Button\n aria-label=\"Clear selection\"\n className={s.Clear}\n onPointerDown={handleClearPointerDown}\n onClick={handleClearClick}\n color=\"secondary\"\n variant=\"ghost\"\n size=\"3xs\"\n uniform\n pill\n >\n <X />\n </Button>\n )}\n <Dropdown className={s.DropdownIcon} />\n </div>\n </div>\n {errorMessage && (\n // Same plain line as FloatingLabelInput, so the two read alike on one form\n <div id={errorId} className={s.ErrorMessage} role=\"alert\">\n {errorMessage}\n </div>\n )}\n </div>\n )\n },\n)\n\nFloatingLabelSelect.displayName = \"FloatingLabelSelect\"\n"]}
|
|
1
|
+
{"version":3,"file":"FloatingLabelSelect.js","sourceRoot":"","sources":["../../../../src/components/FloatingLabelSelect/FloatingLabelSelect.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { forwardRef, useCallback, useId } from \"react\"\n\nimport { Button } from \"../Button\"\nimport { Dropdown, X } from \"../Icon\"\n\nimport s from \"@plexui/styles/components/FloatingLabelSelect/FloatingLabelSelect.module.css\"\n\nexport type FloatingLabelSelectProps = {\n label: string\n selected?: boolean\n errorMessage?: string\n invalid?: boolean\n disabled?: boolean\n open?: boolean\n onInteract?: () => void\n onClearClick?: () => void\n /**\n * Where the label rests once it floats: on the border, or inside the box\n * with the value under it. `inside` always takes the rounded box.\n * @default \"border\"\n */\n labelPlacement?: \"border\" | \"inside\"\n /**\n * Pill shape. `false` takes the rounded box of the other fields.\n * @default true\n */\n pill?: boolean\n children?: React.ReactNode\n className?: string\n \"aria-describedby\"?: string\n} & Omit<\n React.HTMLAttributes<HTMLDivElement>,\n \"children\" | \"role\" | \"tabIndex\" | \"aria-describedby\"\n>\n\nexport const FloatingLabelSelect = forwardRef<HTMLDivElement, FloatingLabelSelectProps>(\n function FloatingLabelSelect(props, ref) {\n const {\n label,\n selected = false,\n errorMessage,\n \"invalid\": invalidProp,\n disabled = false,\n open = false,\n onInteract,\n onClearClick,\n labelPlacement = \"border\",\n pill = true,\n children,\n className,\n \"aria-describedby\": ariaDescribedByProp,\n onKeyDown,\n ...restProps\n } = props\n\n const generatedId = useId()\n const errorId = `floating-label-select-${generatedId}-error`\n\n const invalid = invalidProp ?? !!errorMessage\n\n const showClearButton = !!onClearClick && selected && !disabled\n\n const ariaDescribedBy =\n [ariaDescribedByProp, errorMessage ? errorId : undefined].filter(Boolean).join(\" \") ||\n undefined\n\n const handlePointerDown = useCallback(\n (evt: React.PointerEvent<HTMLDivElement>) => {\n if (evt.button === 2 || disabled) return\n evt.preventDefault()\n onInteract?.()\n },\n [disabled, onInteract],\n )\n\n const handleKeyDown = useCallback(\n (evt: React.KeyboardEvent<HTMLDivElement>) => {\n // Enter and Space on a nested control (the clear button) activate that\n // control: neither this handler nor a wrapping trigger's may take them\n if (evt.target !== evt.currentTarget && (evt.key === \" \" || evt.key === \"Enter\")) return\n onKeyDown?.(evt)\n // A handler that prevented the default (the caller's, or a wrapping\n // Menu.Trigger's that opened its menu) cancels the built-in handling\n if (disabled || evt.defaultPrevented) return\n\n switch (evt.key) {\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \" \":\n case \"Enter\":\n // Enter activates the field only without onInteract, as it\n // would the button a wrapping trigger usually renders\n if (evt.key === \"Enter\" && onInteract) break\n evt.stopPropagation()\n evt.preventDefault()\n if (onInteract) {\n onInteract()\n } else {\n // A wrapping trigger (Select's `trigger`, a Popover.Trigger) opens on click\n evt.currentTarget.click()\n }\n break\n }\n },\n [disabled, onInteract, onKeyDown],\n )\n\n const handleClearPointerDown = useCallback((evt: React.PointerEvent<HTMLButtonElement>) => {\n evt.stopPropagation()\n }, [])\n\n const handleClearClick = useCallback(\n (evt: React.MouseEvent<HTMLButtonElement>) => {\n evt.stopPropagation()\n evt.preventDefault()\n onClearClick?.()\n },\n [onClearClick],\n )\n\n return (\n <div\n className={clsx(s.Root, className)}\n data-label-placement={labelPlacement === \"inside\" ? \"inside\" : undefined}\n data-pill={pill && labelPlacement !== \"inside\" ? \"\" : undefined}\n >\n <div\n // The ref is the focusable field: a wrapping trigger returns focus to it and anchors to it\n ref={ref}\n className={clsx(s.FieldFootprint, {\n [s.HasValue]: selected,\n })}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n data-open={open ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-invalid={invalid ? true : undefined}\n aria-describedby={ariaDescribedBy}\n aria-disabled={disabled || undefined}\n onPointerDown={handlePointerDown}\n onKeyDown={handleKeyDown}\n {...restProps}\n >\n <div className={s.TypeableLabel}>\n <div className={s.LabelPositioner}>\n <div className={s.LabelText}>{label}</div>\n </div>\n </div>\n <span className={s.Content}>{selected ? children : null}</span>\n <div className={s.IndicatorWrapper}>\n {showClearButton && (\n <Button\n aria-label=\"Clear selection\"\n className={s.Clear}\n onPointerDown={handleClearPointerDown}\n onClick={handleClearClick}\n color=\"secondary\"\n variant=\"ghost\"\n size=\"3xs\"\n uniform\n pill\n >\n <X />\n </Button>\n )}\n <Dropdown className={s.DropdownIcon} />\n </div>\n </div>\n {errorMessage && (\n // Same plain line as FloatingLabelInput, so the two read alike on one form\n <div id={errorId} className={s.ErrorMessage} role=\"alert\">\n {errorMessage}\n </div>\n )}\n </div>\n )\n },\n)\n\nFloatingLabelSelect.displayName = \"FloatingLabelSelect\"\n"]}
|
|
@@ -141,16 +141,17 @@ const TabsRoot = ({ value, onChange, children, variant = "segmented", orientatio
|
|
|
141
141
|
});
|
|
142
142
|
});
|
|
143
143
|
}
|
|
144
|
+
else if (thumb.style.transition) {
|
|
145
|
+
// Normal update (value change, etc.): the thumb leaves with the label's colour
|
|
146
|
+
applyThumbSizing(true);
|
|
147
|
+
}
|
|
144
148
|
else {
|
|
145
|
-
//
|
|
149
|
+
// First measure: apply transition after initial calculation is set
|
|
146
150
|
waitForAnimationFrame(() => {
|
|
147
|
-
applyThumbSizing(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
thumb.style.transition = transitionProperty;
|
|
152
|
-
});
|
|
153
|
-
}
|
|
151
|
+
applyThumbSizing(false);
|
|
152
|
+
waitForAnimationFrame(() => {
|
|
153
|
+
thumb.style.transition = transitionProperty;
|
|
154
|
+
});
|
|
154
155
|
});
|
|
155
156
|
}
|
|
156
157
|
}, [applyThumbSizing, value, size, gutterSize, pill, flush, transitionProperty]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../../../src/components/Tabs/Tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { ToggleGroup } from \"radix-ui\"\nimport {\n Children,\n cloneElement,\n Fragment,\n isValidElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n} from \"react\"\nimport { useResizeObserver } from \"usehooks-ts\"\nimport { handlePressableMouseEnter, waitForAnimationFrame } from \"../../lib/helpers\"\nimport { type ControlSize, type SemanticColors, type Sizes, type Variants } from \"../../types\"\nimport { ChevronDownMd } from \"../Icon\"\nimport { LoadingIndicator } from \"../Indicator\"\nimport { Menu } from \"../Menu\"\nimport { fitCount, visibleTabCount } from \"./overflow\"\nimport s from \"@plexui/styles/components/Tabs/Tabs.module.css\"\n\nexport type SizeVariant = \"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nexport type TabsVariant = \"segmented\" | \"underline\"\nexport type TabsOrientation = \"horizontal\" | \"vertical\"\n\nexport type TabsProps<T extends string> = {\n /**\n * Controlled value for the group\n */\n \"value\": T\n /** Callback for when a new value is selected */\n \"onChange\"?: (nextValue: T) => void\n /** Callback any time the control is clicked (even if a new value was not selected) */\n \"onClick\"?: () => void\n /**\n * Text read aloud to screen readers when the control is focused\n */\n \"aria-label\": string\n /**\n * Visual variant of the tab group\n * - `\"segmented\"` — background container with sliding highlight (default)\n * - `\"underline\"` — no background, animated line indicator under active tab\n * @default \"segmented\"\n */\n \"variant\"?: TabsVariant\n /**\n * Orientation of the tab layout\n * @default \"horizontal\"\n */\n \"orientation\"?: TabsOrientation\n /**\n * Controls the size of the tabs\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n *\n * @default md\n */\n \"size\"?: ControlSize\n /**\n * Controls gutter on the edges of the button, defaults to value from `size`.\n *\n * | 2xs | xs | sm | md | lg | xl |\n * | ------ | ------ | ------ | ------ | ------ | ------ |\n * | `6px` | `8px` | `10px` | `12px` | `14px` | `16px` |\n */\n \"gutterSize\"?: Sizes<\"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\">\n /** Disable the entire group */\n \"disabled\"?: boolean\n /**\n * Display the control as a block element with equal width segments\n * @default false\n */\n \"block\"?: boolean\n /**\n * Determines if the tabs should be a fully rounded pill shape.\n * Only applies to the `\"segmented\"` variant.\n * @default true\n */\n \"pill\"?: boolean\n /**\n * Flush underline style — removes tab padding so the indicator\n * matches the text width exactly, uses gap for spacing, and\n * removes the bottom border.\n * Only applies to the `\"underline\"` variant.\n * @default false\n */\n \"flush\"?: boolean\n /**\n * What happens to tabs that do not fit in one row: the strip scrolls\n * sideways (`scroll`), or the tabs that do not fit move into a menu at the\n * end of the strip (`menu`). The menu button shows the active tab's name\n * when it is one of the hidden ones. Horizontal tabs without `block` only.\n * @default \"scroll\"\n */\n \"overflow\"?: \"scroll\" | \"menu\"\n /**\n * Text of the menu button with `overflow=\"menu\"`\n * @default \"More\"\n */\n \"overflowLabel\"?: string\n \"className\"?: string\n \"children\": React.ReactNode\n}\n\nexport const Tabs = <T extends string>({ overflow = \"scroll\", overflowLabel = \"More\", ...props }: TabsProps<T>) => {\n if (overflow === \"menu\" && !props.block && props.orientation !== \"vertical\") {\n return <OverflowTabs {...props} overflowLabel={overflowLabel} />\n }\n return <TabsRoot {...props} />\n}\n\nconst TabsRoot = <T extends string>({\n value,\n onChange,\n children,\n variant = \"segmented\",\n orientation = \"horizontal\",\n block,\n pill = true,\n flush,\n size = \"md\",\n gutterSize,\n className,\n onClick,\n ...restProps\n}: Omit<TabsProps<T>, \"overflow\" | \"overflowLabel\">) => {\n const rootRef = useRef<HTMLDivElement>(null)\n const thumbRef = useRef<HTMLDivElement>(null)\n const prevSizeRef = useRef(size)\n const isVertical = orientation === \"vertical\"\n\n const applyThumbSizing = useCallback(\n (attemptScroll: boolean) => {\n const root = rootRef.current\n const thumb = thumbRef.current\n\n if (!root || !thumb) {\n return\n }\n\n // Get selected node\n const activeNode = root?.querySelector<HTMLDivElement>('[data-state=\"on\"]')\n\n // Impossible\n if (!activeNode) {\n return\n }\n\n if (isVertical) {\n const rootHeight = root.clientHeight\n let targetHeight = Math.floor(activeNode.clientHeight)\n const targetOffset = activeNode.offsetTop\n\n // Detect subpixel edge case\n if (rootHeight - (targetHeight + targetOffset) < 2) {\n targetHeight = targetHeight - 1\n }\n\n thumb.style.height = `${Math.floor(targetHeight)}px`\n thumb.style.width = \"\"\n thumb.style.transform = `translateY(${targetOffset}px)`\n\n // Scroll into view if needed\n if (root.scrollHeight > rootHeight) {\n const buffer = rootHeight * 0.15\n const scrollTop = root.scrollTop\n const top = activeNode.offsetTop\n const bottom = top + targetHeight\n if (top < scrollTop + buffer || bottom > scrollTop + rootHeight - buffer) {\n if (attemptScroll) {\n activeNode.scrollIntoView({ block: \"center\", inline: \"nearest\", behavior: \"smooth\" })\n }\n }\n }\n } else {\n const rootWidth = root.clientWidth\n let targetWidth = Math.floor(activeNode.clientWidth)\n const targetOffset = activeNode.offsetLeft\n\n // Detect if the thumb is moving too far to the edge of the container.\n // This would most commonly be due to subpixel widths adding up to excessive distance.\n if (rootWidth - (targetWidth + targetOffset) < 2) {\n targetWidth = targetWidth - 1\n }\n\n thumb.style.width = `${Math.floor(targetWidth)}px`\n thumb.style.height = \"\"\n thumb.style.transform = `translateX(${targetOffset}px)`\n\n // If the control is scrollable, ensure the active option is visible\n if (root.scrollWidth > rootWidth) {\n // Only scroll items near the edge, but not the inner 2/3.\n const buffer = rootWidth * 0.15\n const scrollLeft = root.scrollLeft\n const left = activeNode.offsetLeft\n const right = left + targetWidth\n if (left < scrollLeft + buffer || right > scrollLeft + rootWidth - buffer) {\n // Cheap trick to avoid unintentional scroll on mount - transition is set after mounting\n if (attemptScroll) {\n activeNode.scrollIntoView({ block: \"nearest\", inline: \"center\", behavior: \"smooth\" })\n }\n }\n }\n }\n },\n [isVertical],\n )\n\n useResizeObserver({\n // @ts-expect-error(2322) -- bug in types: https://github.com/juliencrn/usehooks-ts/issues/663\n ref: rootRef,\n onResize: () => {\n const thumb = thumbRef.current\n\n if (!thumb) {\n return\n }\n\n // Perform the size update instantly\n const currentTransition = thumb.style.transition\n thumb.style.transition = \"\"\n applyThumbSizing(false)\n thumb.style.transition = currentTransition\n },\n })\n\n // Tabs added, removed, reordered or relabelled move the active tab without\n // resizing the group: measure again, instantly, like a resize\n useEffect(() => {\n const root = rootRef.current\n if (!root || typeof MutationObserver === \"undefined\") return\n const observer = new MutationObserver(() => {\n const thumb = thumbRef.current\n if (!thumb) return\n const currentTransition = thumb.style.transition\n thumb.style.transition = \"\"\n applyThumbSizing(false)\n thumb.style.transition = currentTransition\n })\n observer.observe(root, { childList: true, characterData: true, subtree: true })\n return () => observer.disconnect()\n }, [applyThumbSizing])\n\n const transitionProperty = isVertical\n ? \"height 200ms var(--cubic-enter), transform 200ms var(--cubic-enter)\"\n : \"width 200ms var(--cubic-enter), transform 200ms var(--cubic-enter)\"\n\n useLayoutEffect(() => {\n const root = rootRef.current\n const thumb = thumbRef.current\n\n if (!root || !thumb) {\n return\n }\n\n const sizeChanged = prevSizeRef.current !== size\n prevSizeRef.current = size\n\n if (sizeChanged) {\n // Size changed - disable transition, wait for CSS, then apply sizing\n const currentTransition = thumb.style.transition\n thumb.style.transition = \"\"\n\n waitForAnimationFrame(() => {\n applyThumbSizing(false)\n waitForAnimationFrame(() => {\n thumb.style.transition = currentTransition\n })\n })\n } else {\n // Normal update (value change, etc.)\n waitForAnimationFrame(() => {\n applyThumbSizing(!!thumb.style.transition)\n\n // Apply transition after initial calculation is set\n if (!thumb.style.transition) {\n waitForAnimationFrame(() => {\n thumb.style.transition = transitionProperty\n })\n }\n })\n }\n }, [applyThumbSizing, value, size, gutterSize, pill, flush, transitionProperty])\n\n const handleValueChange = (nextValue: T) => {\n // Only trigger onChange when a value exists\n // Disallow toggling off enabled items\n if (nextValue && onChange) onChange(nextValue)\n }\n\n // Only apply pill for segmented variant\n const isPill = variant === \"segmented\" && pill\n // Only apply flush for underline variant\n const isFlush = variant === \"underline\" && flush\n\n return (\n <ToggleGroup.Root\n ref={rootRef}\n className={clsx(s.Tabs, className)}\n type=\"single\"\n value={value}\n loop={false}\n onValueChange={handleValueChange}\n onClick={onClick}\n data-variant={variant}\n data-orientation={orientation}\n data-block={block ? \"\" : undefined}\n data-pill={isPill ? \"\" : undefined}\n data-flush={isFlush ? \"\" : undefined}\n data-size={size}\n data-gutter-size={gutterSize}\n {...restProps}\n >\n <div className={s.TabsThumb} ref={thumbRef} />\n {children}\n </ToggleGroup.Root>\n )\n}\n\n/**\n * Badge configuration for Tabs.Tab\n */\nexport type TabsBadgeProp =\n | React.ReactNode\n | {\n content: React.ReactNode\n color?: SemanticColors<\n \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"discovery\" | \"caution\"\n >\n variant?: Variants<\"soft\" | \"solid\">\n pill?: boolean\n loading?: boolean\n }\n\nexport type TabProps = {\n /**\n * Tab value\n */\n \"value\": string\n /**\n * Text read aloud to screen readers when the tab is focused\n */\n \"aria-label\"?: string\n /**\n * Text content to render in the tab\n */\n \"children\"?: React.ReactNode\n /**\n * Icon to render before the text content\n */\n \"icon\"?: React.ReactNode\n /**\n * Badge to render after the text content.\n * Can be a simple value or an object with content, color, variant, and loading options.\n * @example badge={5}\n * @example badge={{ content: 5, color: \"danger\" }}\n */\n \"badge\"?: TabsBadgeProp\n /**\n * Disable the individual tab\n */\n \"disabled\"?: boolean\n}\n\n// Type guard for badge object form\nconst isBadgeObject = (\n badge: TabsBadgeProp,\n): badge is Exclude<TabsBadgeProp, React.ReactNode> & { content: React.ReactNode } => {\n return badge != null && typeof badge === \"object\" && \"content\" in badge\n}\n\nconst Tab = ({ children, icon, badge, ...restProps }: TabProps) => {\n // Normalize badge prop\n const badgeProps = badge != null ? (isBadgeObject(badge) ? badge : { content: badge }) : null\n\n return (\n <ToggleGroup.Item\n className={s.Tab}\n {...restProps}\n onPointerEnter={handlePressableMouseEnter}\n >\n <span className={s.TabContent}>\n {icon}\n {children && <span>{children}</span>}\n {badgeProps && (\n <span\n className={s.TabBadge}\n data-color={badgeProps.color ?? \"secondary\"}\n data-variant={badgeProps.variant ?? \"soft\"}\n data-pill={badgeProps.pill ? \"\" : undefined}\n >\n {badgeProps.loading ? <LoadingIndicator /> : badgeProps.content}\n </span>\n )}\n </span>\n </ToggleGroup.Item>\n )\n}\n\n// =============================================\n// overflow=\"menu\"\n// =============================================\n\n/** Value of the menu button; no real tab has it */\nconst MORE_VALUE = \"__plexui_tabs_more__\"\n\ntype TabElement = ReactElement<TabProps>\n\n/** The tabs among the children, through fragments */\nconst tabElements = (children: ReactNode): TabElement[] =>\n Children.toArray(children).flatMap((child) => {\n if (!isValidElement<{ children?: ReactNode }>(child)) return []\n return child.type === Fragment ? tabElements(child.props.children) : [child as TabElement]\n })\n\nconst plainText = (node: unknown): string => {\n if (typeof node === \"string\" || typeof node === \"number\") return String(node)\n if (Array.isArray(node)) return node.map(plainText).join(\"\")\n if (isValidElement<{ children?: ReactNode }>(node)) return plainText(node.props.children)\n return \"\"\n}\n\nconst badgeText = (badge: TabsBadgeProp | undefined) =>\n badge != null && isBadgeObject(badge) ? plainText(badge.content) : plainText(badge)\n\n/** A tab's name: its text, else its accessible name, else its value */\nconst tabLabel = (item: TabElement) => plainText(item.props.children) || item.props[\"aria-label\"] || item.props.value\n\n/** What a tab's width depends on: the strip measures again when it changes */\nconst tabsSignature = (items: TabElement[]) =>\n items\n .map((item) =>\n [item.props.value, plainText(item.props.children), badgeText(item.props.badge), item.props.icon != null].join(\"\\u0000\"),\n )\n .join(\"\\u0001\")\n\n/**\n * `Menu.Trigger` sets `data-state` (open or closed) on its child, while a tab\n * keeps `on` or `off` in the same attribute and the thumb finds the active tab\n * by it. The menu's value does not reach the tab; its handlers and\n * `aria-haspopup` / `aria-expanded` do.\n */\nconst MoreTab = ({ \"data-state\": _menuState, ...restProps }: TabProps & { \"data-state\"?: string }) => (\n <Tab {...restProps} />\n)\n\nconst OverflowTabs = <T extends string>({\n children,\n value,\n onChange,\n overflowLabel,\n ...restProps\n}: Omit<TabsProps<T>, \"overflow\"> & { overflowLabel: string }) => {\n const items = tabElements(children)\n // The strip's own props size the tabs and the menu button too\n const { size, variant, gutterSize, pill, flush } = restProps\n const signature = [overflowLabel, size, variant, gutterSize, pill, flush, tabsSignature(items)].join(\"\\u0002\")\n const activeIndex = items.findIndex((item) => item.props.value === value)\n\n // null while the measuring pass renders every tab and the menu button\n const [visibleCount, setVisibleCount] = useState<number | null>(null)\n const [known, setKnown] = useState({ signature, activeIndex })\n const hostRef = useRef<HTMLDivElement>(null)\n const measuringRef = useRef(true)\n const boxWidthRef = useRef(-1)\n\n // New tabs measure again. A new active tab measures again when it moves\n // under the menu button or back out: the button carries the hidden one's name\n if (known.signature !== signature || known.activeIndex !== activeIndex) {\n const crossed =\n visibleCount !== null && (known.activeIndex >= visibleCount || activeIndex >= visibleCount)\n setKnown({ signature, activeIndex })\n if (visibleCount !== null && (known.signature !== signature || crossed)) setVisibleCount(null)\n }\n\n useLayoutEffect(() => {\n measuringRef.current = visibleCount === null\n }, [visibleCount])\n\n useLayoutEffect(() => {\n if (visibleCount !== null) return\n const root = hostRef.current?.firstElementChild\n if (!(root instanceof HTMLElement)) return\n\n // The measuring pass renders every tab, then the menu button\n const buttons = Array.from(root.querySelectorAll<HTMLElement>(\":scope > button\"))\n if (buttons.length !== items.length + 1) return\n\n const widths = buttons.map((button) => button.getBoundingClientRect().width)\n const moreButton = buttons[buttons.length - 1]\n const moreWidth = widths.pop() ?? 0\n const style = getComputedStyle(root)\n const available =\n root.getBoundingClientRect().width -\n (Number.parseFloat(style.paddingLeft) || 0) -\n (Number.parseFloat(style.paddingRight) || 0)\n const gap = Number.parseFloat(style.columnGap) || 0\n boxWidthRef.current = hostRef.current?.parentElement?.clientWidth ?? -1\n\n // A hidden strip has no width to decide by: show every tab, and measure\n // when it appears (the observer sees the width change)\n if (available <= 0) {\n setVisibleCount(items.length)\n return\n }\n\n // The button with the active tab's name: that tab's width plus the chevron\n const chevron = moreButton?.querySelector(\"svg\")\n const chevronWidth = chevron?.getBoundingClientRect().width ?? 0\n const labelGap = chevron?.parentElement ? Number.parseFloat(getComputedStyle(chevron.parentElement).columnGap) || 0 : 0\n const activeWidth = activeIndex < 0 ? 0 : (widths[activeIndex] ?? 0) + chevronWidth + labelGap\n\n setVisibleCount(visibleTabCount(widths, moreWidth, activeWidth, activeIndex, gap, available))\n }, [visibleCount, items.length, activeIndex])\n\n // The width to fit is the container's, not the strip's: the strip shrinks\n // to its content. Reports during a measuring pass are skipped, since the\n // full strip may be pushing its container wider\n useEffect(() => {\n const box = hostRef.current?.parentElement\n if (!box || typeof ResizeObserver === \"undefined\") return\n const observer = new ResizeObserver(() => {\n if (measuringRef.current) return\n const width = box.clientWidth\n if (width === boxWidthRef.current) return\n boxWidthRef.current = width\n setVisibleCount(null)\n })\n observer.observe(box)\n return () => observer.disconnect()\n }, [])\n\n const measuring = visibleCount === null\n const shown = measuring ? items : items.slice(0, visibleCount)\n const hidden = measuring ? [] : items.slice(visibleCount)\n const hiddenActive = hidden.find((item) => item.props.value === value) ?? null\n\n return (\n <div ref={hostRef} className={s.OverflowHost}>\n <Menu>\n <TabsRoot<string>\n {...restProps}\n data-overflow=\"menu\"\n value={hiddenActive ? MORE_VALUE : value}\n onChange={(next) => {\n // Pressing the menu button opens the menu; it is not a tab\n if (next !== MORE_VALUE) onChange?.(next as T)\n }}\n >\n {/* Keyed by value: tabs from different fragments may share a key */}\n {shown.map((item) => cloneElement(item, { key: item.props.value }))}\n {(measuring || hidden.length > 0) && (\n <Menu.Trigger>\n <MoreTab value={MORE_VALUE}>\n <span className={s.OverflowLabel}>\n {hiddenActive ? tabLabel(hiddenActive) : overflowLabel}\n <ChevronDownMd />\n </span>\n </MoreTab>\n </Menu.Trigger>\n )}\n </TabsRoot>\n <Menu.Content align=\"end\" minWidth=\"auto\">\n <Menu.RadioGroup<string> value={value} onChange={(next) => onChange?.(next as T)}>\n {hidden.map((item) => {\n const count = badgeText(item.props.badge)\n return (\n <Menu.RadioItem<string>\n key={item.props.value}\n value={item.props.value}\n disabled={restProps.disabled || item.props.disabled}\n >\n {item.props.icon}\n {item.props.children ?? item.props[\"aria-label\"] ?? item.props.value}\n {/* A tab's count moves into the menu with it */}\n {count !== \"\" && <span className={s.OverflowBadge}>{count}</span>}\n </Menu.RadioItem>\n )\n })}\n </Menu.RadioGroup>\n </Menu.Content>\n </Menu>\n </div>\n )\n}\n\n// Attach sub-components\nTabs.Tab = Tab\n// Backward-compat alias\nTabs.Option = Tab\n"]}
|
|
1
|
+
{"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../../../src/components/Tabs/Tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { ToggleGroup } from \"radix-ui\"\nimport {\n Children,\n cloneElement,\n Fragment,\n isValidElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n} from \"react\"\nimport { useResizeObserver } from \"usehooks-ts\"\nimport { handlePressableMouseEnter, waitForAnimationFrame } from \"../../lib/helpers\"\nimport { type ControlSize, type SemanticColors, type Sizes, type Variants } from \"../../types\"\nimport { ChevronDownMd } from \"../Icon\"\nimport { LoadingIndicator } from \"../Indicator\"\nimport { Menu } from \"../Menu\"\nimport { fitCount, visibleTabCount } from \"./overflow\"\nimport s from \"@plexui/styles/components/Tabs/Tabs.module.css\"\n\nexport type SizeVariant = \"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nexport type TabsVariant = \"segmented\" | \"underline\"\nexport type TabsOrientation = \"horizontal\" | \"vertical\"\n\nexport type TabsProps<T extends string> = {\n /**\n * Controlled value for the group\n */\n \"value\": T\n /** Callback for when a new value is selected */\n \"onChange\"?: (nextValue: T) => void\n /** Callback any time the control is clicked (even if a new value was not selected) */\n \"onClick\"?: () => void\n /**\n * Text read aloud to screen readers when the control is focused\n */\n \"aria-label\": string\n /**\n * Visual variant of the tab group\n * - `\"segmented\"` — background container with sliding highlight (default)\n * - `\"underline\"` — no background, animated line indicator under active tab\n * @default \"segmented\"\n */\n \"variant\"?: TabsVariant\n /**\n * Orientation of the tab layout\n * @default \"horizontal\"\n */\n \"orientation\"?: TabsOrientation\n /**\n * Controls the size of the tabs\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n *\n * @default md\n */\n \"size\"?: ControlSize\n /**\n * Controls gutter on the edges of the button, defaults to value from `size`.\n *\n * | 2xs | xs | sm | md | lg | xl |\n * | ------ | ------ | ------ | ------ | ------ | ------ |\n * | `6px` | `8px` | `10px` | `12px` | `14px` | `16px` |\n */\n \"gutterSize\"?: Sizes<\"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\">\n /** Disable the entire group */\n \"disabled\"?: boolean\n /**\n * Display the control as a block element with equal width segments\n * @default false\n */\n \"block\"?: boolean\n /**\n * Determines if the tabs should be a fully rounded pill shape.\n * Only applies to the `\"segmented\"` variant.\n * @default true\n */\n \"pill\"?: boolean\n /**\n * Flush underline style — removes tab padding so the indicator\n * matches the text width exactly, uses gap for spacing, and\n * removes the bottom border.\n * Only applies to the `\"underline\"` variant.\n * @default false\n */\n \"flush\"?: boolean\n /**\n * What happens to tabs that do not fit in one row: the strip scrolls\n * sideways (`scroll`), or the tabs that do not fit move into a menu at the\n * end of the strip (`menu`). The menu button shows the active tab's name\n * when it is one of the hidden ones. Horizontal tabs without `block` only.\n * @default \"scroll\"\n */\n \"overflow\"?: \"scroll\" | \"menu\"\n /**\n * Text of the menu button with `overflow=\"menu\"`\n * @default \"More\"\n */\n \"overflowLabel\"?: string\n \"className\"?: string\n \"children\": React.ReactNode\n}\n\nexport const Tabs = <T extends string>({ overflow = \"scroll\", overflowLabel = \"More\", ...props }: TabsProps<T>) => {\n if (overflow === \"menu\" && !props.block && props.orientation !== \"vertical\") {\n return <OverflowTabs {...props} overflowLabel={overflowLabel} />\n }\n return <TabsRoot {...props} />\n}\n\nconst TabsRoot = <T extends string>({\n value,\n onChange,\n children,\n variant = \"segmented\",\n orientation = \"horizontal\",\n block,\n pill = true,\n flush,\n size = \"md\",\n gutterSize,\n className,\n onClick,\n ...restProps\n}: Omit<TabsProps<T>, \"overflow\" | \"overflowLabel\">) => {\n const rootRef = useRef<HTMLDivElement>(null)\n const thumbRef = useRef<HTMLDivElement>(null)\n const prevSizeRef = useRef(size)\n const isVertical = orientation === \"vertical\"\n\n const applyThumbSizing = useCallback(\n (attemptScroll: boolean) => {\n const root = rootRef.current\n const thumb = thumbRef.current\n\n if (!root || !thumb) {\n return\n }\n\n // Get selected node\n const activeNode = root?.querySelector<HTMLDivElement>('[data-state=\"on\"]')\n\n // Impossible\n if (!activeNode) {\n return\n }\n\n if (isVertical) {\n const rootHeight = root.clientHeight\n let targetHeight = Math.floor(activeNode.clientHeight)\n const targetOffset = activeNode.offsetTop\n\n // Detect subpixel edge case\n if (rootHeight - (targetHeight + targetOffset) < 2) {\n targetHeight = targetHeight - 1\n }\n\n thumb.style.height = `${Math.floor(targetHeight)}px`\n thumb.style.width = \"\"\n thumb.style.transform = `translateY(${targetOffset}px)`\n\n // Scroll into view if needed\n if (root.scrollHeight > rootHeight) {\n const buffer = rootHeight * 0.15\n const scrollTop = root.scrollTop\n const top = activeNode.offsetTop\n const bottom = top + targetHeight\n if (top < scrollTop + buffer || bottom > scrollTop + rootHeight - buffer) {\n if (attemptScroll) {\n activeNode.scrollIntoView({ block: \"center\", inline: \"nearest\", behavior: \"smooth\" })\n }\n }\n }\n } else {\n const rootWidth = root.clientWidth\n let targetWidth = Math.floor(activeNode.clientWidth)\n const targetOffset = activeNode.offsetLeft\n\n // Detect if the thumb is moving too far to the edge of the container.\n // This would most commonly be due to subpixel widths adding up to excessive distance.\n if (rootWidth - (targetWidth + targetOffset) < 2) {\n targetWidth = targetWidth - 1\n }\n\n thumb.style.width = `${Math.floor(targetWidth)}px`\n thumb.style.height = \"\"\n thumb.style.transform = `translateX(${targetOffset}px)`\n\n // If the control is scrollable, ensure the active option is visible\n if (root.scrollWidth > rootWidth) {\n // Only scroll items near the edge, but not the inner 2/3.\n const buffer = rootWidth * 0.15\n const scrollLeft = root.scrollLeft\n const left = activeNode.offsetLeft\n const right = left + targetWidth\n if (left < scrollLeft + buffer || right > scrollLeft + rootWidth - buffer) {\n // Cheap trick to avoid unintentional scroll on mount - transition is set after mounting\n if (attemptScroll) {\n activeNode.scrollIntoView({ block: \"nearest\", inline: \"center\", behavior: \"smooth\" })\n }\n }\n }\n }\n },\n [isVertical],\n )\n\n useResizeObserver({\n // @ts-expect-error(2322) -- bug in types: https://github.com/juliencrn/usehooks-ts/issues/663\n ref: rootRef,\n onResize: () => {\n const thumb = thumbRef.current\n\n if (!thumb) {\n return\n }\n\n // Perform the size update instantly\n const currentTransition = thumb.style.transition\n thumb.style.transition = \"\"\n applyThumbSizing(false)\n thumb.style.transition = currentTransition\n },\n })\n\n // Tabs added, removed, reordered or relabelled move the active tab without\n // resizing the group: measure again, instantly, like a resize\n useEffect(() => {\n const root = rootRef.current\n if (!root || typeof MutationObserver === \"undefined\") return\n const observer = new MutationObserver(() => {\n const thumb = thumbRef.current\n if (!thumb) return\n const currentTransition = thumb.style.transition\n thumb.style.transition = \"\"\n applyThumbSizing(false)\n thumb.style.transition = currentTransition\n })\n observer.observe(root, { childList: true, characterData: true, subtree: true })\n return () => observer.disconnect()\n }, [applyThumbSizing])\n\n const transitionProperty = isVertical\n ? \"height 200ms var(--cubic-enter), transform 200ms var(--cubic-enter)\"\n : \"width 200ms var(--cubic-enter), transform 200ms var(--cubic-enter)\"\n\n useLayoutEffect(() => {\n const root = rootRef.current\n const thumb = thumbRef.current\n\n if (!root || !thumb) {\n return\n }\n\n const sizeChanged = prevSizeRef.current !== size\n prevSizeRef.current = size\n\n if (sizeChanged) {\n // Size changed - disable transition, wait for CSS, then apply sizing\n const currentTransition = thumb.style.transition\n thumb.style.transition = \"\"\n\n waitForAnimationFrame(() => {\n applyThumbSizing(false)\n waitForAnimationFrame(() => {\n thumb.style.transition = currentTransition\n })\n })\n } else if (thumb.style.transition) {\n // Normal update (value change, etc.): the thumb leaves with the label's colour\n applyThumbSizing(true)\n } else {\n // First measure: apply transition after initial calculation is set\n waitForAnimationFrame(() => {\n applyThumbSizing(false)\n waitForAnimationFrame(() => {\n thumb.style.transition = transitionProperty\n })\n })\n }\n }, [applyThumbSizing, value, size, gutterSize, pill, flush, transitionProperty])\n\n const handleValueChange = (nextValue: T) => {\n // Only trigger onChange when a value exists\n // Disallow toggling off enabled items\n if (nextValue && onChange) onChange(nextValue)\n }\n\n // Only apply pill for segmented variant\n const isPill = variant === \"segmented\" && pill\n // Only apply flush for underline variant\n const isFlush = variant === \"underline\" && flush\n\n return (\n <ToggleGroup.Root\n ref={rootRef}\n className={clsx(s.Tabs, className)}\n type=\"single\"\n value={value}\n loop={false}\n onValueChange={handleValueChange}\n onClick={onClick}\n data-variant={variant}\n data-orientation={orientation}\n data-block={block ? \"\" : undefined}\n data-pill={isPill ? \"\" : undefined}\n data-flush={isFlush ? \"\" : undefined}\n data-size={size}\n data-gutter-size={gutterSize}\n {...restProps}\n >\n <div className={s.TabsThumb} ref={thumbRef} />\n {children}\n </ToggleGroup.Root>\n )\n}\n\n/**\n * Badge configuration for Tabs.Tab\n */\nexport type TabsBadgeProp =\n | React.ReactNode\n | {\n content: React.ReactNode\n color?: SemanticColors<\n \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"discovery\" | \"caution\"\n >\n variant?: Variants<\"soft\" | \"solid\">\n pill?: boolean\n loading?: boolean\n }\n\nexport type TabProps = {\n /**\n * Tab value\n */\n \"value\": string\n /**\n * Text read aloud to screen readers when the tab is focused\n */\n \"aria-label\"?: string\n /**\n * Text content to render in the tab\n */\n \"children\"?: React.ReactNode\n /**\n * Icon to render before the text content\n */\n \"icon\"?: React.ReactNode\n /**\n * Badge to render after the text content.\n * Can be a simple value or an object with content, color, variant, and loading options.\n * @example badge={5}\n * @example badge={{ content: 5, color: \"danger\" }}\n */\n \"badge\"?: TabsBadgeProp\n /**\n * Disable the individual tab\n */\n \"disabled\"?: boolean\n}\n\n// Type guard for badge object form\nconst isBadgeObject = (\n badge: TabsBadgeProp,\n): badge is Exclude<TabsBadgeProp, React.ReactNode> & { content: React.ReactNode } => {\n return badge != null && typeof badge === \"object\" && \"content\" in badge\n}\n\nconst Tab = ({ children, icon, badge, ...restProps }: TabProps) => {\n // Normalize badge prop\n const badgeProps = badge != null ? (isBadgeObject(badge) ? badge : { content: badge }) : null\n\n return (\n <ToggleGroup.Item\n className={s.Tab}\n {...restProps}\n onPointerEnter={handlePressableMouseEnter}\n >\n <span className={s.TabContent}>\n {icon}\n {children && <span>{children}</span>}\n {badgeProps && (\n <span\n className={s.TabBadge}\n data-color={badgeProps.color ?? \"secondary\"}\n data-variant={badgeProps.variant ?? \"soft\"}\n data-pill={badgeProps.pill ? \"\" : undefined}\n >\n {badgeProps.loading ? <LoadingIndicator /> : badgeProps.content}\n </span>\n )}\n </span>\n </ToggleGroup.Item>\n )\n}\n\n// =============================================\n// overflow=\"menu\"\n// =============================================\n\n/** Value of the menu button; no real tab has it */\nconst MORE_VALUE = \"__plexui_tabs_more__\"\n\ntype TabElement = ReactElement<TabProps>\n\n/** The tabs among the children, through fragments */\nconst tabElements = (children: ReactNode): TabElement[] =>\n Children.toArray(children).flatMap((child) => {\n if (!isValidElement<{ children?: ReactNode }>(child)) return []\n return child.type === Fragment ? tabElements(child.props.children) : [child as TabElement]\n })\n\nconst plainText = (node: unknown): string => {\n if (typeof node === \"string\" || typeof node === \"number\") return String(node)\n if (Array.isArray(node)) return node.map(plainText).join(\"\")\n if (isValidElement<{ children?: ReactNode }>(node)) return plainText(node.props.children)\n return \"\"\n}\n\nconst badgeText = (badge: TabsBadgeProp | undefined) =>\n badge != null && isBadgeObject(badge) ? plainText(badge.content) : plainText(badge)\n\n/** A tab's name: its text, else its accessible name, else its value */\nconst tabLabel = (item: TabElement) => plainText(item.props.children) || item.props[\"aria-label\"] || item.props.value\n\n/** What a tab's width depends on: the strip measures again when it changes */\nconst tabsSignature = (items: TabElement[]) =>\n items\n .map((item) =>\n [item.props.value, plainText(item.props.children), badgeText(item.props.badge), item.props.icon != null].join(\"\\u0000\"),\n )\n .join(\"\\u0001\")\n\n/**\n * `Menu.Trigger` sets `data-state` (open or closed) on its child, while a tab\n * keeps `on` or `off` in the same attribute and the thumb finds the active tab\n * by it. The menu's value does not reach the tab; its handlers and\n * `aria-haspopup` / `aria-expanded` do.\n */\nconst MoreTab = ({ \"data-state\": _menuState, ...restProps }: TabProps & { \"data-state\"?: string }) => (\n <Tab {...restProps} />\n)\n\nconst OverflowTabs = <T extends string>({\n children,\n value,\n onChange,\n overflowLabel,\n ...restProps\n}: Omit<TabsProps<T>, \"overflow\"> & { overflowLabel: string }) => {\n const items = tabElements(children)\n // The strip's own props size the tabs and the menu button too\n const { size, variant, gutterSize, pill, flush } = restProps\n const signature = [overflowLabel, size, variant, gutterSize, pill, flush, tabsSignature(items)].join(\"\\u0002\")\n const activeIndex = items.findIndex((item) => item.props.value === value)\n\n // null while the measuring pass renders every tab and the menu button\n const [visibleCount, setVisibleCount] = useState<number | null>(null)\n const [known, setKnown] = useState({ signature, activeIndex })\n const hostRef = useRef<HTMLDivElement>(null)\n const measuringRef = useRef(true)\n const boxWidthRef = useRef(-1)\n\n // New tabs measure again. A new active tab measures again when it moves\n // under the menu button or back out: the button carries the hidden one's name\n if (known.signature !== signature || known.activeIndex !== activeIndex) {\n const crossed =\n visibleCount !== null && (known.activeIndex >= visibleCount || activeIndex >= visibleCount)\n setKnown({ signature, activeIndex })\n if (visibleCount !== null && (known.signature !== signature || crossed)) setVisibleCount(null)\n }\n\n useLayoutEffect(() => {\n measuringRef.current = visibleCount === null\n }, [visibleCount])\n\n useLayoutEffect(() => {\n if (visibleCount !== null) return\n const root = hostRef.current?.firstElementChild\n if (!(root instanceof HTMLElement)) return\n\n // The measuring pass renders every tab, then the menu button\n const buttons = Array.from(root.querySelectorAll<HTMLElement>(\":scope > button\"))\n if (buttons.length !== items.length + 1) return\n\n const widths = buttons.map((button) => button.getBoundingClientRect().width)\n const moreButton = buttons[buttons.length - 1]\n const moreWidth = widths.pop() ?? 0\n const style = getComputedStyle(root)\n const available =\n root.getBoundingClientRect().width -\n (Number.parseFloat(style.paddingLeft) || 0) -\n (Number.parseFloat(style.paddingRight) || 0)\n const gap = Number.parseFloat(style.columnGap) || 0\n boxWidthRef.current = hostRef.current?.parentElement?.clientWidth ?? -1\n\n // A hidden strip has no width to decide by: show every tab, and measure\n // when it appears (the observer sees the width change)\n if (available <= 0) {\n setVisibleCount(items.length)\n return\n }\n\n // The button with the active tab's name: that tab's width plus the chevron\n const chevron = moreButton?.querySelector(\"svg\")\n const chevronWidth = chevron?.getBoundingClientRect().width ?? 0\n const labelGap = chevron?.parentElement ? Number.parseFloat(getComputedStyle(chevron.parentElement).columnGap) || 0 : 0\n const activeWidth = activeIndex < 0 ? 0 : (widths[activeIndex] ?? 0) + chevronWidth + labelGap\n\n setVisibleCount(visibleTabCount(widths, moreWidth, activeWidth, activeIndex, gap, available))\n }, [visibleCount, items.length, activeIndex])\n\n // The width to fit is the container's, not the strip's: the strip shrinks\n // to its content. Reports during a measuring pass are skipped, since the\n // full strip may be pushing its container wider\n useEffect(() => {\n const box = hostRef.current?.parentElement\n if (!box || typeof ResizeObserver === \"undefined\") return\n const observer = new ResizeObserver(() => {\n if (measuringRef.current) return\n const width = box.clientWidth\n if (width === boxWidthRef.current) return\n boxWidthRef.current = width\n setVisibleCount(null)\n })\n observer.observe(box)\n return () => observer.disconnect()\n }, [])\n\n const measuring = visibleCount === null\n const shown = measuring ? items : items.slice(0, visibleCount)\n const hidden = measuring ? [] : items.slice(visibleCount)\n const hiddenActive = hidden.find((item) => item.props.value === value) ?? null\n\n return (\n <div ref={hostRef} className={s.OverflowHost}>\n <Menu>\n <TabsRoot<string>\n {...restProps}\n data-overflow=\"menu\"\n value={hiddenActive ? MORE_VALUE : value}\n onChange={(next) => {\n // Pressing the menu button opens the menu; it is not a tab\n if (next !== MORE_VALUE) onChange?.(next as T)\n }}\n >\n {/* Keyed by value: tabs from different fragments may share a key */}\n {shown.map((item) => cloneElement(item, { key: item.props.value }))}\n {(measuring || hidden.length > 0) && (\n <Menu.Trigger>\n <MoreTab value={MORE_VALUE}>\n <span className={s.OverflowLabel}>\n {hiddenActive ? tabLabel(hiddenActive) : overflowLabel}\n <ChevronDownMd />\n </span>\n </MoreTab>\n </Menu.Trigger>\n )}\n </TabsRoot>\n <Menu.Content align=\"end\" minWidth=\"auto\">\n <Menu.RadioGroup<string> value={value} onChange={(next) => onChange?.(next as T)}>\n {hidden.map((item) => {\n const count = badgeText(item.props.badge)\n return (\n <Menu.RadioItem<string>\n key={item.props.value}\n value={item.props.value}\n disabled={restProps.disabled || item.props.disabled}\n >\n {item.props.icon}\n {item.props.children ?? item.props[\"aria-label\"] ?? item.props.value}\n {/* A tab's count moves into the menu with it */}\n {count !== \"\" && <span className={s.OverflowBadge}>{count}</span>}\n </Menu.RadioItem>\n )\n })}\n </Menu.RadioGroup>\n </Menu.Content>\n </Menu>\n </div>\n )\n}\n\n// Attach sub-components\nTabs.Tab = Tab\n// Backward-compat alias\nTabs.Option = Tab\n"]}
|
|
@@ -72,6 +72,17 @@ export type FloatingLabelInputProps = {
|
|
|
72
72
|
* @default 2
|
|
73
73
|
*/
|
|
74
74
|
rows?: number;
|
|
75
|
+
/**
|
|
76
|
+
* Where the label rests once it floats: on the border, or inside the box
|
|
77
|
+
* with the value under it. `inside` always takes the rounded box.
|
|
78
|
+
* @default "border"
|
|
79
|
+
*/
|
|
80
|
+
labelPlacement?: "border" | "inside";
|
|
81
|
+
/**
|
|
82
|
+
* Pill shape. `false` takes the rounded box of the other fields.
|
|
83
|
+
* @default true
|
|
84
|
+
*/
|
|
85
|
+
pill?: boolean;
|
|
75
86
|
} & React.InputHTMLAttributes<HTMLInputElement>;
|
|
76
87
|
export declare const FloatingLabelInput: import("react").ForwardRefExoticComponent<{
|
|
77
88
|
/**
|
|
@@ -147,4 +158,15 @@ export declare const FloatingLabelInput: import("react").ForwardRefExoticCompone
|
|
|
147
158
|
* @default 2
|
|
148
159
|
*/
|
|
149
160
|
rows?: number;
|
|
161
|
+
/**
|
|
162
|
+
* Where the label rests once it floats: on the border, or inside the box
|
|
163
|
+
* with the value under it. `inside` always takes the rounded box.
|
|
164
|
+
* @default "border"
|
|
165
|
+
*/
|
|
166
|
+
labelPlacement?: "border" | "inside";
|
|
167
|
+
/**
|
|
168
|
+
* Pill shape. `false` takes the rounded box of the other fields.
|
|
169
|
+
* @default true
|
|
170
|
+
*/
|
|
171
|
+
pill?: boolean;
|
|
150
172
|
} & import("react").InputHTMLAttributes<HTMLInputElement> & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -7,6 +7,17 @@ export type FloatingLabelSelectProps = {
|
|
|
7
7
|
open?: boolean;
|
|
8
8
|
onInteract?: () => void;
|
|
9
9
|
onClearClick?: () => void;
|
|
10
|
+
/**
|
|
11
|
+
* Where the label rests once it floats: on the border, or inside the box
|
|
12
|
+
* with the value under it. `inside` always takes the rounded box.
|
|
13
|
+
* @default "border"
|
|
14
|
+
*/
|
|
15
|
+
labelPlacement?: "border" | "inside";
|
|
16
|
+
/**
|
|
17
|
+
* Pill shape. `false` takes the rounded box of the other fields.
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
pill?: boolean;
|
|
10
21
|
children?: React.ReactNode;
|
|
11
22
|
className?: string;
|
|
12
23
|
"aria-describedby"?: string;
|
|
@@ -20,6 +31,17 @@ export declare const FloatingLabelSelect: import("react").ForwardRefExoticCompon
|
|
|
20
31
|
open?: boolean;
|
|
21
32
|
onInteract?: () => void;
|
|
22
33
|
onClearClick?: () => void;
|
|
34
|
+
/**
|
|
35
|
+
* Where the label rests once it floats: on the border, or inside the box
|
|
36
|
+
* with the value under it. `inside` always takes the rounded box.
|
|
37
|
+
* @default "border"
|
|
38
|
+
*/
|
|
39
|
+
labelPlacement?: "border" | "inside";
|
|
40
|
+
/**
|
|
41
|
+
* Pill shape. `false` takes the rounded box of the other fields.
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
pill?: boolean;
|
|
23
45
|
children?: React.ReactNode;
|
|
24
46
|
className?: string;
|
|
25
47
|
"aria-describedby"?: string;
|