@pk-design/react-tailwind 1.7.2 → 1.8.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.
Files changed (61) hide show
  1. package/dist/cjs/components/Button/Button.js +46 -28
  2. package/dist/cjs/components/Button/Button.js.map +1 -1
  3. package/dist/cjs/components/Checkbox/Checkbox.js +10 -4
  4. package/dist/cjs/components/Checkbox/Checkbox.js.map +1 -1
  5. package/dist/cjs/components/CheckboxGroup/CheckboxGroup.js +19 -13
  6. package/dist/cjs/components/CheckboxGroup/CheckboxGroup.js.map +1 -1
  7. package/dist/cjs/components/DataList/DataList.js +2 -2
  8. package/dist/cjs/components/DataList/DataList.js.map +1 -1
  9. package/dist/cjs/components/DataTable/DataTable.js +72 -40
  10. package/dist/cjs/components/DataTable/DataTable.js.map +1 -1
  11. package/dist/cjs/components/DataTable/DataTable.utils.js +2 -1
  12. package/dist/cjs/components/DataTable/DataTable.utils.js.map +1 -1
  13. package/dist/cjs/components/Input/Input.js +11 -8
  14. package/dist/cjs/components/Input/Input.js.map +1 -1
  15. package/dist/cjs/components/Pagination/Pagination.js +27 -15
  16. package/dist/cjs/components/Pagination/Pagination.js.map +1 -1
  17. package/dist/cjs/components/Radio/Radio.js +9 -5
  18. package/dist/cjs/components/Radio/Radio.js.map +1 -1
  19. package/dist/cjs/components/RadioGroup/RadioGroup.js +13 -6
  20. package/dist/cjs/components/RadioGroup/RadioGroup.js.map +1 -1
  21. package/dist/cjs/components/SelectBox/SelectBox.js +24 -25
  22. package/dist/cjs/components/SelectBox/SelectBox.js.map +1 -1
  23. package/dist/cjs/components/Textarea/Textarea.js +8 -5
  24. package/dist/cjs/components/Textarea/Textarea.js.map +1 -1
  25. package/dist/es/components/Button/Button.js +46 -28
  26. package/dist/es/components/Button/Button.js.map +1 -1
  27. package/dist/es/components/Checkbox/Checkbox.js +10 -4
  28. package/dist/es/components/Checkbox/Checkbox.js.map +1 -1
  29. package/dist/es/components/CheckboxGroup/CheckboxGroup.js +20 -14
  30. package/dist/es/components/CheckboxGroup/CheckboxGroup.js.map +1 -1
  31. package/dist/es/components/DataList/DataList.js +2 -2
  32. package/dist/es/components/DataList/DataList.js.map +1 -1
  33. package/dist/es/components/DataTable/DataTable.js +74 -42
  34. package/dist/es/components/DataTable/DataTable.js.map +1 -1
  35. package/dist/es/components/DataTable/DataTable.utils.js +2 -1
  36. package/dist/es/components/DataTable/DataTable.utils.js.map +1 -1
  37. package/dist/es/components/Input/Input.js +12 -9
  38. package/dist/es/components/Input/Input.js.map +1 -1
  39. package/dist/es/components/Pagination/Pagination.js +27 -15
  40. package/dist/es/components/Pagination/Pagination.js.map +1 -1
  41. package/dist/es/components/Radio/Radio.js +9 -5
  42. package/dist/es/components/Radio/Radio.js.map +1 -1
  43. package/dist/es/components/RadioGroup/RadioGroup.js +14 -7
  44. package/dist/es/components/RadioGroup/RadioGroup.js.map +1 -1
  45. package/dist/es/components/SelectBox/SelectBox.js +24 -25
  46. package/dist/es/components/SelectBox/SelectBox.js.map +1 -1
  47. package/dist/es/components/Textarea/Textarea.js +9 -6
  48. package/dist/es/components/Textarea/Textarea.js.map +1 -1
  49. package/dist/react-tailwind.cjs.js +269 -180
  50. package/dist/react-tailwind.cjs.js.map +1 -1
  51. package/dist/react-tailwind.es.js +269 -180
  52. package/dist/react-tailwind.es.js.map +1 -1
  53. package/dist/types/components/Button/Button.types.d.ts +5 -0
  54. package/dist/types/components/CheckboxGroup/CheckboxGroup.types.d.ts +9 -1
  55. package/dist/types/components/DataList/DataList.d.ts +1 -1
  56. package/dist/types/components/DataList/DataList.types.d.ts +8 -0
  57. package/dist/types/components/DataTable/DataTable.d.ts +1 -1
  58. package/dist/types/components/DataTable/DataTable.types.d.ts +46 -0
  59. package/dist/types/components/Pagination/Pagination.types.d.ts +21 -24
  60. package/dist/types/components/RadioGroup/RadioGroup.types.d.ts +8 -0
  61. package/package.json +1 -1
@@ -37,20 +37,20 @@ function buildInputClass(className, { isFocusWithin = false, disabled = false, h
37
37
  : 'focus:outline-[var(--ui-focus-ring)] focus:outline-2 focus:-outline-offset-2', className);
38
38
  }
39
39
  const Input = React.forwardRef((props, ref) => {
40
- const { name, id = name, type, label, labelHint, className, labelClass, labelWrapperClass, containerClass, error, showErrorMessage = true, rightGroup, leftGroup, prefix, suffix, clearable = false, onClear, showCount = false, helperText, size = 'md', value, defaultValue, onChange, maxLength, ...inputProps } = props;
40
+ const { name, id = name, type, label, labelHint, className, labelClass, labelWrapperClass, containerClass, error, showErrorMessage = true, rightGroup, leftGroup, prefix, suffix, clearable = false, onClear, showCount = false, helperText, size = 'md', value, defaultValue, onChange, maxLength, required, 'aria-describedby': ariaDescribedBy, ...inputProps } = props;
41
41
  const innerRef = React.useRef(null);
42
42
  React.useImperativeHandle(ref, () => innerRef.current);
43
43
  const [uncontrolledValue, setUncontrolledValue] = React.useState(String(defaultValue !== null && defaultValue !== void 0 ? defaultValue : ''));
44
44
  const isControlled = value !== undefined;
45
45
  const currentVal = isControlled ? String(value !== null && value !== void 0 ? value : '') : uncontrolledValue;
46
46
  const charLength = currentVal.length;
47
- const handleInputChange = (e) => {
47
+ const handleInputChange = React.useCallback((e) => {
48
48
  if (!isControlled) {
49
49
  setUncontrolledValue(e.target.value);
50
50
  }
51
51
  onChange === null || onChange === void 0 ? void 0 : onChange(e);
52
- };
53
- const handleClear = () => {
52
+ }, [isControlled, onChange]);
53
+ const handleClear = React.useCallback(() => {
54
54
  if (innerRef.current) {
55
55
  innerRef.current.value = '';
56
56
  const event = new Event('input', {
@@ -63,18 +63,21 @@ const Input = React.forwardRef((props, ref) => {
63
63
  onChange === null || onChange === void 0 ? void 0 : onChange(event);
64
64
  }
65
65
  onClear === null || onClear === void 0 ? void 0 : onClear();
66
- };
66
+ }, [isControlled, onChange, onClear]);
67
67
  const hasError = Boolean(error);
68
68
  const currentSize = sizeClasses[size] || sizeClasses.md;
69
+ const errorId = id && hasError && showErrorMessage ? `${id}-error` : undefined;
70
+ const helperId = id && helperText && !hasError ? `${id}-helper` : undefined;
71
+ const describedBy = [ariaDescribedBy, errorId, helperId].filter(Boolean).join(' ') || undefined;
69
72
  const showClearButton = clearable && charLength > 0 && !inputProps.disabled;
70
- const actualRightGroup = rightGroup !== null && rightGroup !== void 0 ? rightGroup : (showClearButton ? (jsxRuntime.jsx("button", { type: "button", onClick: handleClear, className: "p-1 rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors cursor-pointer", title: "Clear text", tabIndex: -1, children: jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: currentSize.icon, children: jsxRuntime.jsx("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" }) }) })) : null);
73
+ const actualRightGroup = rightGroup !== null && rightGroup !== void 0 ? rightGroup : (showClearButton ? (jsxRuntime.jsx("button", { type: "button", onClick: handleClear, className: "p-1 rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors cursor-pointer", "aria-label": "Clear input text", title: "Clear text", tabIndex: -1, children: jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: currentSize.icon, children: jsxRuntime.jsx("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" }) }) })) : null);
71
74
  const hasRightGroup = actualRightGroup !== null && actualRightGroup !== undefined;
72
75
  const hasLeftGroup = leftGroup != null && leftGroup !== undefined;
73
- return (jsxRuntime.jsxs("div", { className: buildClassname.buildClassName('group', hasError && 'has-error', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassname.buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass), children: [jsxRuntime.jsx(Label.Label, { className: labelClass, htmlFor: id, children: label }), labelHint && jsxRuntime.jsx(TextContent.TextContent, { xsmall: true, children: labelHint })] })), jsxRuntime.jsxs("div", { className: "flex rounded-lg shadow-2xs", children: [prefix && (jsxRuntime.jsx("span", { className: "inline-flex items-center px-3 rounded-l-lg border border-r-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0", children: prefix })), jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0", children: [hasLeftGroup && (jsxRuntime.jsx("span", { className: buildClassname.buildClassName('absolute top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: leftGroup })), jsxRuntime.jsx("input", { ref: innerRef, autoComplete: "off", ...inputProps, value: value, defaultValue: defaultValue, onChange: handleInputChange, maxLength: maxLength, name: name, id: id, type: type, className: buildClassname.buildClassName(buildInputClass(className, {
76
+ return (jsxRuntime.jsxs("div", { className: buildClassname.buildClassName('group', hasError && 'has-error', containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassname.buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass), children: [jsxRuntime.jsx(Label.Label, { className: labelClass, htmlFor: id, "aria-required": required, children: label }), labelHint && jsxRuntime.jsx(TextContent.TextContent, { xsmall: true, children: labelHint })] })), jsxRuntime.jsxs("div", { className: "flex rounded-lg shadow-2xs", children: [prefix && (jsxRuntime.jsx("span", { className: "inline-flex items-center px-3 rounded-l-lg border border-r-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0", children: prefix })), jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0", children: [hasLeftGroup && (jsxRuntime.jsx("span", { className: buildClassname.buildClassName('absolute top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: leftGroup })), jsxRuntime.jsx("input", { ref: innerRef, autoComplete: "off", ...inputProps, value: value, defaultValue: defaultValue, onChange: handleInputChange, maxLength: maxLength, name: name, id: id, type: type, required: required, "aria-invalid": hasError ? true : undefined, "aria-describedby": describedBy, className: buildClassname.buildClassName(buildInputClass(className, {
74
77
  disabled: inputProps.disabled,
75
78
  hasError,
76
79
  size,
77
- }), prefix ? '!rounded-l-none' : '', suffix ? '!rounded-r-none' : '', hasRightGroup ? (size === 'lg' ? 'pe-12' : size === 'sm' ? 'pe-8' : 'pe-10') : '', hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : '') }), hasRightGroup && (jsxRuntime.jsx("span", { className: buildClassname.buildClassName('absolute end-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: actualRightGroup }))] }), suffix && (jsxRuntime.jsx("span", { className: "inline-flex items-center px-3 rounded-r-lg border border-l-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0", children: suffix }))] }), (showErrorMessage && error) || helperText || showCount ? (jsxRuntime.jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsxRuntime.jsx(TextContent.TextContent, { error: true, small: true, children: error })) : helperText ? (jsxRuntime.jsx(TextContent.TextContent, { muted: true, small: true, children: helperText })) : null }), showCount && (jsxRuntime.jsxs("span", { className: buildClassname.buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
80
+ }), prefix ? '!rounded-l-none' : '', suffix ? '!rounded-r-none' : '', hasRightGroup ? (size === 'lg' ? 'pe-12' : size === 'sm' ? 'pe-8' : 'pe-10') : '', hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : '') }), hasRightGroup && (jsxRuntime.jsx("span", { className: buildClassname.buildClassName('absolute end-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500', currentSize.group), children: actualRightGroup }))] }), suffix && (jsxRuntime.jsx("span", { className: "inline-flex items-center px-3 rounded-r-lg border border-l-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0", children: suffix }))] }), (showErrorMessage && error) || helperText || showCount ? (jsxRuntime.jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2 text-xs", children: [jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: showErrorMessage && error ? (jsxRuntime.jsx(TextContent.TextContent, { error: true, small: true, id: errorId, children: error })) : helperText ? (jsxRuntime.jsx(TextContent.TextContent, { muted: true, small: true, id: helperId, children: helperText })) : null }), showCount && (jsxRuntime.jsxs("span", { className: buildClassname.buildClassName('text-[11px] font-medium shrink-0 ml-auto', maxLength && charLength >= maxLength
78
81
  ? 'text-red-500 font-semibold'
79
82
  : 'text-gray-400 dark:text-gray-500'), children: [charLength, maxLength ? ` / ${maxLength}` : ''] }))] })) : null] }));
80
83
  });
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../../../../../src/components/Input/Input.tsx"],"sourcesContent":["import { forwardRef, useImperativeHandle, useRef, useState, type ChangeEvent } from 'react'\nimport { Label } from '../Label'\nimport { buildClassName } from '../../utils/build-classname'\nimport type { InputProps, InputSize } from './Input.types'\nimport { TextContent } from '../TextContent'\n\nconst sizeClasses: Record<InputSize, { input: string; group: string; icon: string; text: string }> =\n {\n sm: {\n input: 'px-2.5 py-1.5 text-xs leading-5',\n group: 'w-8 text-xs',\n icon: 'size-3.5',\n text: 'text-xs',\n },\n md: {\n input: 'px-3.5 py-2 text-sm leading-6',\n group: 'w-10 text-sm',\n icon: 'size-4',\n text: 'text-sm',\n },\n lg: {\n input: 'px-4 py-2.5 text-base leading-7',\n group: 'w-12 text-base',\n icon: 'size-5',\n text: 'text-base',\n },\n }\n\nexport function buildInputClass(\n className?: string,\n {\n isFocusWithin = false,\n disabled = false,\n hasError = false,\n size = 'md',\n }: { isFocusWithin?: boolean; disabled?: boolean; hasError?: boolean; size?: InputSize } = {},\n) {\n const currentSize = sizeClasses[size] || sizeClasses.md\n\n return buildClassName(\n 'transition-all duration-150',\n 'block w-full rounded-lg bg-white',\n currentSize.input,\n 'text-gray-900 outline outline-1 -outline-offset-1',\n hasError\n ? '!outline-red-500 !ring-1 !ring-red-500/50 dark:!outline-red-500'\n : 'outline-[var(--ui-border)]',\n disabled\n ? 'pointer-events-none bg-gray-100 dark:bg-gray-800 dark:text-gray-600 dark:placeholder-gray-600 placeholder-gray-400 outline-[var(--ui-border-muted)]'\n : 'bg-white dark:bg-gray-700 dark:text-white outline-[var(--ui-border)] dark:placeholder-gray-400 placeholder-gray-400',\n isFocusWithin\n ? 'focus-within:outline-[var(--ui-focus-ring)] focus-within:outline-2 focus-within:-outline-offset-2'\n : 'focus:outline-[var(--ui-focus-ring)] focus:outline-2 focus:-outline-offset-2',\n className,\n )\n}\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {\n const {\n name,\n id = name,\n type,\n label,\n labelHint,\n className,\n labelClass,\n labelWrapperClass,\n containerClass,\n error,\n showErrorMessage = true,\n rightGroup,\n leftGroup,\n prefix,\n suffix,\n clearable = false,\n onClear,\n showCount = false,\n helperText,\n size = 'md',\n value,\n defaultValue,\n onChange,\n maxLength,\n ...inputProps\n } = props\n\n const innerRef = useRef<HTMLInputElement>(null)\n useImperativeHandle(ref, () => innerRef.current as HTMLInputElement)\n\n const [uncontrolledValue, setUncontrolledValue] = useState<string>(String(defaultValue ?? ''))\n\n const isControlled = value !== undefined\n const currentVal = isControlled ? String(value ?? '') : uncontrolledValue\n const charLength = currentVal.length\n\n const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setUncontrolledValue(e.target.value)\n }\n onChange?.(e)\n }\n\n const handleClear = () => {\n if (innerRef.current) {\n innerRef.current.value = ''\n const event = new Event('input', {\n bubbles: true,\n }) as unknown as ChangeEvent<HTMLInputElement>\n Object.defineProperty(event, 'target', { writable: true, value: { value: '' } })\n if (!isControlled) {\n setUncontrolledValue('')\n }\n onChange?.(event)\n }\n onClear?.()\n }\n\n const hasError = Boolean(error)\n const currentSize = sizeClasses[size] || sizeClasses.md\n\n const showClearButton = clearable && charLength > 0 && !inputProps.disabled\n\n const actualRightGroup =\n rightGroup ??\n (showClearButton ? (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"p-1 rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors cursor-pointer\"\n title=\"Clear text\"\n tabIndex={-1}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n className={currentSize.icon}\n >\n <path d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n ) : null)\n\n const hasRightGroup = actualRightGroup !== null && actualRightGroup !== undefined\n const hasLeftGroup = leftGroup != null && leftGroup !== undefined\n\n return (\n <div className={buildClassName('group', hasError && 'has-error', containerClass)}>\n {label && (\n <div\n className={buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass)}\n >\n <Label className={labelClass} htmlFor={id}>\n {label}\n </Label>\n {labelHint && <TextContent xsmall>{labelHint}</TextContent>}\n </div>\n )}\n\n <div className=\"flex rounded-lg shadow-2xs\">\n {/* Static Prefix Addon */}\n {prefix && (\n <span className=\"inline-flex items-center px-3 rounded-l-lg border border-r-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0\">\n {prefix}\n </span>\n )}\n\n <div className=\"relative flex-1 min-w-0\">\n {hasLeftGroup && (\n <span\n className={buildClassName(\n 'absolute top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500',\n currentSize.group,\n )}\n >\n {leftGroup}\n </span>\n )}\n\n <input\n ref={innerRef}\n autoComplete=\"off\"\n {...inputProps}\n value={value}\n defaultValue={defaultValue}\n onChange={handleInputChange}\n maxLength={maxLength}\n name={name}\n id={id}\n type={type}\n className={buildClassName(\n buildInputClass(className, {\n disabled: inputProps.disabled,\n hasError,\n size,\n }),\n prefix ? '!rounded-l-none' : '',\n suffix ? '!rounded-r-none' : '',\n hasRightGroup ? (size === 'lg' ? 'pe-12' : size === 'sm' ? 'pe-8' : 'pe-10') : '',\n hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : '',\n )}\n />\n\n {hasRightGroup && (\n <span\n className={buildClassName(\n 'absolute end-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500',\n currentSize.group,\n )}\n >\n {actualRightGroup}\n </span>\n )}\n </div>\n\n {/* Static Suffix Addon */}\n {suffix && (\n <span className=\"inline-flex items-center px-3 rounded-r-lg border border-l-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0\">\n {suffix}\n </span>\n )}\n </div>\n\n {/* Footer Row: Error / Helper Text & Live Character Count */}\n {(showErrorMessage && error) || helperText || showCount ? (\n <div className=\"mt-1.5 flex items-center justify-between gap-2 text-xs\">\n <div className=\"min-w-0 flex-1\">\n {showErrorMessage && error ? (\n <TextContent error small>\n {error}\n </TextContent>\n ) : helperText ? (\n <TextContent muted small>\n {helperText}\n </TextContent>\n ) : null}\n </div>\n\n {showCount && (\n <span\n className={buildClassName(\n 'text-[11px] font-medium shrink-0 ml-auto',\n maxLength && charLength >= maxLength\n ? 'text-red-500 font-semibold'\n : 'text-gray-400 dark:text-gray-500',\n )}\n >\n {charLength}\n {maxLength ? ` / ${maxLength}` : ''}\n </span>\n )}\n </div>\n ) : null}\n </div>\n )\n})\n\nInput.displayName = 'Input'\n"],"names":["buildClassName","forwardRef","useRef","useImperativeHandle","useState","_jsx","_jsxs","Label","TextContent"],"mappings":";;;;;;;;AAMA,MAAM,WAAW,GACf;AACE,IAAA,EAAE,EAAE;AACF,QAAA,KAAK,EAAE,iCAAiC;AACxC,QAAA,KAAK,EAAE,aAAa;AACpB,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,IAAI,EAAE,SAAS;AAChB,KAAA;AACD,IAAA,EAAE,EAAE;AACF,QAAA,KAAK,EAAE,+BAA+B;AACtC,QAAA,KAAK,EAAE,cAAc;AACrB,QAAA,IAAI,EAAE,QAAQ;AACd,QAAA,IAAI,EAAE,SAAS;AAChB,KAAA;AACD,IAAA,EAAE,EAAE;AACF,QAAA,KAAK,EAAE,iCAAiC;AACxC,QAAA,KAAK,EAAE,gBAAgB;AACvB,QAAA,IAAI,EAAE,QAAQ;AACd,QAAA,IAAI,EAAE,WAAW;AAClB,KAAA;CACF;AAEG,SAAU,eAAe,CAC7B,SAAkB,EAClB,EACE,aAAa,GAAG,KAAK,EACrB,QAAQ,GAAG,KAAK,EAChB,QAAQ,GAAG,KAAK,EAChB,IAAI,GAAG,IAAI,GAAA,GAC8E,EAAE,EAAA;IAE7F,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,EAAE;AAEvD,IAAA,OAAOA,6BAAc,CACnB,6BAA6B,EAC7B,kCAAkC,EAClC,WAAW,CAAC,KAAK,EACjB,mDAAmD,EACnD;AACE,UAAE;UACA,4BAA4B,EAChC;AACE,UAAE;UACA,qHAAqH,EACzH;AACE,UAAE;AACF,UAAE,8EAA8E,EAClF,SAAS,CACV;AACH;AAEO,MAAM,KAAK,GAAGC,gBAAU,CAA+B,CAAC,KAAK,EAAE,GAAG,KAAI;AAC3E,IAAA,MAAM,EACJ,IAAI,EACJ,EAAE,GAAG,IAAI,EACT,IAAI,EACJ,KAAK,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,KAAK,EACL,gBAAgB,GAAG,IAAI,EACvB,UAAU,EACV,SAAS,EACT,MAAM,EACN,MAAM,EACN,SAAS,GAAG,KAAK,EACjB,OAAO,EACP,SAAS,GAAG,KAAK,EACjB,UAAU,EACV,IAAI,GAAG,IAAI,EACX,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,GAAG,UAAU,EACd,GAAG,KAAK;AAET,IAAA,MAAM,QAAQ,GAAGC,YAAM,CAAmB,IAAI,CAAC;IAC/CC,yBAAmB,CAAC,GAAG,EAAE,MAAM,QAAQ,CAAC,OAA2B,CAAC;AAEpE,IAAA,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAGC,cAAQ,CAAS,MAAM,CAAC,YAAY,KAAA,IAAA,IAAZ,YAAY,KAAA,MAAA,GAAZ,YAAY,GAAI,EAAE,CAAC,CAAC;AAE9F,IAAA,MAAM,YAAY,GAAG,KAAK,KAAK,SAAS;IACxC,MAAM,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC,KAAK,KAAA,IAAA,IAAL,KAAK,KAAA,MAAA,GAAL,KAAK,GAAI,EAAE,CAAC,GAAG,iBAAiB;AACzE,IAAA,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM;AAEpC,IAAA,MAAM,iBAAiB,GAAG,CAAC,CAAgC,KAAI;QAC7D,IAAI,CAAC,YAAY,EAAE;AACjB,YAAA,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QACtC;AACA,QAAA,QAAQ,aAAR,QAAQ,KAAA,MAAA,GAAA,MAAA,GAAR,QAAQ,CAAG,CAAC,CAAC;AACf,IAAA,CAAC;IAED,MAAM,WAAW,GAAG,MAAK;AACvB,QAAA,IAAI,QAAQ,CAAC,OAAO,EAAE;AACpB,YAAA,QAAQ,CAAC,OAAO,CAAC,KAAK,GAAG,EAAE;AAC3B,YAAA,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE;AAC/B,gBAAA,OAAO,EAAE,IAAI;AACd,aAAA,CAA6C;YAC9C,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC;YAChF,IAAI,CAAC,YAAY,EAAE;gBACjB,oBAAoB,CAAC,EAAE,CAAC;YAC1B;AACA,YAAA,QAAQ,aAAR,QAAQ,KAAA,MAAA,GAAA,MAAA,GAAR,QAAQ,CAAG,KAAK,CAAC;QACnB;AACA,QAAA,OAAO,KAAA,IAAA,IAAP,OAAO,KAAA,MAAA,GAAA,MAAA,GAAP,OAAO,EAAI;AACb,IAAA,CAAC;AAED,IAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;IAC/B,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,EAAE;AAEvD,IAAA,MAAM,eAAe,GAAG,SAAS,IAAI,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ;AAE3E,IAAA,MAAM,gBAAgB,GACpB,UAAU,KAAA,IAAA,IAAV,UAAU,KAAA,MAAA,GAAV,UAAU,IACT,eAAe,IACdC,cAAA,CAAA,QAAA,EAAA,EACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,WAAW,EACpB,SAAS,EAAC,uJAAuJ,EACjK,KAAK,EAAC,YAAY,EAClB,QAAQ,EAAE,EAAE,EAAA,QAAA,EAEZA,cAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,4BAA4B,EAClC,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,cAAc,EACnB,SAAS,EAAE,WAAW,CAAC,IAAI,EAAA,QAAA,EAE3BA,cAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,8KAA8K,EAAA,CAAG,EAAA,CACrL,EAAA,CACC,IACP,IAAI,CAAC;IAEX,MAAM,aAAa,GAAG,gBAAgB,KAAK,IAAI,IAAI,gBAAgB,KAAK,SAAS;IACjF,MAAM,YAAY,GAAG,SAAS,IAAI,IAAI,IAAI,SAAS,KAAK,SAAS;AAEjE,IAAA,QACEC,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAEN,6BAAc,CAAC,OAAO,EAAE,QAAQ,IAAI,WAAW,EAAE,cAAc,CAAC,EAAA,QAAA,EAAA,CAC7E,KAAK,KACJM,eAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAEN,6BAAc,CAAC,0CAA0C,EAAE,iBAAiB,CAAC,EAAA,QAAA,EAAA,CAExFK,cAAA,CAACE,WAAK,EAAA,EAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAA,QAAA,EACtC,KAAK,GACA,EACP,SAAS,IAAIF,cAAA,CAACG,uBAAW,EAAA,EAAC,MAAM,EAAA,IAAA,EAAA,QAAA,EAAE,SAAS,EAAA,CAAe,CAAA,EAAA,CACvD,CACP,EAEDF,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,4BAA4B,aAExC,MAAM,KACLD,cAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,kLAAkL,EAAA,QAAA,EAC/L,MAAM,EAAA,CACF,CACR,EAEDC,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,yBAAyB,EAAA,QAAA,EAAA,CACrC,YAAY,KACXD,cAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAEL,6BAAc,CACvB,yFAAyF,EACzF,WAAW,CAAC,KAAK,CAClB,EAAA,QAAA,EAEA,SAAS,EAAA,CACL,CACR,EAEDK,cAAA,CAAA,OAAA,EAAA,EACE,GAAG,EAAE,QAAQ,EACb,YAAY,EAAC,KAAK,KACd,UAAU,EACd,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,IAAI,EACV,SAAS,EAAEL,6BAAc,CACvB,eAAe,CAAC,SAAS,EAAE;oCACzB,QAAQ,EAAE,UAAU,CAAC,QAAQ;oCAC7B,QAAQ;oCACR,IAAI;iCACL,CAAC,EACF,MAAM,GAAG,iBAAiB,GAAG,EAAE,EAC/B,MAAM,GAAG,iBAAiB,GAAG,EAAE,EAC/B,aAAa,IAAI,IAAI,KAAK,IAAI,GAAG,OAAO,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,GAAG,OAAO,IAAI,EAAE,EACjF,YAAY,IAAI,IAAI,KAAK,IAAI,GAAG,OAAO,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,GAAG,OAAO,IAAI,EAAE,CACjF,EAAA,CACD,EAED,aAAa,KACZK,cAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAEL,6BAAc,CACvB,+FAA+F,EAC/F,WAAW,CAAC,KAAK,CAClB,EAAA,QAAA,EAEA,gBAAgB,EAAA,CACZ,CACR,IACG,EAGL,MAAM,KACLK,cAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,kLAAkL,YAC/L,MAAM,EAAA,CACF,CACR,CAAA,EAAA,CACG,EAGL,CAAC,gBAAgB,IAAI,KAAK,KAAK,UAAU,IAAI,SAAS,IACrDC,yBAAK,SAAS,EAAC,wDAAwD,EAAA,QAAA,EAAA,CACrED,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,gBAAgB,YAC5B,gBAAgB,IAAI,KAAK,IACxBA,cAAA,CAACG,uBAAW,IAAC,KAAK,EAAA,IAAA,EAAC,KAAK,EAAA,IAAA,EAAA,QAAA,EACrB,KAAK,GACM,IACZ,UAAU,IACZH,cAAA,CAACG,uBAAW,EAAA,EAAC,KAAK,EAAA,IAAA,EAAC,KAAK,kBACrB,UAAU,EAAA,CACC,IACZ,IAAI,EAAA,CACJ,EAEL,SAAS,KACRF,0BACE,SAAS,EAAEN,6BAAc,CACvB,0CAA0C,EAC1C,SAAS,IAAI,UAAU,IAAI;AACzB,8BAAE;8BACA,kCAAkC,CACvC,EAAA,QAAA,EAAA,CAEA,UAAU,EACV,SAAS,GAAG,CAAA,GAAA,EAAM,SAAS,CAAA,CAAE,GAAG,EAAE,CAAA,EAAA,CAC9B,CACR,CAAA,EAAA,CACG,IACJ,IAAI,CAAA,EAAA,CACJ;AAEV,CAAC;AAED,KAAK,CAAC,WAAW,GAAG,OAAO;;;;;"}
1
+ {"version":3,"file":"Input.js","sources":["../../../../../src/components/Input/Input.tsx"],"sourcesContent":["import {\n useCallback,\n forwardRef,\n useImperativeHandle,\n useRef,\n useState,\n type ChangeEvent,\n} from 'react'\nimport { Label } from '../Label'\nimport { buildClassName } from '../../utils/build-classname'\nimport type { InputProps, InputSize } from './Input.types'\nimport { TextContent } from '../TextContent'\n\nconst sizeClasses: Record<InputSize, { input: string; group: string; icon: string; text: string }> =\n {\n sm: {\n input: 'px-2.5 py-1.5 text-xs leading-5',\n group: 'w-8 text-xs',\n icon: 'size-3.5',\n text: 'text-xs',\n },\n md: {\n input: 'px-3.5 py-2 text-sm leading-6',\n group: 'w-10 text-sm',\n icon: 'size-4',\n text: 'text-sm',\n },\n lg: {\n input: 'px-4 py-2.5 text-base leading-7',\n group: 'w-12 text-base',\n icon: 'size-5',\n text: 'text-base',\n },\n }\n\nexport function buildInputClass(\n className?: string,\n {\n isFocusWithin = false,\n disabled = false,\n hasError = false,\n size = 'md',\n }: { isFocusWithin?: boolean; disabled?: boolean; hasError?: boolean; size?: InputSize } = {},\n) {\n const currentSize = sizeClasses[size] || sizeClasses.md\n\n return buildClassName(\n 'transition-all duration-150',\n 'block w-full rounded-lg bg-white',\n currentSize.input,\n 'text-gray-900 outline outline-1 -outline-offset-1',\n hasError\n ? '!outline-red-500 !ring-1 !ring-red-500/50 dark:!outline-red-500'\n : 'outline-[var(--ui-border)]',\n disabled\n ? 'pointer-events-none bg-gray-100 dark:bg-gray-800 dark:text-gray-600 dark:placeholder-gray-600 placeholder-gray-400 outline-[var(--ui-border-muted)]'\n : 'bg-white dark:bg-gray-700 dark:text-white outline-[var(--ui-border)] dark:placeholder-gray-400 placeholder-gray-400',\n isFocusWithin\n ? 'focus-within:outline-[var(--ui-focus-ring)] focus-within:outline-2 focus-within:-outline-offset-2'\n : 'focus:outline-[var(--ui-focus-ring)] focus:outline-2 focus:-outline-offset-2',\n className,\n )\n}\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {\n const {\n name,\n id = name,\n type,\n label,\n labelHint,\n className,\n labelClass,\n labelWrapperClass,\n containerClass,\n error,\n showErrorMessage = true,\n rightGroup,\n leftGroup,\n prefix,\n suffix,\n clearable = false,\n onClear,\n showCount = false,\n helperText,\n size = 'md',\n value,\n defaultValue,\n onChange,\n maxLength,\n required,\n 'aria-describedby': ariaDescribedBy,\n ...inputProps\n } = props\n\n const innerRef = useRef<HTMLInputElement>(null)\n useImperativeHandle(ref, () => innerRef.current as HTMLInputElement)\n\n const [uncontrolledValue, setUncontrolledValue] = useState<string>(String(defaultValue ?? ''))\n\n const isControlled = value !== undefined\n const currentVal = isControlled ? String(value ?? '') : uncontrolledValue\n const charLength = currentVal.length\n\n const handleInputChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setUncontrolledValue(e.target.value)\n }\n onChange?.(e)\n },\n [isControlled, onChange],\n )\n\n const handleClear = useCallback(() => {\n if (innerRef.current) {\n innerRef.current.value = ''\n const event = new Event('input', {\n bubbles: true,\n }) as unknown as ChangeEvent<HTMLInputElement>\n Object.defineProperty(event, 'target', { writable: true, value: { value: '' } })\n if (!isControlled) {\n setUncontrolledValue('')\n }\n onChange?.(event)\n }\n onClear?.()\n }, [isControlled, onChange, onClear])\n\n const hasError = Boolean(error)\n const currentSize = sizeClasses[size] || sizeClasses.md\n\n const errorId = id && hasError && showErrorMessage ? `${id}-error` : undefined\n const helperId = id && helperText && !hasError ? `${id}-helper` : undefined\n const describedBy = [ariaDescribedBy, errorId, helperId].filter(Boolean).join(' ') || undefined\n\n const showClearButton = clearable && charLength > 0 && !inputProps.disabled\n\n const actualRightGroup =\n rightGroup ??\n (showClearButton ? (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"p-1 rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors cursor-pointer\"\n aria-label=\"Clear input text\"\n title=\"Clear text\"\n tabIndex={-1}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n className={currentSize.icon}\n >\n <path d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\" />\n </svg>\n </button>\n ) : null)\n\n const hasRightGroup = actualRightGroup !== null && actualRightGroup !== undefined\n const hasLeftGroup = leftGroup != null && leftGroup !== undefined\n\n return (\n <div className={buildClassName('group', hasError && 'has-error', containerClass)}>\n {label && (\n <div\n className={buildClassName('flex items-center justify-between mb-1.5', labelWrapperClass)}\n >\n <Label className={labelClass} htmlFor={id} aria-required={required}>\n {label}\n </Label>\n {labelHint && <TextContent xsmall>{labelHint}</TextContent>}\n </div>\n )}\n\n <div className=\"flex rounded-lg shadow-2xs\">\n {/* Static Prefix Addon */}\n {prefix && (\n <span className=\"inline-flex items-center px-3 rounded-l-lg border border-r-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0\">\n {prefix}\n </span>\n )}\n\n <div className=\"relative flex-1 min-w-0\">\n {hasLeftGroup && (\n <span\n className={buildClassName(\n 'absolute top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500',\n currentSize.group,\n )}\n >\n {leftGroup}\n </span>\n )}\n\n <input\n ref={innerRef}\n autoComplete=\"off\"\n {...inputProps}\n value={value}\n defaultValue={defaultValue}\n onChange={handleInputChange}\n maxLength={maxLength}\n name={name}\n id={id}\n type={type}\n required={required}\n aria-invalid={hasError ? true : undefined}\n aria-describedby={describedBy}\n className={buildClassName(\n buildInputClass(className, {\n disabled: inputProps.disabled,\n hasError,\n size,\n }),\n prefix ? '!rounded-l-none' : '',\n suffix ? '!rounded-r-none' : '',\n hasRightGroup ? (size === 'lg' ? 'pe-12' : size === 'sm' ? 'pe-8' : 'pe-10') : '',\n hasLeftGroup ? (size === 'lg' ? 'ps-12' : size === 'sm' ? 'ps-8' : 'ps-10') : '',\n )}\n />\n\n {hasRightGroup && (\n <span\n className={buildClassName(\n 'absolute end-0 top-0 h-full flex items-center justify-center text-gray-400 dark:text-gray-500',\n currentSize.group,\n )}\n >\n {actualRightGroup}\n </span>\n )}\n </div>\n\n {/* Static Suffix Addon */}\n {suffix && (\n <span className=\"inline-flex items-center px-3 rounded-r-lg border border-l-0 border-[var(--ui-border)] bg-gray-50 dark:bg-gray-800 text-gray-500 dark:text-gray-400 text-xs font-medium shrink-0\">\n {suffix}\n </span>\n )}\n </div>\n\n {/* Footer Row: Error / Helper Text & Live Character Count */}\n {(showErrorMessage && error) || helperText || showCount ? (\n <div className=\"mt-1.5 flex items-center justify-between gap-2 text-xs\">\n <div className=\"min-w-0 flex-1\">\n {showErrorMessage && error ? (\n <TextContent error small id={errorId}>\n {error}\n </TextContent>\n ) : helperText ? (\n <TextContent muted small id={helperId}>\n {helperText}\n </TextContent>\n ) : null}\n </div>\n\n {showCount && (\n <span\n className={buildClassName(\n 'text-[11px] font-medium shrink-0 ml-auto',\n maxLength && charLength >= maxLength\n ? 'text-red-500 font-semibold'\n : 'text-gray-400 dark:text-gray-500',\n )}\n >\n {charLength}\n {maxLength ? ` / ${maxLength}` : ''}\n </span>\n )}\n </div>\n ) : null}\n </div>\n )\n})\n\nInput.displayName = 'Input'\n"],"names":["buildClassName","forwardRef","useRef","useImperativeHandle","useState","useCallback","_jsx","_jsxs","Label","TextContent"],"mappings":"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"}
@@ -7,27 +7,39 @@ var buildClassname = require('../../utils/build-classname.js');
7
7
  var ChevronLeft = require('../Icons/ChevronLeft.svg.js');
8
8
  var ChevronRight = require('../Icons/ChevronRight.svg.js');
9
9
 
10
- const Pagination = ({ page: currentPage, limit, total, onChange, className, ellipsis = true, // Default to showing ellipsis
11
- }) => {
12
- const pages = new Array(Math.ceil(total / limit)).fill(null).map((_, i) => i + 1);
13
- const isFirstPage = currentPage === 1;
14
- const isLastPage = total === 0 || pages.length === currentPage;
15
- const range = usePagination.usePagination({ totalPages: pages.length, currentPage });
10
+ const Pagination = (props) => {
11
+ var _a, _b, _c, _d, _e, _f;
12
+ const { className, ellipsis = true, onChange, isMobile, showSummary = true, showPageNumbers = true, } = props;
13
+ const currentPage = (_c = (_b = (_a = props.page) !== null && _a !== void 0 ? _a : props.current) !== null && _b !== void 0 ? _b : props.currentPage) !== null && _c !== void 0 ? _c : 1;
14
+ const limit = (_e = (_d = props.limit) !== null && _d !== void 0 ? _d : props.pageSize) !== null && _e !== void 0 ? _e : 10;
15
+ const total = (_f = props.total) !== null && _f !== void 0 ? _f : 0;
16
+ const totalPages = Math.max(1, Math.ceil(total / limit));
17
+ const isFirstPage = currentPage <= 1;
18
+ const isLastPage = total === 0 || currentPage >= totalPages;
19
+ const range = usePagination.usePagination({ totalPages, currentPage });
16
20
  const handlePageChange = (nextVal) => {
17
- if (nextVal === currentPage)
21
+ if (nextVal === currentPage || nextVal < 1 || nextVal > totalPages)
18
22
  return;
19
23
  onChange({ page: nextVal });
20
24
  };
21
- if (ellipsis) {
22
- return (jsxRuntime.jsxs("div", { "data-testid": "pagination-container", className: buildClassname.buildClassName('flex items-center justify-between bg-white dark:bg-gray-800 px-4 py-3 sm:px-6', className), children: [jsxRuntime.jsxs("div", { className: "flex flex-1 justify-between sm:hidden", children: [jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isFirstPage, onClick: () => handlePageChange(currentPage - 1), "data-testid": "ellipsis-mobile-prev-btn", children: [jsxRuntime.jsx("span", { children: "Previous" }), jsxRuntime.jsx(ChevronLeft.default, { className: "size-4" })] }), jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isLastPage, onClick: () => handlePageChange(currentPage + 1), "data-testid": "ellipsis-mobile-next-btn", children: [jsxRuntime.jsx("span", { children: "Next" }), jsxRuntime.jsx(ChevronRight.default, { className: "size-4" })] })] }), jsxRuntime.jsxs("div", { className: "hidden sm:flex sm:flex-1 sm:items-center sm:justify-between", children: [jsxRuntime.jsxs("p", { "data-testid": "pagination-summary", className: "text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1", children: ["Showing", jsxRuntime.jsx("span", { className: "font-medium", children: total === 0 ? 0 : Math.max(currentPage * limit - limit + 1, 1) }), "to", jsxRuntime.jsx("span", { className: "font-medium", children: Math.min(currentPage * limit, total) }), "of", jsxRuntime.jsx("span", { className: "font-medium", children: total }), "results"] }), jsxRuntime.jsxs("ul", { className: "flex items-center space-x-2 text-sm", children: [jsxRuntime.jsx("li", { children: jsxRuntime.jsx(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isFirstPage, onClick: () => handlePageChange(currentPage - 1), "data-testid": "ellipsis-prev-btn", children: "Prev" }) }), range.map((page, idx) => {
23
- if (page === usePagination.DOTS) {
24
- return (jsxRuntime.jsx("li", { "data-testid": `page-${page}`, className: "px-2 py-1 text-gray-400", children: "\u2026" }, `${page}-${idx}`));
25
- }
26
- return (jsxRuntime.jsx("li", { children: jsxRuntime.jsx(Button.Button, { size: "xs", theme: page === currentPage ? 'primary' : 'secondary', variant: page === currentPage ? 'default' : 'plain', "aria-current": page === currentPage ? 'page' : undefined, onClick: () => handlePageChange(page), children: page }) }, `${page}-${idx}`));
27
- }), jsxRuntime.jsx("li", { children: jsxRuntime.jsx(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isLastPage, onClick: () => handlePageChange(currentPage + 1), "data-testid": "ellipsis-next-btn", children: "Next" }) })] })] })] }));
25
+ const startResult = total === 0 ? 0 : Math.max((currentPage - 1) * limit + 1, 1);
26
+ const endResult = Math.min(currentPage * limit, total);
27
+ // Explicit Mobile UX (when isMobile=true)
28
+ if (isMobile) {
29
+ return (jsxRuntime.jsxs("div", { "data-testid": "pagination-container", className: buildClassname.buildClassName('flex items-center justify-between bg-white dark:bg-gray-800 px-4 py-3 sm:px-6 rounded-xl border border-[var(--ui-border-muted)] w-full', className), children: [jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isFirstPage, onClick: () => handlePageChange(currentPage - 1), "data-testid": ellipsis ? 'ellipsis-mobile-prev-btn' : 'mobile-prev-btn', className: "flex items-center gap-1 font-medium", children: [jsxRuntime.jsx(ChevronLeft.default, { className: "size-4" }), jsxRuntime.jsx("span", { children: "Previous" })] }), jsxRuntime.jsxs("span", { className: "text-xs font-semibold text-gray-700 dark:text-gray-300", children: ["Page ", currentPage, " of ", totalPages] }), jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isLastPage, onClick: () => handlePageChange(currentPage + 1), "data-testid": ellipsis ? 'ellipsis-mobile-next-btn' : 'mobile-next-btn', className: "flex items-center gap-1 font-medium", children: [jsxRuntime.jsx("span", { children: "Next" }), jsxRuntime.jsx(ChevronRight.default, { className: "size-4" })] })] }));
28
30
  }
29
- return (jsxRuntime.jsxs("div", { "data-testid": "pagination-container", className: buildClassname.buildClassName('flex items-center justify-between bg-white dark:bg-gray-800 px-4 py-3 sm:px-6', className), children: [jsxRuntime.jsxs("div", { className: "flex flex-1 justify-between sm:hidden", children: [jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isFirstPage, onClick: () => handlePageChange(currentPage - 1), "data-testid": "mobile-prev-btn", children: [jsxRuntime.jsx("span", { children: "Previous" }), jsxRuntime.jsx(ChevronLeft.default, { className: "size-4" })] }), jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isLastPage, onClick: () => handlePageChange(currentPage + 1), "data-testid": "mobile-next-btn", children: [jsxRuntime.jsx("span", { children: "Next" }), jsxRuntime.jsx(ChevronRight.default, { className: "size-4" })] })] }), jsxRuntime.jsxs("div", { className: "hidden sm:flex sm:flex-1 sm:items-center sm:justify-between", children: [jsxRuntime.jsxs("p", { "data-testid": "pagination-summary", className: "text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1", children: ["Showing", jsxRuntime.jsx("span", { className: "font-medium", children: total === 0 ? 0 : Math.max(currentPage * limit - limit + 1, 1) }), "to", jsxRuntime.jsx("span", { className: "font-medium", children: Math.min(currentPage * limit, total) }), "of", jsxRuntime.jsx("span", { className: "font-medium", children: total }), "results"] }), jsxRuntime.jsxs("nav", { className: "isolate inline-flex items-center rounded-md", "aria-label": "Pagination", children: [jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isFirstPage, onClick: () => handlePageChange(currentPage - 1), "data-testid": "prev-btn", children: [jsxRuntime.jsx("span", { className: "sr-only", children: "Previous" }), jsxRuntime.jsx(ChevronLeft.default, { className: "size-4" })] }), pages.map((page) => (jsxRuntime.jsx(Button.Button, { size: "xs", theme: page === currentPage ? 'primary' : 'secondary', variant: page === currentPage ? 'default' : 'plain', "aria-current": page === currentPage ? 'page' : undefined, onClick: () => handlePageChange(page), children: jsxRuntime.jsx("span", { className: "size-4 block", children: page }) }, page))), jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isLastPage, onClick: () => handlePageChange(currentPage + 1), "data-testid": "next-btn", children: [jsxRuntime.jsx("span", { className: "sr-only", children: "Next" }), jsxRuntime.jsx(ChevronRight.default, { className: "size-4" })] })] })] })] }));
31
+ // Standard Responsive View
32
+ return (jsxRuntime.jsxs("div", { "data-testid": "pagination-container", className: buildClassname.buildClassName('flex items-center justify-between bg-white dark:bg-gray-800 px-4 py-3 sm:px-6 rounded-xl border border-[var(--ui-border-muted)] w-full', className), children: [jsxRuntime.jsxs("div", { className: "flex flex-1 items-center justify-between sm:hidden", children: [jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isFirstPage, onClick: () => handlePageChange(currentPage - 1), "data-testid": ellipsis ? 'ellipsis-mobile-prev-btn' : 'mobile-prev-btn', className: "flex items-center gap-1", children: [jsxRuntime.jsx(ChevronLeft.default, { className: "size-4" }), jsxRuntime.jsx("span", { children: "Previous" })] }), jsxRuntime.jsxs("span", { className: "text-xs font-semibold text-gray-700 dark:text-gray-300", children: ["Page ", currentPage, " of ", totalPages] }), jsxRuntime.jsxs(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isLastPage, onClick: () => handlePageChange(currentPage + 1), "data-testid": ellipsis ? 'ellipsis-mobile-next-btn' : 'mobile-next-btn', className: "flex items-center gap-1", children: [jsxRuntime.jsx("span", { children: "Next" }), jsxRuntime.jsx(ChevronRight.default, { className: "size-4" })] })] }), jsxRuntime.jsxs("div", { className: "hidden sm:flex sm:flex-1 sm:items-center sm:justify-between", children: [showSummary && (jsxRuntime.jsxs("p", { "data-testid": "pagination-summary", className: "text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1", children: ["Showing", jsxRuntime.jsx("span", { className: "font-medium", children: startResult }), "to", jsxRuntime.jsx("span", { className: "font-medium", children: endResult }), "of", jsxRuntime.jsx("span", { className: "font-medium", children: total }), "results"] })), showPageNumbers && (jsxRuntime.jsxs("ul", { className: "flex items-center space-x-2 text-sm", children: [jsxRuntime.jsx("li", { children: jsxRuntime.jsx(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isFirstPage, onClick: () => handlePageChange(currentPage - 1), "data-testid": ellipsis ? 'ellipsis-prev-btn' : 'prev-btn', children: ellipsis ? 'Prev' : 'Previous' }) }), ellipsis
33
+ ? range.map((pageItem, idx) => {
34
+ if (pageItem === usePagination.DOTS) {
35
+ return (jsxRuntime.jsx("li", { "data-testid": `page-${pageItem}`, className: "px-2 py-1 text-gray-400", children: "\u2026" }, `${pageItem}-${idx}`));
36
+ }
37
+ const pageNum = Number(pageItem);
38
+ return (jsxRuntime.jsx("li", { children: jsxRuntime.jsx(Button.Button, { size: "xs", theme: pageNum === currentPage ? 'primary' : 'secondary', variant: pageNum === currentPage ? 'default' : 'plain', "aria-current": pageNum === currentPage ? 'page' : undefined, onClick: () => handlePageChange(pageNum), children: pageNum }) }, `${pageItem}-${idx}`));
39
+ })
40
+ : Array.from({ length: totalPages }, (_, i) => i + 1).map((pageNum) => (jsxRuntime.jsx("li", { children: jsxRuntime.jsx(Button.Button, { size: "xs", theme: pageNum === currentPage ? 'primary' : 'secondary', variant: pageNum === currentPage ? 'default' : 'plain', "aria-current": pageNum === currentPage ? 'page' : undefined, onClick: () => handlePageChange(pageNum), children: jsxRuntime.jsx("span", { className: "size-4 block", children: pageNum }) }) }, pageNum))), jsxRuntime.jsx("li", { children: jsxRuntime.jsx(Button.Button, { size: "xs", theme: "secondary", variant: "plain", disabled: isLastPage, onClick: () => handlePageChange(currentPage + 1), "data-testid": ellipsis ? 'ellipsis-next-btn' : 'next-btn', children: ellipsis ? 'Next' : 'Next' }) })] }))] })] }));
30
41
  };
42
+ Pagination.displayName = 'Pagination';
31
43
 
32
44
  exports.Pagination = Pagination;
33
45
  //# sourceMappingURL=Pagination.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.js","sources":["../../../../../src/components/Pagination/Pagination.tsx"],"sourcesContent":["import React from 'react'\nimport { Button } from '../Button'\nimport { usePagination, DOTS } from './usePagination'\nimport { buildClassName } from '../../utils/build-classname'\nimport ChevronLeftIcon from '../Icons/ChevronLeft.svg'\nimport ChevronRightIcon from '../Icons/ChevronRight.svg'\nimport type { PaginationProps } from './Pagination.types'\n\nexport const Pagination: React.FC<PaginationProps> = ({\n page: currentPage,\n limit,\n total,\n onChange,\n className,\n ellipsis = true, // Default to showing ellipsis\n}) => {\n const pages = new Array(Math.ceil(total / limit)).fill(null).map((_, i) => i + 1)\n const isFirstPage = currentPage === 1\n const isLastPage = total === 0 || pages.length === currentPage\n\n const range = usePagination({ totalPages: pages.length, currentPage })\n\n const handlePageChange = (nextVal: number) => {\n if (nextVal === currentPage) return\n\n onChange({ page: nextVal })\n }\n\n if (ellipsis) {\n return (\n <div\n data-testid=\"pagination-container\"\n className={buildClassName(\n 'flex items-center justify-between bg-white dark:bg-gray-800 px-4 py-3 sm:px-6',\n className,\n )}\n >\n <div className=\"flex flex-1 justify-between sm:hidden\">\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isFirstPage}\n onClick={() => handlePageChange(currentPage - 1)}\n data-testid=\"ellipsis-mobile-prev-btn\"\n >\n <span>Previous</span>\n <ChevronLeftIcon className=\"size-4\" />\n </Button>\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isLastPage}\n onClick={() => handlePageChange(currentPage + 1)}\n data-testid=\"ellipsis-mobile-next-btn\"\n >\n <span>Next</span>\n <ChevronRightIcon className=\"size-4\" />\n </Button>\n </div>\n <div className=\"hidden sm:flex sm:flex-1 sm:items-center sm:justify-between\">\n <p\n data-testid=\"pagination-summary\"\n className=\"text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1\"\n >\n Showing\n <span className=\"font-medium\">\n {total === 0 ? 0 : Math.max(currentPage * limit - limit + 1, 1)}\n </span>\n to\n <span className=\"font-medium\">{Math.min(currentPage * limit, total)}</span>\n of\n <span className=\"font-medium\">{total}</span>\n results\n </p>\n <ul className=\"flex items-center space-x-2 text-sm\">\n <li>\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isFirstPage}\n onClick={() => handlePageChange(currentPage - 1)}\n data-testid=\"ellipsis-prev-btn\"\n >\n Prev\n </Button>\n </li>\n {range.map((page, idx) => {\n if (page === DOTS) {\n return (\n <li\n key={`${page}-${idx}`}\n data-testid={`page-${page}`}\n className=\"px-2 py-1 text-gray-400\"\n >\n &hellip;\n </li>\n )\n }\n return (\n <li key={`${page}-${idx}`}>\n <Button\n size=\"xs\"\n theme={page === currentPage ? 'primary' : 'secondary'}\n variant={page === currentPage ? 'default' : 'plain'}\n aria-current={page === currentPage ? 'page' : undefined}\n onClick={() => handlePageChange(page as number)}\n >\n {page}\n </Button>\n </li>\n )\n })}\n <li>\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isLastPage}\n onClick={() => handlePageChange(currentPage + 1)}\n data-testid=\"ellipsis-next-btn\"\n >\n Next\n </Button>\n </li>\n </ul>\n </div>\n </div>\n )\n }\n\n return (\n <div\n data-testid=\"pagination-container\"\n className={buildClassName(\n 'flex items-center justify-between bg-white dark:bg-gray-800 px-4 py-3 sm:px-6',\n className,\n )}\n >\n <div className=\"flex flex-1 justify-between sm:hidden\">\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isFirstPage}\n onClick={() => handlePageChange(currentPage - 1)}\n data-testid=\"mobile-prev-btn\"\n >\n <span>Previous</span>\n <ChevronLeftIcon className=\"size-4\" />\n </Button>\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isLastPage}\n onClick={() => handlePageChange(currentPage + 1)}\n data-testid=\"mobile-next-btn\"\n >\n <span>Next</span>\n <ChevronRightIcon className=\"size-4\" />\n </Button>\n </div>\n <div className=\"hidden sm:flex sm:flex-1 sm:items-center sm:justify-between\">\n <p\n data-testid=\"pagination-summary\"\n className=\"text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1\"\n >\n Showing\n <span className=\"font-medium\">\n {total === 0 ? 0 : Math.max(currentPage * limit - limit + 1, 1)}\n </span>\n to\n <span className=\"font-medium\">{Math.min(currentPage * limit, total)}</span>\n of\n <span className=\"font-medium\">{total}</span>\n results\n </p>\n <nav className=\"isolate inline-flex items-center rounded-md\" aria-label=\"Pagination\">\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isFirstPage}\n onClick={() => handlePageChange(currentPage - 1)}\n data-testid=\"prev-btn\"\n >\n <span className=\"sr-only\">Previous</span>\n <ChevronLeftIcon className=\"size-4\" />\n </Button>\n {pages.map((page) => (\n <Button\n key={page}\n size=\"xs\"\n theme={page === currentPage ? 'primary' : 'secondary'}\n variant={page === currentPage ? 'default' : 'plain'}\n aria-current={page === currentPage ? 'page' : undefined}\n onClick={() => handlePageChange(page)}\n >\n <span className=\"size-4 block\">{page}</span>\n </Button>\n ))}\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isLastPage}\n onClick={() => handlePageChange(currentPage + 1)}\n data-testid=\"next-btn\"\n >\n <span className=\"sr-only\">Next</span>\n <ChevronRightIcon className=\"size-4\" />\n </Button>\n </nav>\n </div>\n </div>\n )\n}\n"],"names":["usePagination","_jsxs","buildClassName","Button","_jsx","ChevronLeftIcon","ChevronRightIcon","DOTS"],"mappings":"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"}
1
+ {"version":3,"file":"Pagination.js","sources":["../../../../../src/components/Pagination/Pagination.tsx"],"sourcesContent":["import React from 'react'\nimport { Button } from '../Button'\nimport { usePagination, DOTS } from './usePagination'\nimport { buildClassName } from '../../utils/build-classname'\nimport ChevronLeftIcon from '../Icons/ChevronLeft.svg'\nimport ChevronRightIcon from '../Icons/ChevronRight.svg'\nimport type { PaginationProps } from './Pagination.types'\n\nexport const Pagination: React.FC<PaginationProps> = (props) => {\n const {\n className,\n ellipsis = true,\n onChange,\n isMobile,\n showSummary = true,\n showPageNumbers = true,\n } = props\n\n const currentPage =\n (props as any).page ?? (props as any).current ?? (props as any).currentPage ?? 1\n const limit = (props as any).limit ?? (props as any).pageSize ?? 10\n const total = props.total ?? 0\n\n const totalPages = Math.max(1, Math.ceil(total / limit))\n const isFirstPage = currentPage <= 1\n const isLastPage = total === 0 || currentPage >= totalPages\n\n const range = usePagination({ totalPages, currentPage })\n\n const handlePageChange = (nextVal: number) => {\n if (nextVal === currentPage || nextVal < 1 || nextVal > totalPages) return\n\n onChange({ page: nextVal })\n }\n\n const startResult = total === 0 ? 0 : Math.max((currentPage - 1) * limit + 1, 1)\n const endResult = Math.min(currentPage * limit, total)\n\n // Explicit Mobile UX (when isMobile=true)\n if (isMobile) {\n return (\n <div\n data-testid=\"pagination-container\"\n className={buildClassName(\n 'flex items-center justify-between bg-white dark:bg-gray-800 px-4 py-3 sm:px-6 rounded-xl border border-[var(--ui-border-muted)] w-full',\n className,\n )}\n >\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isFirstPage}\n onClick={() => handlePageChange(currentPage - 1)}\n data-testid={ellipsis ? 'ellipsis-mobile-prev-btn' : 'mobile-prev-btn'}\n className=\"flex items-center gap-1 font-medium\"\n >\n <ChevronLeftIcon className=\"size-4\" />\n <span>Previous</span>\n </Button>\n <span className=\"text-xs font-semibold text-gray-700 dark:text-gray-300\">\n Page {currentPage} of {totalPages}\n </span>\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isLastPage}\n onClick={() => handlePageChange(currentPage + 1)}\n data-testid={ellipsis ? 'ellipsis-mobile-next-btn' : 'mobile-next-btn'}\n className=\"flex items-center gap-1 font-medium\"\n >\n <span>Next</span>\n <ChevronRightIcon className=\"size-4\" />\n </Button>\n </div>\n )\n }\n\n // Standard Responsive View\n return (\n <div\n data-testid=\"pagination-container\"\n className={buildClassName(\n 'flex items-center justify-between bg-white dark:bg-gray-800 px-4 py-3 sm:px-6 rounded-xl border border-[var(--ui-border-muted)] w-full',\n className,\n )}\n >\n {/* Mobile Layout (< 640px) */}\n <div className=\"flex flex-1 items-center justify-between sm:hidden\">\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isFirstPage}\n onClick={() => handlePageChange(currentPage - 1)}\n data-testid={ellipsis ? 'ellipsis-mobile-prev-btn' : 'mobile-prev-btn'}\n className=\"flex items-center gap-1\"\n >\n <ChevronLeftIcon className=\"size-4\" />\n <span>Previous</span>\n </Button>\n <span className=\"text-xs font-semibold text-gray-700 dark:text-gray-300\">\n Page {currentPage} of {totalPages}\n </span>\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isLastPage}\n onClick={() => handlePageChange(currentPage + 1)}\n data-testid={ellipsis ? 'ellipsis-mobile-next-btn' : 'mobile-next-btn'}\n className=\"flex items-center gap-1\"\n >\n <span>Next</span>\n <ChevronRightIcon className=\"size-4\" />\n </Button>\n </div>\n\n {/* Desktop / Tablet Layout (>= 640px) */}\n <div className=\"hidden sm:flex sm:flex-1 sm:items-center sm:justify-between\">\n {showSummary && (\n <p\n data-testid=\"pagination-summary\"\n className=\"text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1\"\n >\n Showing\n <span className=\"font-medium\">{startResult}</span>\n to\n <span className=\"font-medium\">{endResult}</span>\n of\n <span className=\"font-medium\">{total}</span>\n results\n </p>\n )}\n\n {showPageNumbers && (\n <ul className=\"flex items-center space-x-2 text-sm\">\n <li>\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isFirstPage}\n onClick={() => handlePageChange(currentPage - 1)}\n data-testid={ellipsis ? 'ellipsis-prev-btn' : 'prev-btn'}\n >\n {ellipsis ? 'Prev' : 'Previous'}\n </Button>\n </li>\n {ellipsis\n ? range.map((pageItem, idx) => {\n if (pageItem === DOTS) {\n return (\n <li\n key={`${pageItem}-${idx}`}\n data-testid={`page-${pageItem}`}\n className=\"px-2 py-1 text-gray-400\"\n >\n &hellip;\n </li>\n )\n }\n const pageNum = Number(pageItem)\n return (\n <li key={`${pageItem}-${idx}`}>\n <Button\n size=\"xs\"\n theme={pageNum === currentPage ? 'primary' : 'secondary'}\n variant={pageNum === currentPage ? 'default' : 'plain'}\n aria-current={pageNum === currentPage ? 'page' : undefined}\n onClick={() => handlePageChange(pageNum)}\n >\n {pageNum}\n </Button>\n </li>\n )\n })\n : Array.from({ length: totalPages }, (_, i) => i + 1).map((pageNum) => (\n <li key={pageNum}>\n <Button\n size=\"xs\"\n theme={pageNum === currentPage ? 'primary' : 'secondary'}\n variant={pageNum === currentPage ? 'default' : 'plain'}\n aria-current={pageNum === currentPage ? 'page' : undefined}\n onClick={() => handlePageChange(pageNum)}\n >\n <span className=\"size-4 block\">{pageNum}</span>\n </Button>\n </li>\n ))}\n <li>\n <Button\n size=\"xs\"\n theme=\"secondary\"\n variant=\"plain\"\n disabled={isLastPage}\n onClick={() => handlePageChange(currentPage + 1)}\n data-testid={ellipsis ? 'ellipsis-next-btn' : 'next-btn'}\n >\n {ellipsis ? 'Next' : 'Next'}\n </Button>\n </li>\n </ul>\n )}\n </div>\n </div>\n )\n}\n\nPagination.displayName = 'Pagination'\n"],"names":["usePagination","_jsxs","buildClassName","Button","_jsx","ChevronLeftIcon","ChevronRightIcon","DOTS"],"mappings":"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"}
@@ -17,16 +17,20 @@ const THEME_MAP = {
17
17
  danger: 'checked:border-[var(--ui-danger)] checked:hover:border-[var(--ui-danger)] focus:ring-[var(--ui-danger-ring)]',
18
18
  };
19
19
  const Radio = React.forwardRef((props, ref) => {
20
- const { id, name, label, description, size = 'md', theme = 'primary', labelClass = '', descriptionClass = '', wrapperClass = '', containerClass = '', error, disabled = false, className = '', ...rest } = props;
20
+ const { id, name, label, description, size = 'md', theme = 'primary', labelClass = '', descriptionClass = '', wrapperClass = '', containerClass = '', error, disabled = false, className = '', required, 'aria-describedby': ariaDescribedBy, ...rest } = props;
21
21
  const generatedId = React.useId();
22
22
  const radioId = id !== null && id !== void 0 ? id : (name && rest.value ? `${name}-${rest.value}` : generatedId);
23
- return (jsxRuntime.jsxs("div", { className: buildClassname.buildClassName(wrapperClass), children: [jsxRuntime.jsxs("div", { className: buildClassname.buildClassName('flex items-start gap-2.5', containerClass), children: [jsxRuntime.jsx("div", { className: "grid place-items-center shrink-0 pt-0.5", children: jsxRuntime.jsx("input", { ref: ref, ...rest, id: radioId, name: name, type: "radio", disabled: disabled, "aria-checked": rest.checked, className: buildClassname.buildClassName('peer transition-all col-start-1 row-start-1 appearance-none shrink-0 rounded-full', 'border focus:ring-2 focus:ring-offset-2', 'checked:border-5 checked:bg-white', 'dark:focus:ring-offset-gray-800', SIZE_MAP[size], THEME_MAP[theme], disabled
23
+ const hasError = Boolean(error);
24
+ const errorId = radioId && hasError ? `${radioId}-error` : undefined;
25
+ const descId = radioId && description ? `${radioId}-desc` : undefined;
26
+ const describedBy = [ariaDescribedBy, errorId, descId].filter(Boolean).join(' ') || undefined;
27
+ return (jsxRuntime.jsxs("div", { className: buildClassname.buildClassName(wrapperClass), children: [jsxRuntime.jsxs("div", { className: buildClassname.buildClassName('flex items-start gap-2.5', containerClass), children: [jsxRuntime.jsx("div", { className: "grid place-items-center shrink-0 pt-0.5", children: jsxRuntime.jsx("input", { ref: ref, ...rest, id: radioId, name: name, type: "radio", disabled: disabled, required: required, "aria-required": required ? true : undefined, "aria-invalid": hasError ? true : undefined, "aria-describedby": describedBy, "aria-checked": rest.checked, className: buildClassname.buildClassName('peer transition-all col-start-1 row-start-1 appearance-none shrink-0 rounded-full', 'border focus:ring-2 focus:ring-offset-2', 'checked:border-5 checked:bg-white', 'dark:focus:ring-offset-gray-800', SIZE_MAP[size], THEME_MAP[theme], disabled
24
28
  ? 'border-[var(--ui-border-muted)] bg-gray-100 dark:bg-gray-800 pointer-events-none'
25
- : 'bg-white dark:bg-gray-700 border-[var(--ui-border)] hover:border-gray-400 dark:hover:border-gray-500 cursor-pointer', className) }) }), (label || description) && (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [label && (jsxRuntime.jsx(Label.Label, { htmlFor: radioId, className: buildClassname.buildClassName(disabled
29
+ : 'bg-white dark:bg-gray-700 border-[var(--ui-border)] hover:border-gray-400 dark:hover:border-gray-500 cursor-pointer', className) }) }), (label || description) && (jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [label && (jsxRuntime.jsx(Label.Label, { htmlFor: radioId, "aria-required": required, className: buildClassname.buildClassName(disabled
26
30
  ? 'cursor-not-allowed text-gray-400 dark:text-gray-500'
27
- : 'cursor-pointer text-gray-700 dark:text-gray-200 font-medium', labelClass), children: label })), description && (jsxRuntime.jsx("p", { className: buildClassname.buildClassName('text-xs leading-normal', disabled
31
+ : 'cursor-pointer text-gray-700 dark:text-gray-200 font-medium', labelClass), children: label })), description && (jsxRuntime.jsx("p", { id: descId, className: buildClassname.buildClassName('text-xs leading-normal', disabled
28
32
  ? 'text-gray-300 dark:text-gray-600'
29
- : 'text-gray-500 dark:text-gray-400', descriptionClass), children: description }))] }))] }), error && (jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx(TextContent.TextContent, { error: true, small: true, children: error }) }))] }));
33
+ : 'text-gray-500 dark:text-gray-400', descriptionClass), children: description }))] }))] }), error && (jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx(TextContent.TextContent, { error: true, small: true, id: errorId, children: error }) }))] }));
30
34
  });
31
35
  Radio.displayName = 'Radio';
32
36
 
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.js","sources":["../../../../../src/components/Radio/Radio.tsx"],"sourcesContent":["import { forwardRef, useId } from 'react'\nimport { Label } from '../Label'\nimport { buildClassName } from '../../utils/build-classname'\nimport type { RadioProps, RadioSize, RadioTheme } from './Radio.types'\nimport { TextContent } from '../TextContent'\n\nconst SIZE_MAP: Record<RadioSize, string> = {\n sm: 'size-4',\n md: 'size-4.5',\n lg: 'size-5.5',\n}\n\nconst THEME_MAP: Record<RadioTheme, string> = {\n primary:\n 'checked:border-[var(--ui-primary)] checked:hover:border-[var(--ui-primary)] focus:ring-[var(--ui-primary-ring)]',\n success: 'checked:border-emerald-600 checked:hover:border-emerald-600 focus:ring-emerald-500',\n danger:\n 'checked:border-[var(--ui-danger)] checked:hover:border-[var(--ui-danger)] focus:ring-[var(--ui-danger-ring)]',\n}\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {\n const {\n id,\n name,\n label,\n description,\n size = 'md',\n theme = 'primary',\n labelClass = '',\n descriptionClass = '',\n wrapperClass = '',\n containerClass = '',\n error,\n disabled = false,\n className = '',\n ...rest\n } = props\n\n const generatedId = useId()\n const radioId = id ?? (name && rest.value ? `${name}-${rest.value}` : generatedId)\n\n return (\n <div className={buildClassName(wrapperClass)}>\n <div className={buildClassName('flex items-start gap-2.5', containerClass)}>\n <div className=\"grid place-items-center shrink-0 pt-0.5\">\n <input\n ref={ref}\n {...rest}\n id={radioId}\n name={name}\n type=\"radio\"\n disabled={disabled}\n aria-checked={rest.checked}\n className={buildClassName(\n 'peer transition-all col-start-1 row-start-1 appearance-none shrink-0 rounded-full',\n 'border focus:ring-2 focus:ring-offset-2',\n 'checked:border-5 checked:bg-white',\n 'dark:focus:ring-offset-gray-800',\n SIZE_MAP[size],\n THEME_MAP[theme],\n disabled\n ? 'border-[var(--ui-border-muted)] bg-gray-100 dark:bg-gray-800 pointer-events-none'\n : 'bg-white dark:bg-gray-700 border-[var(--ui-border)] hover:border-gray-400 dark:hover:border-gray-500 cursor-pointer',\n className,\n )}\n />\n </div>\n {(label || description) && (\n <div className=\"flex flex-col gap-0.5 min-w-0\">\n {label && (\n <Label\n htmlFor={radioId}\n className={buildClassName(\n disabled\n ? 'cursor-not-allowed text-gray-400 dark:text-gray-500'\n : 'cursor-pointer text-gray-700 dark:text-gray-200 font-medium',\n labelClass,\n )}\n >\n {label}\n </Label>\n )}\n {description && (\n <p\n className={buildClassName(\n 'text-xs leading-normal',\n disabled\n ? 'text-gray-300 dark:text-gray-600'\n : 'text-gray-500 dark:text-gray-400',\n descriptionClass,\n )}\n >\n {description}\n </p>\n )}\n </div>\n )}\n </div>\n {error && (\n <div className=\"mt-1\">\n <TextContent error small>\n {error}\n </TextContent>\n </div>\n )}\n </div>\n )\n})\n\nRadio.displayName = 'Radio'\n"],"names":["forwardRef","useId","_jsxs","buildClassName","_jsx","Label","TextContent"],"mappings":";;;;;;;;AAMA,MAAM,QAAQ,GAA8B;AAC1C,IAAA,EAAE,EAAE,QAAQ;AACZ,IAAA,EAAE,EAAE,UAAU;AACd,IAAA,EAAE,EAAE,UAAU;CACf;AAED,MAAM,SAAS,GAA+B;AAC5C,IAAA,OAAO,EACL,iHAAiH;AACnH,IAAA,OAAO,EAAE,oFAAoF;AAC7F,IAAA,MAAM,EACJ,8GAA8G;CACjH;AAEM,MAAM,KAAK,GAAGA,gBAAU,CAA+B,CAAC,KAAK,EAAE,GAAG,KAAI;IAC3E,MAAM,EACJ,EAAE,EACF,IAAI,EACJ,KAAK,EACL,WAAW,EACX,IAAI,GAAG,IAAI,EACX,KAAK,GAAG,SAAS,EACjB,UAAU,GAAG,EAAE,EACf,gBAAgB,GAAG,EAAE,EACrB,YAAY,GAAG,EAAE,EACjB,cAAc,GAAG,EAAE,EACnB,KAAK,EACL,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,EAAE,EACd,GAAG,IAAI,EACR,GAAG,KAAK;AAET,IAAA,MAAM,WAAW,GAAGC,WAAK,EAAE;AAC3B,IAAA,MAAM,OAAO,GAAG,EAAE,KAAA,IAAA,IAAF,EAAE,KAAA,MAAA,GAAF,EAAE,IAAK,IAAI,IAAI,IAAI,CAAC,KAAK,GAAG,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAC,KAAK,CAAA,CAAE,GAAG,WAAW,CAAC;AAElF,IAAA,QACEC,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAEC,6BAAc,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,CAC1CD,yBAAK,SAAS,EAAEC,6BAAc,CAAC,0BAA0B,EAAE,cAAc,CAAC,EAAA,QAAA,EAAA,CACxEC,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,yCAAyC,YACtDA,cAAA,CAAA,OAAA,EAAA,EACE,GAAG,EAAE,GAAG,KACJ,IAAI,EACR,EAAE,EAAE,OAAO,EACX,IAAI,EAAE,IAAI,EACV,IAAI,EAAC,OAAO,EACZ,QAAQ,EAAE,QAAQ,EAAA,cAAA,EACJ,IAAI,CAAC,OAAO,EAC1B,SAAS,EAAED,6BAAc,CACvB,mFAAmF,EACnF,yCAAyC,EACzC,mCAAmC,EACnC,iCAAiC,EACjC,QAAQ,CAAC,IAAI,CAAC,EACd,SAAS,CAAC,KAAK,CAAC,EAChB;AACE,kCAAE;AACF,kCAAE,qHAAqH,EACzH,SAAS,CACV,EAAA,CACD,EAAA,CACE,EACL,CAAC,KAAK,IAAI,WAAW,MACpBD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,+BAA+B,EAAA,QAAA,EAAA,CAC3C,KAAK,KACJE,eAACC,WAAK,EAAA,EACJ,OAAO,EAAE,OAAO,EAChB,SAAS,EAAEF,6BAAc,CACvB;AACE,sCAAE;sCACA,6DAA6D,EACjE,UAAU,CACX,EAAA,QAAA,EAEA,KAAK,GACA,CACT,EACA,WAAW,KACVC,sBACE,SAAS,EAAED,6BAAc,CACvB,wBAAwB,EACxB;AACE,sCAAE;AACF,sCAAE,kCAAkC,EACtC,gBAAgB,CACjB,EAAA,QAAA,EAEA,WAAW,EAAA,CACV,CACL,IACG,CACP,CAAA,EAAA,CACG,EACL,KAAK,KACJC,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,MAAM,EAAA,QAAA,EACnBA,cAAA,CAACE,uBAAW,IAAC,KAAK,EAAA,IAAA,EAAC,KAAK,EAAA,IAAA,EAAA,QAAA,EACrB,KAAK,EAAA,CACM,EAAA,CACV,CACP,CAAA,EAAA,CACG;AAEV,CAAC;AAED,KAAK,CAAC,WAAW,GAAG,OAAO;;;;"}
1
+ {"version":3,"file":"Radio.js","sources":["../../../../../src/components/Radio/Radio.tsx"],"sourcesContent":["import { forwardRef, useId } from 'react'\nimport { Label } from '../Label'\nimport { buildClassName } from '../../utils/build-classname'\nimport type { RadioProps, RadioSize, RadioTheme } from './Radio.types'\nimport { TextContent } from '../TextContent'\n\nconst SIZE_MAP: Record<RadioSize, string> = {\n sm: 'size-4',\n md: 'size-4.5',\n lg: 'size-5.5',\n}\n\nconst THEME_MAP: Record<RadioTheme, string> = {\n primary:\n 'checked:border-[var(--ui-primary)] checked:hover:border-[var(--ui-primary)] focus:ring-[var(--ui-primary-ring)]',\n success: 'checked:border-emerald-600 checked:hover:border-emerald-600 focus:ring-emerald-500',\n danger:\n 'checked:border-[var(--ui-danger)] checked:hover:border-[var(--ui-danger)] focus:ring-[var(--ui-danger-ring)]',\n}\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {\n const {\n id,\n name,\n label,\n description,\n size = 'md',\n theme = 'primary',\n labelClass = '',\n descriptionClass = '',\n wrapperClass = '',\n containerClass = '',\n error,\n disabled = false,\n className = '',\n required,\n 'aria-describedby': ariaDescribedBy,\n ...rest\n } = props\n\n const generatedId = useId()\n const radioId = id ?? (name && rest.value ? `${name}-${rest.value}` : generatedId)\n\n const hasError = Boolean(error)\n const errorId = radioId && hasError ? `${radioId}-error` : undefined\n const descId = radioId && description ? `${radioId}-desc` : undefined\n const describedBy = [ariaDescribedBy, errorId, descId].filter(Boolean).join(' ') || undefined\n\n return (\n <div className={buildClassName(wrapperClass)}>\n <div className={buildClassName('flex items-start gap-2.5', containerClass)}>\n <div className=\"grid place-items-center shrink-0 pt-0.5\">\n <input\n ref={ref}\n {...rest}\n id={radioId}\n name={name}\n type=\"radio\"\n disabled={disabled}\n required={required}\n aria-required={required ? true : undefined}\n aria-invalid={hasError ? true : undefined}\n aria-describedby={describedBy}\n aria-checked={rest.checked}\n className={buildClassName(\n 'peer transition-all col-start-1 row-start-1 appearance-none shrink-0 rounded-full',\n 'border focus:ring-2 focus:ring-offset-2',\n 'checked:border-5 checked:bg-white',\n 'dark:focus:ring-offset-gray-800',\n SIZE_MAP[size],\n THEME_MAP[theme],\n disabled\n ? 'border-[var(--ui-border-muted)] bg-gray-100 dark:bg-gray-800 pointer-events-none'\n : 'bg-white dark:bg-gray-700 border-[var(--ui-border)] hover:border-gray-400 dark:hover:border-gray-500 cursor-pointer',\n className,\n )}\n />\n </div>\n {(label || description) && (\n <div className=\"flex flex-col gap-0.5 min-w-0\">\n {label && (\n <Label\n htmlFor={radioId}\n aria-required={required}\n className={buildClassName(\n disabled\n ? 'cursor-not-allowed text-gray-400 dark:text-gray-500'\n : 'cursor-pointer text-gray-700 dark:text-gray-200 font-medium',\n labelClass,\n )}\n >\n {label}\n </Label>\n )}\n {description && (\n <p\n id={descId}\n className={buildClassName(\n 'text-xs leading-normal',\n disabled\n ? 'text-gray-300 dark:text-gray-600'\n : 'text-gray-500 dark:text-gray-400',\n descriptionClass,\n )}\n >\n {description}\n </p>\n )}\n </div>\n )}\n </div>\n {error && (\n <div className=\"mt-1\">\n <TextContent error small id={errorId}>\n {error}\n </TextContent>\n </div>\n )}\n </div>\n )\n})\n\nRadio.displayName = 'Radio'\n"],"names":["forwardRef","useId","_jsxs","buildClassName","_jsx","Label","TextContent"],"mappings":"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"}
@@ -14,7 +14,9 @@ const COLUMN_GRID_MAP = {
14
14
  4: 'grid-cols-1 md:grid-cols-4',
15
15
  };
16
16
  const RadioGroup = (props) => {
17
- const { name, variant = 'default', size = 'md', theme = 'primary', label, labelClass, labelWrapperClass, labelHint, containerClass, options, value, columns, disabled = false, row, error, showErrorMessage = true, onChange, } = props;
17
+ const { name, variant = 'default', size = 'md', theme = 'primary', label, labelClass, labelWrapperClass, labelHint, containerClass, options, value, columns, disabled = false, row, error, showErrorMessage = true, onChange, required, 'aria-describedby': ariaDescribedBy, } = props;
18
+ const groupId = React.useId();
19
+ const groupName = name || groupId;
18
20
  const items = React.useMemo(() => {
19
21
  var _a;
20
22
  return (_a = options === null || options === void 0 ? void 0 : options.map((option) => typeof option === 'string'
@@ -28,21 +30,26 @@ const RadioGroup = (props) => {
28
30
  : option)) !== null && _a !== void 0 ? _a : [];
29
31
  }, [options]);
30
32
  const isCards = variant === 'cards';
31
- return (jsxRuntime.jsxs("div", { className: buildClassname.buildClassName(containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassname.buildClassName('flex items-center justify-between mb-3', labelWrapperClass), children: [jsxRuntime.jsx(Label.Label, { className: labelClass, children: label }), labelHint] })), jsxRuntime.jsx("div", { className: buildClassname.buildClassName(columns
33
+ const hasError = Boolean(error);
34
+ const labelId = label ? `${groupId}-label` : undefined;
35
+ const errorId = groupId && hasError && showErrorMessage ? `${groupId}-error` : undefined;
36
+ const describedBy = [ariaDescribedBy, errorId].filter(Boolean).join(' ') || undefined;
37
+ return (jsxRuntime.jsxs("div", { role: "radiogroup", "aria-labelledby": labelId, "aria-describedby": describedBy, className: buildClassname.buildClassName(containerClass), children: [label && (jsxRuntime.jsxs("div", { className: buildClassname.buildClassName('flex items-center justify-between mb-3', labelWrapperClass), children: [jsxRuntime.jsx(Label.Label, { id: labelId, className: labelClass, "aria-required": required, children: label }), labelHint] })), jsxRuntime.jsx("div", { className: buildClassname.buildClassName(columns
32
38
  ? buildClassname.buildClassName('grid gap-3', COLUMN_GRID_MAP[columns])
33
39
  : row || isCards
34
40
  ? 'flex flex-wrap gap-3'
35
41
  : 'flex flex-col gap-3'), children: items.map((item) => {
36
42
  const isSelected = value === item.value;
37
43
  const isItemDisabled = disabled || Boolean(item.disabled);
44
+ const radioItemId = `${groupName}-${item.value}`;
38
45
  if (isCards) {
39
- return (jsxRuntime.jsxs("label", { htmlFor: `${name}-${item.value}`, className: buildClassname.buildClassName('relative flex items-start gap-3 p-4 rounded-xl border transition-all cursor-pointer select-none min-w-[200px] flex-1', isSelected
46
+ return (jsxRuntime.jsxs("label", { htmlFor: radioItemId, className: buildClassname.buildClassName('relative flex items-start gap-3 p-4 rounded-xl border transition-all cursor-pointer select-none min-w-[200px] flex-1', 'focus-within:ring-2 focus-within:ring-[var(--ui-primary-ring)] focus-within:border-[var(--ui-primary)]', isSelected
40
47
  ? 'border-[var(--ui-primary)] bg-blue-50/40 dark:bg-blue-950/30 ring-2 ring-[var(--ui-primary-ring)]/30'
41
48
  : 'border-[var(--ui-border)] bg-white dark:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600', isItemDisabled &&
42
- 'opacity-50 cursor-not-allowed pointer-events-none bg-gray-50 dark:bg-gray-800/50'), children: [jsxRuntime.jsx(Radio.Radio, { name: name, id: `${name}-${item.value}`, value: item.value, "aria-label": item.label, size: size, theme: theme, checked: isSelected, disabled: isItemDisabled, onChange: onChange, containerClass: "pt-0.5" }), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [item.icon && (jsxRuntime.jsx("span", { className: "shrink-0 text-gray-500 dark:text-gray-400", children: item.icon })), jsxRuntime.jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-white truncate", children: item.label })] }), item.description && (jsxRuntime.jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400 font-normal leading-relaxed", children: item.description }))] })] }, item.value));
49
+ 'opacity-50 cursor-not-allowed pointer-events-none bg-gray-50 dark:bg-gray-800/50'), children: [jsxRuntime.jsx(Radio.Radio, { name: groupName, id: radioItemId, value: item.value, "aria-label": item.label, size: size, theme: theme, checked: isSelected, disabled: isItemDisabled, onChange: onChange, containerClass: "pt-0.5" }), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [item.icon && (jsxRuntime.jsx("span", { className: "shrink-0 text-gray-500 dark:text-gray-400", children: item.icon })), jsxRuntime.jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-white truncate", children: item.label })] }), item.description && (jsxRuntime.jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400 font-normal leading-relaxed", children: item.description }))] })] }, item.value));
43
50
  }
44
- return (jsxRuntime.jsx(Radio.Radio, { name: name, id: `${name}-${item.value}`, label: item.label, description: item.description, value: item.value, size: size, theme: theme, checked: isSelected, disabled: isItemDisabled, onChange: onChange }, item.value));
45
- }) }), showErrorMessage && error && (jsxRuntime.jsx("div", { className: "mt-1.5", children: jsxRuntime.jsx(TextContent.TextContent, { error: true, small: true, children: error }) }))] }));
51
+ return (jsxRuntime.jsx(Radio.Radio, { name: groupName, id: radioItemId, label: item.label, description: item.description, value: item.value, size: size, theme: theme, checked: isSelected, disabled: isItemDisabled, onChange: onChange }, item.value));
52
+ }) }), showErrorMessage && error && (jsxRuntime.jsx("div", { className: "mt-1.5", children: jsxRuntime.jsx(TextContent.TextContent, { error: true, small: true, id: errorId, children: error }) }))] }));
46
53
  };
47
54
  RadioGroup.displayName = 'RadioGroup';
48
55
 
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup.js","sources":["../../../../../src/components/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import React, { useMemo } from 'react'\nimport { Radio } from '../Radio'\nimport { Label } from '../Label'\nimport { buildClassName } from '../../utils/build-classname'\nimport { TextContent } from '../TextContent'\nimport type { RadioGroupProps, RadionGroupItem } from './RadioGroup.types'\n\nconst COLUMN_GRID_MAP: Record<number, string> = {\n 1: 'grid-cols-1',\n 2: 'grid-cols-1 md:grid-cols-2',\n 3: 'grid-cols-1 md:grid-cols-3',\n 4: 'grid-cols-1 md:grid-cols-4',\n}\n\nexport const RadioGroup: React.FC<RadioGroupProps> = (props) => {\n const {\n name,\n variant = 'default',\n size = 'md',\n theme = 'primary',\n label,\n labelClass,\n labelWrapperClass,\n labelHint,\n containerClass,\n options,\n value,\n columns,\n disabled = false,\n row,\n error,\n showErrorMessage = true,\n onChange,\n } = props\n\n const items = useMemo(\n () =>\n options?.map((option) =>\n typeof option === 'string'\n ? {\n label: option,\n value: option,\n description: undefined,\n icon: undefined,\n disabled: undefined,\n }\n : option,\n ) ?? [],\n [options],\n )\n\n const isCards = variant === 'cards'\n\n return (\n <div className={buildClassName(containerClass)}>\n {label && (\n <div\n className={buildClassName('flex items-center justify-between mb-3', labelWrapperClass)}\n >\n <Label className={labelClass}>{label}</Label>\n {labelHint}\n </div>\n )}\n\n <div\n className={buildClassName(\n columns\n ? buildClassName('grid gap-3', COLUMN_GRID_MAP[columns])\n : row || isCards\n ? 'flex flex-wrap gap-3'\n : 'flex flex-col gap-3',\n )}\n >\n {items.map((item) => {\n const isSelected = value === item.value\n const isItemDisabled = disabled || Boolean(item.disabled)\n\n if (isCards) {\n return (\n <label\n key={item.value}\n htmlFor={`${name}-${item.value}`}\n className={buildClassName(\n 'relative flex items-start gap-3 p-4 rounded-xl border transition-all cursor-pointer select-none min-w-[200px] flex-1',\n isSelected\n ? 'border-[var(--ui-primary)] bg-blue-50/40 dark:bg-blue-950/30 ring-2 ring-[var(--ui-primary-ring)]/30'\n : 'border-[var(--ui-border)] bg-white dark:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600',\n isItemDisabled &&\n 'opacity-50 cursor-not-allowed pointer-events-none bg-gray-50 dark:bg-gray-800/50',\n )}\n >\n <Radio\n name={name}\n id={`${name}-${item.value}`}\n value={item.value}\n aria-label={item.label}\n size={size}\n theme={theme}\n checked={isSelected}\n disabled={isItemDisabled}\n onChange={onChange}\n containerClass=\"pt-0.5\"\n />\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n {item.icon && (\n <span className=\"shrink-0 text-gray-500 dark:text-gray-400\">{item.icon}</span>\n )}\n <span className=\"text-sm font-semibold text-gray-900 dark:text-white truncate\">\n {item.label}\n </span>\n </div>\n {item.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-gray-400 font-normal leading-relaxed\">\n {item.description}\n </p>\n )}\n </div>\n </label>\n )\n }\n\n return (\n <Radio\n key={item.value}\n name={name}\n id={`${name}-${item.value}`}\n label={item.label}\n description={item.description}\n value={item.value}\n size={size}\n theme={theme}\n checked={isSelected}\n disabled={isItemDisabled}\n onChange={onChange}\n />\n )\n })}\n </div>\n\n {showErrorMessage && error && (\n <div className=\"mt-1.5\">\n <TextContent error small>\n {error}\n </TextContent>\n </div>\n )}\n </div>\n )\n}\n\nRadioGroup.displayName = 'RadioGroup'\n"],"names":["useMemo","_jsxs","buildClassName","_jsx","Label","Radio","TextContent"],"mappings":"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"}
1
+ {"version":3,"file":"RadioGroup.js","sources":["../../../../../src/components/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import React, { useId, useMemo } from 'react'\nimport { Radio } from '../Radio'\nimport { Label } from '../Label'\nimport { buildClassName } from '../../utils/build-classname'\nimport { TextContent } from '../TextContent'\nimport type { RadioGroupProps } from './RadioGroup.types'\n\nconst COLUMN_GRID_MAP: Record<number, string> = {\n 1: 'grid-cols-1',\n 2: 'grid-cols-1 md:grid-cols-2',\n 3: 'grid-cols-1 md:grid-cols-3',\n 4: 'grid-cols-1 md:grid-cols-4',\n}\n\nexport const RadioGroup: React.FC<RadioGroupProps> = (props) => {\n const {\n name,\n variant = 'default',\n size = 'md',\n theme = 'primary',\n label,\n labelClass,\n labelWrapperClass,\n labelHint,\n containerClass,\n options,\n value,\n columns,\n disabled = false,\n row,\n error,\n showErrorMessage = true,\n onChange,\n required,\n 'aria-describedby': ariaDescribedBy,\n } = props\n\n const groupId = useId()\n const groupName = name || groupId\n\n const items = useMemo(\n () =>\n options?.map((option) =>\n typeof option === 'string'\n ? {\n label: option,\n value: option,\n description: undefined,\n icon: undefined,\n disabled: undefined,\n }\n : option,\n ) ?? [],\n [options],\n )\n\n const isCards = variant === 'cards'\n const hasError = Boolean(error)\n const labelId = label ? `${groupId}-label` : undefined\n const errorId = groupId && hasError && showErrorMessage ? `${groupId}-error` : undefined\n const describedBy = [ariaDescribedBy, errorId].filter(Boolean).join(' ') || undefined\n\n return (\n <div\n role=\"radiogroup\"\n aria-labelledby={labelId}\n aria-describedby={describedBy}\n className={buildClassName(containerClass)}\n >\n {label && (\n <div\n className={buildClassName('flex items-center justify-between mb-3', labelWrapperClass)}\n >\n <Label id={labelId} className={labelClass} aria-required={required}>\n {label}\n </Label>\n {labelHint}\n </div>\n )}\n\n <div\n className={buildClassName(\n columns\n ? buildClassName('grid gap-3', COLUMN_GRID_MAP[columns])\n : row || isCards\n ? 'flex flex-wrap gap-3'\n : 'flex flex-col gap-3',\n )}\n >\n {items.map((item) => {\n const isSelected = value === item.value\n const isItemDisabled = disabled || Boolean(item.disabled)\n const radioItemId = `${groupName}-${item.value}`\n\n if (isCards) {\n return (\n <label\n key={item.value}\n htmlFor={radioItemId}\n className={buildClassName(\n 'relative flex items-start gap-3 p-4 rounded-xl border transition-all cursor-pointer select-none min-w-[200px] flex-1',\n 'focus-within:ring-2 focus-within:ring-[var(--ui-primary-ring)] focus-within:border-[var(--ui-primary)]',\n isSelected\n ? 'border-[var(--ui-primary)] bg-blue-50/40 dark:bg-blue-950/30 ring-2 ring-[var(--ui-primary-ring)]/30'\n : 'border-[var(--ui-border)] bg-white dark:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600',\n isItemDisabled &&\n 'opacity-50 cursor-not-allowed pointer-events-none bg-gray-50 dark:bg-gray-800/50',\n )}\n >\n <Radio\n name={groupName}\n id={radioItemId}\n value={item.value}\n aria-label={item.label}\n size={size}\n theme={theme}\n checked={isSelected}\n disabled={isItemDisabled}\n onChange={onChange}\n containerClass=\"pt-0.5\"\n />\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n {item.icon && (\n <span className=\"shrink-0 text-gray-500 dark:text-gray-400\">{item.icon}</span>\n )}\n <span className=\"text-sm font-semibold text-gray-900 dark:text-white truncate\">\n {item.label}\n </span>\n </div>\n {item.description && (\n <p className=\"mt-1 text-xs text-gray-500 dark:text-gray-400 font-normal leading-relaxed\">\n {item.description}\n </p>\n )}\n </div>\n </label>\n )\n }\n\n return (\n <Radio\n key={item.value}\n name={groupName}\n id={radioItemId}\n label={item.label}\n description={item.description}\n value={item.value}\n size={size}\n theme={theme}\n checked={isSelected}\n disabled={isItemDisabled}\n onChange={onChange}\n />\n )\n })}\n </div>\n\n {showErrorMessage && error && (\n <div className=\"mt-1.5\">\n <TextContent error small id={errorId}>\n {error}\n </TextContent>\n </div>\n )}\n </div>\n )\n}\n\nRadioGroup.displayName = 'RadioGroup'\n"],"names":["useId","useMemo","_jsxs","buildClassName","_jsx","Label","Radio","TextContent"],"mappings":";;;;;;;;;AAOA,MAAM,eAAe,GAA2B;AAC9C,IAAA,CAAC,EAAE,aAAa;AAChB,IAAA,CAAC,EAAE,4BAA4B;AAC/B,IAAA,CAAC,EAAE,4BAA4B;AAC/B,IAAA,CAAC,EAAE,4BAA4B;CAChC;AAEM,MAAM,UAAU,GAA8B,CAAC,KAAK,KAAI;IAC7D,MAAM,EACJ,IAAI,EACJ,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,IAAI,EACX,KAAK,GAAG,SAAS,EACjB,KAAK,EACL,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,cAAc,EACd,OAAO,EACP,KAAK,EACL,OAAO,EACP,QAAQ,GAAG,KAAK,EAChB,GAAG,EACH,KAAK,EACL,gBAAgB,GAAG,IAAI,EACvB,QAAQ,EACR,QAAQ,EACR,kBAAkB,EAAE,eAAe,GACpC,GAAG,KAAK;AAET,IAAA,MAAM,OAAO,GAAGA,WAAK,EAAE;AACvB,IAAA,MAAM,SAAS,GAAG,IAAI,IAAI,OAAO;AAEjC,IAAA,MAAM,KAAK,GAAGC,aAAO,CACnB,MAAK;;AACH,QAAA,OAAA,MAAA,OAAO,KAAA,IAAA,IAAP,OAAO,KAAA,MAAA,GAAA,MAAA,GAAP,OAAO,CAAE,GAAG,CAAC,CAAC,MAAM,KAClB,OAAO,MAAM,KAAK;AAChB,cAAE;AACE,gBAAA,KAAK,EAAE,MAAM;AACb,gBAAA,KAAK,EAAE,MAAM;AACb,gBAAA,WAAW,EAAE,SAAS;AACtB,gBAAA,IAAI,EAAE,SAAS;AACf,gBAAA,QAAQ,EAAE,SAAS;AACpB;AACH,cAAE,MAAM,CACX,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,EAAA,GAAI,EAAE;AAAA,IAAA,CAAA,EACT,CAAC,OAAO,CAAC,CACV;AAED,IAAA,MAAM,OAAO,GAAG,OAAO,KAAK,OAAO;AACnC,IAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;AAC/B,IAAA,MAAM,OAAO,GAAG,KAAK,GAAG,CAAA,EAAG,OAAO,CAAA,MAAA,CAAQ,GAAG,SAAS;AACtD,IAAA,MAAM,OAAO,GAAG,OAAO,IAAI,QAAQ,IAAI,gBAAgB,GAAG,GAAG,OAAO,CAAA,MAAA,CAAQ,GAAG,SAAS;AACxF,IAAA,MAAM,WAAW,GAAG,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS;IAErF,QACEC,eAAA,CAAA,KAAA,EAAA,EACE,IAAI,EAAC,YAAY,qBACA,OAAO,EAAA,kBAAA,EACN,WAAW,EAC7B,SAAS,EAAEC,6BAAc,CAAC,cAAc,CAAC,EAAA,QAAA,EAAA,CAExC,KAAK,KACJD,eAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAEC,6BAAc,CAAC,wCAAwC,EAAE,iBAAiB,CAAC,EAAA,QAAA,EAAA,CAEtFC,cAAA,CAACC,WAAK,EAAA,EAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAA,eAAA,EAAiB,QAAQ,YAC/D,KAAK,EAAA,CACA,EACP,SAAS,CAAA,EAAA,CACN,CACP,EAEDD,cAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAED,6BAAc,CACvB;sBACIA,6BAAc,CAAC,YAAY,EAAE,eAAe,CAAC,OAAO,CAAC;sBACrD,GAAG,IAAI;AACP,0BAAE;0BACA,qBAAqB,CAC5B,EAAA,QAAA,EAEA,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;AAClB,oBAAA,MAAM,UAAU,GAAG,KAAK,KAAK,IAAI,CAAC,KAAK;oBACvC,MAAM,cAAc,GAAG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;oBACzD,MAAM,WAAW,GAAG,CAAA,EAAG,SAAS,IAAI,IAAI,CAAC,KAAK,CAAA,CAAE;oBAEhD,IAAI,OAAO,EAAE;AACX,wBAAA,QACED,eAAA,CAAA,OAAA,EAAA,EAEE,OAAO,EAAE,WAAW,EACpB,SAAS,EAAEC,6BAAc,CACvB,sHAAsH,EACtH,wGAAwG,EACxG;AACE,kCAAE;kCACA,sGAAsG,EAC1G,cAAc;gCACZ,kFAAkF,CACrF,aAEDC,cAAA,CAACE,WAAK,IACJ,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,WAAW,EACf,KAAK,EAAE,IAAI,CAAC,KAAK,gBACL,IAAI,CAAC,KAAK,EACtB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAC,QAAQ,GACvB,EAEFJ,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,gBAAgB,EAAA,QAAA,EAAA,CAC7BA,yBAAK,SAAS,EAAC,yBAAyB,EAAA,QAAA,EAAA,CACrC,IAAI,CAAC,IAAI,KACRE,cAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,2CAA2C,YAAE,IAAI,CAAC,IAAI,EAAA,CAAQ,CAC/E,EACDA,yBAAM,SAAS,EAAC,8DAA8D,EAAA,QAAA,EAC3E,IAAI,CAAC,KAAK,EAAA,CACN,CAAA,EAAA,CACH,EACL,IAAI,CAAC,WAAW,KACfA,cAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAC,2EAA2E,EAAA,QAAA,EACrF,IAAI,CAAC,WAAW,EAAA,CACf,CACL,CAAA,EAAA,CACG,CAAA,EAAA,EAvCD,IAAI,CAAC,KAAK,CAwCT;oBAEZ;oBAEA,QACEA,cAAA,CAACE,WAAK,EAAA,EAEJ,IAAI,EAAE,SAAS,EACf,EAAE,EAAE,WAAW,EACf,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,WAAW,EAAE,IAAI,CAAC,WAAW,EAC7B,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,QAAQ,EAAA,EAVb,IAAI,CAAC,KAAK,CAWf;AAEN,gBAAA,CAAC,CAAC,EAAA,CACE,EAEL,gBAAgB,IAAI,KAAK,KACxBF,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,QAAQ,YACrBA,cAAA,CAACG,uBAAW,EAAA,EAAC,KAAK,EAAA,IAAA,EAAC,KAAK,EAAA,IAAA,EAAC,EAAE,EAAE,OAAO,EAAA,QAAA,EACjC,KAAK,EAAA,CACM,EAAA,CACV,CACP,CAAA,EAAA,CACG;AAEV;AAEA,UAAU,CAAC,WAAW,GAAG,YAAY;;;;"}