@pk-design/react-tailwind 1.8.0 → 1.9.0

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 (32) hide show
  1. package/dist/cjs/components/Banner/Banner.js +1 -1
  2. package/dist/cjs/components/Banner/Banner.js.map +1 -1
  3. package/dist/cjs/components/Button/Button.js +88 -60
  4. package/dist/cjs/components/Button/Button.js.map +1 -1
  5. package/dist/cjs/components/DataTable/DataTable.js +1 -1
  6. package/dist/cjs/components/DataTable/DataTable.js.map +1 -1
  7. package/dist/cjs/components/RadioGroup/RadioGroup.js +5 -3
  8. package/dist/cjs/components/RadioGroup/RadioGroup.js.map +1 -1
  9. package/dist/cjs/components/SelectBox/SelectBox.js +25 -4
  10. package/dist/cjs/components/SelectBox/SelectBox.js.map +1 -1
  11. package/dist/cjs/components/Toast/Toast.js +1 -1
  12. package/dist/cjs/components/Toast/Toast.js.map +1 -1
  13. package/dist/es/components/Banner/Banner.js +1 -1
  14. package/dist/es/components/Banner/Banner.js.map +1 -1
  15. package/dist/es/components/Button/Button.js +89 -61
  16. package/dist/es/components/Button/Button.js.map +1 -1
  17. package/dist/es/components/DataTable/DataTable.js +1 -1
  18. package/dist/es/components/DataTable/DataTable.js.map +1 -1
  19. package/dist/es/components/RadioGroup/RadioGroup.js +5 -3
  20. package/dist/es/components/RadioGroup/RadioGroup.js.map +1 -1
  21. package/dist/es/components/SelectBox/SelectBox.js +26 -5
  22. package/dist/es/components/SelectBox/SelectBox.js.map +1 -1
  23. package/dist/es/components/Toast/Toast.js +1 -1
  24. package/dist/es/components/Toast/Toast.js.map +1 -1
  25. package/dist/react-tailwind.cjs.js +121 -70
  26. package/dist/react-tailwind.cjs.js.map +1 -1
  27. package/dist/react-tailwind.es.js +122 -71
  28. package/dist/react-tailwind.es.js.map +1 -1
  29. package/dist/types/components/Button/Button.types.d.ts +12 -6
  30. package/dist/types/components/DataTable/DataTable.types.d.ts +2 -2
  31. package/dist/types/components/SelectBox/SelectBox.types.d.ts +18 -1
  32. package/package.json +1 -1
@@ -1,64 +1,40 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { forwardRef, useMemo } from 'react';
2
+ import { forwardRef, useEffect, useMemo } from 'react';
3
3
  import { buildClassName } from '../../utils/build-classname.js';
4
4
  import { Loader } from '../Loader/index.js';
5
5
  import { TextContent } from '../TextContent/TextContent.js';
6
6
 
7
7
  /**
8
8
  * Tailwind CSS classes for theme + variant combinations.
9
+ *
10
+ * Only colours live here. Focus outline width/offset and disabled styling are
11
+ * applied uniformly in the component so they can be toggled in one place.
9
12
  */
10
13
  const THEMED_BTN_CLASS = {
11
14
  primary: {
12
- default: 'text-white bg-[var(--ui-primary)] hover:bg-[var(--ui-primary-hover)] focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-primary-ring)] disabled:bg-[var(--ui-primary-disabled)]',
13
- outlined: 'text-[var(--ui-primary-text)] hover:text-white border border-[var(--ui-primary)] hover:bg-[var(--ui-primary)] focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-primary-ring)] disabled:text-[var(--ui-primary-disabled)] disabled:border-[var(--ui-primary-disabled)]',
14
- plain: 'text-[var(--ui-primary-text)] hover:bg-blue-50/80 dark:hover:bg-blue-950/40 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-primary-ring)] disabled:text-[var(--ui-primary-disabled)]',
15
+ default: 'text-white bg-[var(--ui-primary)] hover:bg-[var(--ui-primary-hover)] focus-visible:outline-[var(--ui-primary-ring)]',
16
+ outlined: 'text-[var(--ui-primary-text)] hover:text-white border border-[var(--ui-primary)] hover:bg-[var(--ui-primary)] focus-visible:outline-[var(--ui-primary-ring)]',
17
+ plain: 'text-[var(--ui-primary-text)] hover:bg-current/10 active:bg-current/15 focus-visible:outline-[var(--ui-primary-ring)]',
15
18
  },
16
19
  danger: {
17
- default: 'text-white bg-[var(--ui-danger)] hover:bg-[var(--ui-danger-hover)] focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-danger-ring)] disabled:bg-[var(--ui-danger-disabled)]',
18
- outlined: 'text-[var(--ui-danger-text)] hover:text-white border border-[var(--ui-danger)] hover:bg-[var(--ui-danger)] focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-danger-ring)] disabled:text-[var(--ui-danger-disabled)] disabled:border-[var(--ui-danger-disabled)]',
19
- plain: 'text-[var(--ui-danger-text)] hover:bg-red-50/80 dark:hover:bg-red-950/40 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-danger-ring)] disabled:text-[var(--ui-danger-disabled)]',
20
+ default: 'text-white bg-[var(--ui-danger)] hover:bg-[var(--ui-danger-hover)] focus-visible:outline-[var(--ui-danger-ring)]',
21
+ outlined: 'text-[var(--ui-danger-text)] hover:text-white border border-[var(--ui-danger)] hover:bg-[var(--ui-danger)] focus-visible:outline-[var(--ui-danger-ring)]',
22
+ plain: 'text-[var(--ui-danger-text)] hover:bg-current/10 active:bg-current/15 focus-visible:outline-[var(--ui-danger-ring)]',
20
23
  },
21
24
  secondary: {
22
- default: 'text-gray-700 bg-white border border-[var(--ui-border)] hover:bg-gray-100 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:bg-gray-200 dark:disabled:bg-gray-700',
23
- outlined: 'text-gray-700 hover:text-white border border-[var(--ui-border)] hover:bg-gray-700 dark:text-gray-200 dark:hover:text-white dark:hover:bg-gray-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:text-gray-400 disabled:border-[var(--ui-border-muted)]',
24
- plain: 'text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:text-gray-400',
25
+ default: 'text-gray-700 bg-white border border-[var(--ui-border)] hover:bg-gray-100 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700 focus-visible:outline-[var(--ui-focus-ring)]',
26
+ outlined: 'text-gray-700 hover:text-white border border-[var(--ui-border)] hover:bg-gray-700 dark:text-gray-200 dark:hover:text-white dark:hover:bg-gray-600 focus-visible:outline-[var(--ui-focus-ring)]',
27
+ plain: 'text-gray-700 hover:bg-current/10 active:bg-current/15 dark:text-gray-200 focus-visible:outline-[var(--ui-focus-ring)]',
25
28
  },
26
29
  success: {
27
- default: 'text-white bg-emerald-600 hover:bg-emerald-700 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-emerald-500 disabled:bg-emerald-300 dark:disabled:bg-emerald-900',
28
- outlined: 'text-emerald-600 hover:text-white border border-emerald-600 hover:bg-emerald-600 dark:text-emerald-400 dark:border-emerald-500 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-emerald-500 disabled:opacity-50',
29
- plain: 'text-emerald-600 hover:bg-emerald-50 dark:text-emerald-400 dark:hover:bg-emerald-950/40 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-emerald-500 disabled:opacity-50',
30
+ default: 'text-white bg-emerald-600 hover:bg-emerald-700 focus-visible:outline-emerald-500',
31
+ outlined: 'text-emerald-700 hover:text-white border border-emerald-600 hover:bg-emerald-600 dark:text-emerald-400 dark:border-emerald-500 focus-visible:outline-emerald-500',
32
+ plain: 'text-emerald-700 hover:bg-current/10 active:bg-current/15 dark:text-emerald-400 focus-visible:outline-emerald-500',
30
33
  },
31
34
  warning: {
32
- default: 'text-white bg-amber-500 hover:bg-amber-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-amber-500 disabled:bg-amber-300 dark:disabled:bg-amber-900',
33
- outlined: 'text-amber-600 hover:text-white border border-amber-500 hover:bg-amber-500 dark:text-amber-400 dark:border-amber-500 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-amber-500 disabled:opacity-50',
34
- plain: 'text-amber-600 hover:bg-amber-50 dark:text-amber-400 dark:hover:bg-amber-950/40 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-amber-500 disabled:opacity-50',
35
- },
36
- };
37
- const LOADER_TEXT_CLASS = {
38
- primary: {
39
- default: 'text-white',
40
- outlined: 'text-[var(--ui-primary-text)]',
41
- plain: 'text-[var(--ui-primary-text)]',
42
- },
43
- danger: {
44
- default: 'text-white',
45
- outlined: 'text-[var(--ui-danger-text)]',
46
- plain: 'text-[var(--ui-danger-text)]',
47
- },
48
- secondary: {
49
- default: 'text-gray-700 dark:text-white',
50
- outlined: 'text-gray-700 dark:text-gray-200',
51
- plain: 'text-gray-700 dark:text-gray-200',
52
- },
53
- success: {
54
- default: 'text-white',
55
- outlined: 'text-emerald-600 dark:text-emerald-400',
56
- plain: 'text-emerald-600 dark:text-emerald-400',
57
- },
58
- warning: {
59
- default: 'text-white',
60
- outlined: 'text-amber-600 dark:text-amber-400',
61
- plain: 'text-amber-600 dark:text-amber-400',
35
+ default: 'text-white bg-amber-500 hover:bg-amber-600 focus-visible:outline-amber-500',
36
+ outlined: 'text-amber-700 hover:text-white border border-amber-500 hover:bg-amber-500 dark:text-amber-400 dark:border-amber-500 focus-visible:outline-amber-500',
37
+ plain: 'text-amber-700 hover:bg-current/10 active:bg-current/15 dark:text-amber-400 focus-visible:outline-amber-500',
62
38
  },
63
39
  };
64
40
  const SIZE_CLASSES = {
@@ -78,22 +54,32 @@ const LOADER_SIZE = {
78
54
  };
79
55
  /**
80
56
  * Base shared tailwind classes.
57
+ *
58
+ * Disabled styling is keyed off both the native `disabled` attribute and
59
+ * `aria-disabled`, so non-button elements rendered via `as` look disabled too.
81
60
  */
82
61
  const BASE_BTN_CLASS = 'font-medium inline-flex items-center justify-center shrink-0 cursor-pointer select-none ' +
83
- 'disabled:cursor-not-allowed disabled:pointer-events-none disabled:opacity-75 ' +
84
- 'active:scale-[0.98] transition-all duration-150 ease-out focus:outline-none';
62
+ 'transition-[color,background-color,border-color,box-shadow,opacity,transform] duration-150 ease-out ' +
63
+ 'active:scale-[0.98] focus:outline-none ' +
64
+ 'disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none ' +
65
+ 'aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-disabled:shadow-none';
85
66
  const Button = forwardRef(({ as, type, ...props }, ref) => {
86
- var _a, _b, _c, _d;
87
67
  const { className = '', children, theme = 'primary', variant = 'default', size = 'md', leftIcon, rightIcon, fullWidth = false, loading = false, loadingText = '', rounded = false, disabled, iconOnly = false, noOutlineOnFocus = false, active, onClick, ...restProps } = props;
88
68
  const Component = as || 'button';
89
69
  const isNativeButton = Component === 'button';
70
+ // Clean invalid props when not rendering a real button
71
+ const { type: _ignoreType, disabled: _ignoreDisabled, role, tabIndex, onKeyDown, onKeyUp, ...domProps } = restProps;
72
+ const ariaLabel = domProps['aria-label'];
73
+ const ariaLabelledBy = domProps['aria-labelledby'];
90
74
  // Accessibility guard for icon-only buttons
91
- if (iconOnly && !restProps['aria-label']) {
92
- console.warn('[ui] <Button iconOnly> requires aria-label for accessibility.');
93
- }
75
+ useEffect(() => {
76
+ if (iconOnly && !ariaLabel && !ariaLabelledBy) {
77
+ console.warn('[ui] <Button iconOnly> requires aria-label or aria-labelledby for accessibility.');
78
+ }
79
+ }, [iconOnly, ariaLabel, ariaLabelledBy]);
94
80
  const resolvedDisabled = Boolean(disabled || loading);
95
- // Clean invalid props when not rendering a real button
96
- const { type: _ignoreType, disabled: _ignoreDisabled, ...cleanRest } = restProps;
81
+ // Links (`href`, or `to` for router Link components) keep their native semantics.
82
+ const isLink = !isNativeButton && (domProps.href != null || domProps.to != null);
97
83
  const handleClick = (e) => {
98
84
  if (resolvedDisabled) {
99
85
  e.preventDefault();
@@ -102,31 +88,73 @@ const Button = forwardRef(({ as, type, ...props }, ref) => {
102
88
  }
103
89
  onClick === null || onClick === void 0 ? void 0 : onClick(e);
104
90
  };
91
+ // Mirror native <button> keyboard activation for non-button elements:
92
+ // Enter activates on keydown, Space on keyup (and must not scroll the page).
93
+ const handleKeyDown = (e) => {
94
+ onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
95
+ if (e.defaultPrevented || e.target !== e.currentTarget)
96
+ return;
97
+ if (e.key === 'Enter') {
98
+ e.preventDefault();
99
+ e.currentTarget.click();
100
+ }
101
+ else if (e.key === ' ') {
102
+ e.preventDefault();
103
+ }
104
+ };
105
+ const handleKeyUp = (e) => {
106
+ onKeyUp === null || onKeyUp === void 0 ? void 0 : onKeyUp(e);
107
+ if (e.defaultPrevented || e.target !== e.currentTarget)
108
+ return;
109
+ if (e.key === ' ') {
110
+ e.preventDefault();
111
+ e.currentTarget.click();
112
+ }
113
+ };
105
114
  const elementProps = isNativeButton
106
115
  ? {
107
116
  type: type !== null && type !== void 0 ? type : 'button',
108
117
  disabled: resolvedDisabled,
118
+ role,
119
+ tabIndex,
109
120
  onClick: handleClick,
121
+ onKeyDown,
122
+ onKeyUp,
110
123
  }
111
- : {
112
- role: (_a = cleanRest.role) !== null && _a !== void 0 ? _a : 'button',
113
- tabIndex: resolvedDisabled ? -1 : ((_b = cleanRest.tabIndex) !== null && _b !== void 0 ? _b : 0),
114
- 'aria-disabled': resolvedDisabled ? true : undefined,
115
- onClick: handleClick,
116
- };
124
+ : isLink
125
+ ? {
126
+ role,
127
+ tabIndex: resolvedDisabled ? -1 : tabIndex,
128
+ 'aria-disabled': resolvedDisabled ? true : undefined,
129
+ onClick: handleClick,
130
+ onKeyDown,
131
+ onKeyUp,
132
+ }
133
+ : {
134
+ role: role !== null && role !== void 0 ? role : 'button',
135
+ tabIndex: resolvedDisabled ? -1 : (tabIndex !== null && tabIndex !== void 0 ? tabIndex : 0),
136
+ 'aria-disabled': resolvedDisabled ? true : undefined,
137
+ onClick: handleClick,
138
+ onKeyDown: handleKeyDown,
139
+ onKeyUp: handleKeyUp,
140
+ };
117
141
  const sizeObj = SIZE_CLASSES[size] || SIZE_CLASSES.md;
118
142
  const classes = useMemo(() => {
119
143
  var _a;
120
- return buildClassName(BASE_BTN_CLASS, ((_a = THEMED_BTN_CLASS[theme]) === null || _a === void 0 ? void 0 : _a[variant]) || THEMED_BTN_CLASS.primary.default, iconOnly ? sizeObj.iconOnly : sizeObj.normal, !noOutlineOnFocus && 'focus-visible:ring-2 focus-visible:ring-offset-2', rounded && 'rounded-full', fullWidth && 'w-full', variant === 'default' && 'shadow-xs hover:shadow-none disabled:shadow-none', active && 'ring-2 ring-offset-2 ring-current', className);
144
+ return buildClassName(BASE_BTN_CLASS, ((_a = THEMED_BTN_CLASS[theme]) === null || _a === void 0 ? void 0 : _a[variant]) || THEMED_BTN_CLASS.primary.default, iconOnly ? sizeObj.iconOnly : sizeObj.normal,
145
+ // An outline (not a ring) so the offset gap stays transparent on any surface/mode.
146
+ !noOutlineOnFocus &&
147
+ 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid', rounded && 'rounded-full', fullWidth && 'w-full', variant === 'default' && 'shadow-xs hover:shadow-none', active && 'ring-2 ring-current', className);
121
148
  }, [theme, variant, sizeObj, iconOnly, noOutlineOnFocus, rounded, fullWidth, active, className]);
122
- const loaderIcon = (jsx(Loader, { "data-testid": "btn-loader-icon", size: LOADER_SIZE[size] || 'xs', className: buildClassName((_c = LOADER_TEXT_CLASS[theme]) === null || _c === void 0 ? void 0 : _c[variant]) }));
149
+ // The spinner and loading text inherit the button's text colour.
150
+ const loaderIcon = (jsx(Loader, { "data-testid": "btn-loader-icon", size: LOADER_SIZE[size] || 'xs', className: "text-current" }));
123
151
  /**
124
152
  * SPECIAL CASE: iconOnly + loading → show spinner only
125
153
  */
126
154
  if (loading && iconOnly) {
127
- return (jsx(Component, { ref: ref, className: classes, "aria-busy": "true", "aria-pressed": active !== undefined ? active : undefined, ...elementProps, ...cleanRest, children: loaderIcon }));
155
+ return (jsx(Component, { ref: ref, className: classes, "aria-busy": "true", "aria-pressed": active !== undefined ? active : undefined, ...domProps, ...elementProps, children: loaderIcon }));
128
156
  }
129
- return (jsx(Component, { ref: ref, className: classes, "aria-busy": loading ? 'true' : undefined, "aria-pressed": active !== undefined ? active : undefined, ...elementProps, ...cleanRest, children: loading ? (jsxs("span", { className: "inline-flex items-center gap-2", "aria-live": "polite", children: [loaderIcon, loadingText ? (jsx(TextContent, { className: buildClassName((_d = LOADER_TEXT_CLASS[theme]) === null || _d === void 0 ? void 0 : _d[variant]), children: loadingText })) : (children)] })) : (jsxs(Fragment, { children: [leftIcon && jsx("span", { className: "shrink-0 inline-flex items-center", children: leftIcon }), children, rightIcon && jsx("span", { className: "shrink-0 inline-flex items-center", children: rightIcon })] })) }));
157
+ return (jsx(Component, { ref: ref, className: classes, "aria-busy": loading ? 'true' : undefined, "aria-pressed": active !== undefined ? active : undefined, ...domProps, ...elementProps, children: loading ? (jsxs("span", { className: "inline-flex items-center gap-2", "aria-live": "polite", children: [loaderIcon, loadingText ? (jsx(TextContent, { className: "text-current", children: loadingText })) : (children)] })) : (jsxs(Fragment, { children: [leftIcon && jsx("span", { className: "shrink-0 inline-flex items-center", children: leftIcon }), children, rightIcon && jsx("span", { className: "shrink-0 inline-flex items-center", children: rightIcon })] })) }));
130
158
  });
131
159
  Button.displayName = 'Button';
132
160
 
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sources":["../../../../../src/components/Button/Button.tsx"],"sourcesContent":["import React, { ElementType, forwardRef, useMemo } from 'react'\nimport { buildClassName } from '../../utils/build-classname'\nimport { Loader } from '../Loader'\nimport { TextContent } from '../TextContent'\nimport type { ButtonComponent, ButtonProps, ButtonSize, ThemedButtonClass } from './Button.types'\nimport type { PolymorphicRef } from '../common-type'\n\n/**\n * Tailwind CSS classes for theme + variant combinations.\n */\nconst THEMED_BTN_CLASS: ThemedButtonClass = {\n primary: {\n default:\n 'text-white bg-[var(--ui-primary)] hover:bg-[var(--ui-primary-hover)] focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-primary-ring)] disabled:bg-[var(--ui-primary-disabled)]',\n outlined:\n 'text-[var(--ui-primary-text)] hover:text-white border border-[var(--ui-primary)] hover:bg-[var(--ui-primary)] focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-primary-ring)] disabled:text-[var(--ui-primary-disabled)] disabled:border-[var(--ui-primary-disabled)]',\n plain:\n 'text-[var(--ui-primary-text)] hover:bg-blue-50/80 dark:hover:bg-blue-950/40 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-primary-ring)] disabled:text-[var(--ui-primary-disabled)]',\n },\n danger: {\n default:\n 'text-white bg-[var(--ui-danger)] hover:bg-[var(--ui-danger-hover)] focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-danger-ring)] disabled:bg-[var(--ui-danger-disabled)]',\n outlined:\n 'text-[var(--ui-danger-text)] hover:text-white border border-[var(--ui-danger)] hover:bg-[var(--ui-danger)] focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-danger-ring)] disabled:text-[var(--ui-danger-disabled)] disabled:border-[var(--ui-danger-disabled)]',\n plain:\n 'text-[var(--ui-danger-text)] hover:bg-red-50/80 dark:hover:bg-red-950/40 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-danger-ring)] disabled:text-[var(--ui-danger-disabled)]',\n },\n secondary: {\n default:\n 'text-gray-700 bg-white border border-[var(--ui-border)] hover:bg-gray-100 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:bg-gray-200 dark:disabled:bg-gray-700',\n outlined:\n 'text-gray-700 hover:text-white border border-[var(--ui-border)] hover:bg-gray-700 dark:text-gray-200 dark:hover:text-white dark:hover:bg-gray-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:text-gray-400 disabled:border-[var(--ui-border-muted)]',\n plain:\n 'text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-800 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--ui-focus-ring)] disabled:text-gray-400',\n },\n success: {\n default:\n 'text-white bg-emerald-600 hover:bg-emerald-700 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-emerald-500 disabled:bg-emerald-300 dark:disabled:bg-emerald-900',\n outlined:\n 'text-emerald-600 hover:text-white border border-emerald-600 hover:bg-emerald-600 dark:text-emerald-400 dark:border-emerald-500 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-emerald-500 disabled:opacity-50',\n plain:\n 'text-emerald-600 hover:bg-emerald-50 dark:text-emerald-400 dark:hover:bg-emerald-950/40 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-emerald-500 disabled:opacity-50',\n },\n warning: {\n default:\n 'text-white bg-amber-500 hover:bg-amber-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-amber-500 disabled:bg-amber-300 dark:disabled:bg-amber-900',\n outlined:\n 'text-amber-600 hover:text-white border border-amber-500 hover:bg-amber-500 dark:text-amber-400 dark:border-amber-500 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-amber-500 disabled:opacity-50',\n plain:\n 'text-amber-600 hover:bg-amber-50 dark:text-amber-400 dark:hover:bg-amber-950/40 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-amber-500 disabled:opacity-50',\n },\n}\n\nconst LOADER_TEXT_CLASS: ThemedButtonClass = {\n primary: {\n default: 'text-white',\n outlined: 'text-[var(--ui-primary-text)]',\n plain: 'text-[var(--ui-primary-text)]',\n },\n danger: {\n default: 'text-white',\n outlined: 'text-[var(--ui-danger-text)]',\n plain: 'text-[var(--ui-danger-text)]',\n },\n secondary: {\n default: 'text-gray-700 dark:text-white',\n outlined: 'text-gray-700 dark:text-gray-200',\n plain: 'text-gray-700 dark:text-gray-200',\n },\n success: {\n default: 'text-white',\n outlined: 'text-emerald-600 dark:text-emerald-400',\n plain: 'text-emerald-600 dark:text-emerald-400',\n },\n warning: {\n default: 'text-white',\n outlined: 'text-amber-600 dark:text-amber-400',\n plain: 'text-amber-600 dark:text-amber-400',\n },\n}\n\nconst SIZE_CLASSES: Record<ButtonSize, { normal: string; iconOnly: string }> = {\n xs: { normal: 'h-7 px-2.5 rounded-sm gap-1 text-xs', iconOnly: 'h-7 w-7 p-1 rounded-sm text-xs' },\n sm: { normal: 'h-8 px-3 rounded gap-1.5 text-sm', iconOnly: 'h-8 w-8 p-1.5 rounded text-sm' },\n md: { normal: 'h-9 px-4 rounded-md gap-2 text-sm', iconOnly: 'h-9 w-9 p-2 rounded-md text-sm' },\n lg: {\n normal: 'h-10 px-5 rounded-lg gap-2 text-base',\n iconOnly: 'h-10 w-10 p-2.5 rounded-lg text-base',\n },\n}\n\nconst LOADER_SIZE: Record<ButtonSize, 'xs' | 'sm'> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'sm',\n}\n\n/**\n * Base shared tailwind classes.\n */\nconst BASE_BTN_CLASS =\n 'font-medium inline-flex items-center justify-center shrink-0 cursor-pointer select-none ' +\n 'disabled:cursor-not-allowed disabled:pointer-events-none disabled:opacity-75 ' +\n 'active:scale-[0.98] transition-all duration-150 ease-out focus:outline-none'\n\nexport const Button = forwardRef(\n <C extends ElementType = 'button'>(\n { as, type, ...props }: ButtonProps<C>,\n ref: PolymorphicRef<C>,\n ) => {\n const {\n className = '',\n children,\n theme = 'primary',\n variant = 'default',\n size = 'md',\n leftIcon,\n rightIcon,\n fullWidth = false,\n loading = false,\n loadingText = '',\n rounded = false,\n disabled,\n iconOnly = false,\n noOutlineOnFocus = false,\n active,\n onClick,\n ...restProps\n } = props\n\n const Component = as || 'button'\n const isNativeButton = Component === 'button'\n\n // Accessibility guard for icon-only buttons\n if (iconOnly && !(restProps as Record<string, unknown>)['aria-label']) {\n console.warn('[ui] <Button iconOnly> requires aria-label for accessibility.')\n }\n\n const resolvedDisabled = Boolean(disabled || loading)\n\n // Clean invalid props when not rendering a real button\n const { type: _ignoreType, disabled: _ignoreDisabled, ...cleanRest } = restProps\n\n const handleClick = (e: React.MouseEvent<any>) => {\n if (resolvedDisabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n onClick?.(e)\n }\n\n const elementProps = isNativeButton\n ? {\n type: type ?? 'button',\n disabled: resolvedDisabled,\n onClick: handleClick,\n }\n : {\n role: cleanRest.role ?? 'button',\n tabIndex: resolvedDisabled ? -1 : (cleanRest.tabIndex ?? 0),\n 'aria-disabled': resolvedDisabled ? true : undefined,\n onClick: handleClick,\n }\n\n const sizeObj = SIZE_CLASSES[size] || SIZE_CLASSES.md\n\n const classes = useMemo(\n () =>\n buildClassName(\n BASE_BTN_CLASS,\n THEMED_BTN_CLASS[theme]?.[variant] || THEMED_BTN_CLASS.primary.default,\n iconOnly ? sizeObj.iconOnly : sizeObj.normal,\n !noOutlineOnFocus && 'focus-visible:ring-2 focus-visible:ring-offset-2',\n rounded && 'rounded-full',\n fullWidth && 'w-full',\n variant === 'default' && 'shadow-xs hover:shadow-none disabled:shadow-none',\n active && 'ring-2 ring-offset-2 ring-current',\n className,\n ),\n [theme, variant, sizeObj, iconOnly, noOutlineOnFocus, rounded, fullWidth, active, className],\n )\n\n const loaderIcon = (\n <Loader\n data-testid=\"btn-loader-icon\"\n size={LOADER_SIZE[size] || 'xs'}\n className={buildClassName(LOADER_TEXT_CLASS[theme]?.[variant])}\n />\n )\n\n /**\n * SPECIAL CASE: iconOnly + loading → show spinner only\n */\n if (loading && iconOnly) {\n return (\n <Component\n ref={ref}\n className={classes}\n aria-busy=\"true\"\n aria-pressed={active !== undefined ? active : undefined}\n {...elementProps}\n {...cleanRest}\n >\n {loaderIcon}\n </Component>\n )\n }\n\n return (\n <Component\n ref={ref}\n className={classes}\n aria-busy={loading ? 'true' : undefined}\n aria-pressed={active !== undefined ? active : undefined}\n {...elementProps}\n {...cleanRest}\n >\n {loading ? (\n <span className=\"inline-flex items-center gap-2\" aria-live=\"polite\">\n {loaderIcon}\n {loadingText ? (\n <TextContent className={buildClassName(LOADER_TEXT_CLASS[theme]?.[variant])}>\n {loadingText}\n </TextContent>\n ) : (\n children\n )}\n </span>\n ) : (\n <>\n {leftIcon && <span className=\"shrink-0 inline-flex items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"shrink-0 inline-flex items-center\">{rightIcon}</span>}\n </>\n )}\n </Component>\n )\n },\n) as ButtonComponent\n\nButton.displayName = 'Button'\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"Button.js","sources":["../../../../../src/components/Button/Button.tsx"],"sourcesContent":["import React, { ElementType, forwardRef, useEffect, useMemo } from 'react'\nimport { buildClassName } from '../../utils/build-classname'\nimport { Loader } from '../Loader'\nimport { TextContent } from '../TextContent'\nimport type { ButtonComponent, ButtonProps, ButtonSize, ThemedButtonClass } from './Button.types'\nimport type { PolymorphicRef } from '../common-type'\n\n/**\n * Tailwind CSS classes for theme + variant combinations.\n *\n * Only colours live here. Focus outline width/offset and disabled styling are\n * applied uniformly in the component so they can be toggled in one place.\n */\nconst THEMED_BTN_CLASS: ThemedButtonClass = {\n primary: {\n default:\n 'text-white bg-[var(--ui-primary)] hover:bg-[var(--ui-primary-hover)] focus-visible:outline-[var(--ui-primary-ring)]',\n outlined:\n 'text-[var(--ui-primary-text)] hover:text-white border border-[var(--ui-primary)] hover:bg-[var(--ui-primary)] focus-visible:outline-[var(--ui-primary-ring)]',\n plain:\n 'text-[var(--ui-primary-text)] hover:bg-current/10 active:bg-current/15 focus-visible:outline-[var(--ui-primary-ring)]',\n },\n danger: {\n default:\n 'text-white bg-[var(--ui-danger)] hover:bg-[var(--ui-danger-hover)] focus-visible:outline-[var(--ui-danger-ring)]',\n outlined:\n 'text-[var(--ui-danger-text)] hover:text-white border border-[var(--ui-danger)] hover:bg-[var(--ui-danger)] focus-visible:outline-[var(--ui-danger-ring)]',\n plain:\n 'text-[var(--ui-danger-text)] hover:bg-current/10 active:bg-current/15 focus-visible:outline-[var(--ui-danger-ring)]',\n },\n secondary: {\n default:\n 'text-gray-700 bg-white border border-[var(--ui-border)] hover:bg-gray-100 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700 focus-visible:outline-[var(--ui-focus-ring)]',\n outlined:\n 'text-gray-700 hover:text-white border border-[var(--ui-border)] hover:bg-gray-700 dark:text-gray-200 dark:hover:text-white dark:hover:bg-gray-600 focus-visible:outline-[var(--ui-focus-ring)]',\n plain:\n 'text-gray-700 hover:bg-current/10 active:bg-current/15 dark:text-gray-200 focus-visible:outline-[var(--ui-focus-ring)]',\n },\n success: {\n default: 'text-white bg-emerald-600 hover:bg-emerald-700 focus-visible:outline-emerald-500',\n outlined:\n 'text-emerald-700 hover:text-white border border-emerald-600 hover:bg-emerald-600 dark:text-emerald-400 dark:border-emerald-500 focus-visible:outline-emerald-500',\n plain:\n 'text-emerald-700 hover:bg-current/10 active:bg-current/15 dark:text-emerald-400 focus-visible:outline-emerald-500',\n },\n warning: {\n default: 'text-white bg-amber-500 hover:bg-amber-600 focus-visible:outline-amber-500',\n outlined:\n 'text-amber-700 hover:text-white border border-amber-500 hover:bg-amber-500 dark:text-amber-400 dark:border-amber-500 focus-visible:outline-amber-500',\n plain:\n 'text-amber-700 hover:bg-current/10 active:bg-current/15 dark:text-amber-400 focus-visible:outline-amber-500',\n },\n}\n\nconst SIZE_CLASSES: Record<ButtonSize, { normal: string; iconOnly: string }> = {\n xs: { normal: 'h-7 px-2.5 rounded-sm gap-1 text-xs', iconOnly: 'h-7 w-7 p-1 rounded-sm text-xs' },\n sm: { normal: 'h-8 px-3 rounded gap-1.5 text-sm', iconOnly: 'h-8 w-8 p-1.5 rounded text-sm' },\n md: { normal: 'h-9 px-4 rounded-md gap-2 text-sm', iconOnly: 'h-9 w-9 p-2 rounded-md text-sm' },\n lg: {\n normal: 'h-10 px-5 rounded-lg gap-2 text-base',\n iconOnly: 'h-10 w-10 p-2.5 rounded-lg text-base',\n },\n}\n\nconst LOADER_SIZE: Record<ButtonSize, 'xs' | 'sm'> = {\n xs: 'xs',\n sm: 'xs',\n md: 'sm',\n lg: 'sm',\n}\n\n/**\n * Base shared tailwind classes.\n *\n * Disabled styling is keyed off both the native `disabled` attribute and\n * `aria-disabled`, so non-button elements rendered via `as` look disabled too.\n */\nconst BASE_BTN_CLASS =\n 'font-medium inline-flex items-center justify-center shrink-0 cursor-pointer select-none ' +\n 'transition-[color,background-color,border-color,box-shadow,opacity,transform] duration-150 ease-out ' +\n 'active:scale-[0.98] focus:outline-none ' +\n 'disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none ' +\n 'aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-disabled:shadow-none'\n\nexport const Button = forwardRef(\n <C extends ElementType = 'button'>(\n { as, type, ...props }: ButtonProps<C>,\n ref: PolymorphicRef<C>,\n ) => {\n const {\n className = '',\n children,\n theme = 'primary',\n variant = 'default',\n size = 'md',\n leftIcon,\n rightIcon,\n fullWidth = false,\n loading = false,\n loadingText = '',\n rounded = false,\n disabled,\n iconOnly = false,\n noOutlineOnFocus = false,\n active,\n onClick,\n ...restProps\n } = props\n\n const Component = as || 'button'\n const isNativeButton = Component === 'button'\n\n // Clean invalid props when not rendering a real button\n const {\n type: _ignoreType,\n disabled: _ignoreDisabled,\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n ...domProps\n } = restProps as Record<string, any>\n\n const ariaLabel = domProps['aria-label']\n const ariaLabelledBy = domProps['aria-labelledby']\n\n // Accessibility guard for icon-only buttons\n useEffect(() => {\n if (iconOnly && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n '[ui] <Button iconOnly> requires aria-label or aria-labelledby for accessibility.',\n )\n }\n }, [iconOnly, ariaLabel, ariaLabelledBy])\n\n const resolvedDisabled = Boolean(disabled || loading)\n\n // Links (`href`, or `to` for router Link components) keep their native semantics.\n const isLink = !isNativeButton && (domProps.href != null || domProps.to != null)\n\n const handleClick = (e: React.MouseEvent<any>) => {\n if (resolvedDisabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n onClick?.(e)\n }\n\n // Mirror native <button> keyboard activation for non-button elements:\n // Enter activates on keydown, Space on keyup (and must not scroll the page).\n const handleKeyDown = (e: React.KeyboardEvent<any>) => {\n onKeyDown?.(e)\n if (e.defaultPrevented || e.target !== e.currentTarget) return\n if (e.key === 'Enter') {\n e.preventDefault()\n e.currentTarget.click()\n } else if (e.key === ' ') {\n e.preventDefault()\n }\n }\n\n const handleKeyUp = (e: React.KeyboardEvent<any>) => {\n onKeyUp?.(e)\n if (e.defaultPrevented || e.target !== e.currentTarget) return\n if (e.key === ' ') {\n e.preventDefault()\n e.currentTarget.click()\n }\n }\n\n const elementProps = isNativeButton\n ? {\n type: type ?? 'button',\n disabled: resolvedDisabled,\n role,\n tabIndex,\n onClick: handleClick,\n onKeyDown,\n onKeyUp,\n }\n : isLink\n ? {\n role,\n tabIndex: resolvedDisabled ? -1 : tabIndex,\n 'aria-disabled': resolvedDisabled ? true : undefined,\n onClick: handleClick,\n onKeyDown,\n onKeyUp,\n }\n : {\n role: role ?? 'button',\n tabIndex: resolvedDisabled ? -1 : (tabIndex ?? 0),\n 'aria-disabled': resolvedDisabled ? true : undefined,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onKeyUp: handleKeyUp,\n }\n\n const sizeObj = SIZE_CLASSES[size] || SIZE_CLASSES.md\n\n const classes = useMemo(\n () =>\n buildClassName(\n BASE_BTN_CLASS,\n THEMED_BTN_CLASS[theme]?.[variant] || THEMED_BTN_CLASS.primary.default,\n iconOnly ? sizeObj.iconOnly : sizeObj.normal,\n // An outline (not a ring) so the offset gap stays transparent on any surface/mode.\n !noOutlineOnFocus &&\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid',\n rounded && 'rounded-full',\n fullWidth && 'w-full',\n variant === 'default' && 'shadow-xs hover:shadow-none',\n active && 'ring-2 ring-current',\n className,\n ),\n [theme, variant, sizeObj, iconOnly, noOutlineOnFocus, rounded, fullWidth, active, className],\n )\n\n // The spinner and loading text inherit the button's text colour.\n const loaderIcon = (\n <Loader\n data-testid=\"btn-loader-icon\"\n size={LOADER_SIZE[size] || 'xs'}\n className=\"text-current\"\n />\n )\n\n /**\n * SPECIAL CASE: iconOnly + loading → show spinner only\n */\n if (loading && iconOnly) {\n return (\n <Component\n ref={ref}\n className={classes}\n aria-busy=\"true\"\n aria-pressed={active !== undefined ? active : undefined}\n {...domProps}\n {...elementProps}\n >\n {loaderIcon}\n </Component>\n )\n }\n\n return (\n <Component\n ref={ref}\n className={classes}\n aria-busy={loading ? 'true' : undefined}\n aria-pressed={active !== undefined ? active : undefined}\n {...domProps}\n {...elementProps}\n >\n {loading ? (\n <span className=\"inline-flex items-center gap-2\" aria-live=\"polite\">\n {loaderIcon}\n {loadingText ? (\n <TextContent className=\"text-current\">{loadingText}</TextContent>\n ) : (\n children\n )}\n </span>\n ) : (\n <>\n {leftIcon && <span className=\"shrink-0 inline-flex items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"shrink-0 inline-flex items-center\">{rightIcon}</span>}\n </>\n )}\n </Component>\n )\n },\n) as ButtonComponent\n\nButton.displayName = 'Button'\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -132,7 +132,7 @@ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination,
132
132
  }), isInlineMode && (jsx(TableCell, { align: "right", className: buildClassName(densityCellClass, striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40'), onClick: (e) => e.stopPropagation(), children: jsx("div", { className: buildClassName('opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity duration-150 flex items-center justify-end gap-1.5', rowHoverActionClass), "data-testid": `row-hover-actions-${key}`, children: renderActionsContent(item, idx) }) })), isOverlayMode && (jsx(TableCell, { align: "right", style: { padding: 0, width: 0, minWidth: 0, maxWidth: 0 }, className: "sticky right-0 z-20 !p-0 !pr-0 !pl-0 !py-0 w-0 max-w-0 min-w-0 border-0 overflow-visible text-right", onClick: (e) => e.stopPropagation(), children: jsx("div", { className: buildClassName('absolute right-0 top-0 bottom-0 h-full opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity duration-150 flex items-center justify-end gap-1 px-3 z-30 pointer-events-none group-hover:pointer-events-auto whitespace-nowrap', striped && idx % 2 === 1
133
133
  ? 'bg-gray-100 dark:bg-gray-800'
134
134
  : 'bg-white group-hover:bg-gray-50 dark:bg-gray-900 dark:group-hover:bg-gray-800', rowHoverActionClass), "data-testid": `row-hover-actions-${key}`, children: renderActionsContent(item, idx) }) }))] }, key));
135
- })) }), footerRow && jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsx("div", { className: buildClassName(stickyPagination && 'sticky bottom-0 z-20 bg-white dark:bg-gray-800', paginationClass, paginationContainerClass), children: renderPagination ? (renderPagination(pagination, setPagination)) : (jsx(Pagination, { ...pagination, ...paginationProps, className: buildClassName('rounded-t-none rounded-b-lg border border-[var(--ui-border)]', stickyPagination && 'sticky bottom-0 z-20 bg-white dark:bg-gray-800', paginationProps === null || paginationProps === void 0 ? void 0 : paginationProps.className), onChange: setPagination })) }))] }));
135
+ })) }), footerRow && jsx(TableFoot, { children: footerRow })] }) }), pagination && (jsx("div", { className: buildClassName(stickyPagination && 'sticky bottom-0 z-20', paginationContainerClass), children: renderPagination ? (renderPagination(pagination, setPagination)) : (jsx(Pagination, { ...pagination, ...paginationProps, className: buildClassName('rounded-t-none rounded-b-lg border border-[var(--ui-border)] bg-white dark:bg-gray-800', paginationClass, paginationProps === null || paginationProps === void 0 ? void 0 : paginationProps.className), onChange: setPagination })) }))] }));
136
136
  }
137
137
  DataTable.displayName = 'DataTable';
138
138
 
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.js","sources":["../../../../../src/components/DataTable/DataTable.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n EmptyTableRow,\n Table,\n TableBody,\n TableCell,\n TableFoot,\n TableHead,\n TableHeaderCell,\n TableRow,\n} from '../Table'\nimport { buildClassName } from '../../utils/build-classname'\nimport type {\n DataTableProps,\n DataTableColumn,\n DataTableDensity,\n Sorting,\n SortQuery,\n} from './DataTable.types'\nimport { TextContent } from '../TextContent'\nimport { Pagination } from '../Pagination'\nimport { Checkbox } from '../Checkbox'\nimport { Button } from '../Button'\nimport { get } from '../../utils/get'\nimport { updateSortQuery, useRowSelection } from './DataTable.utils'\nimport { getSortIcon } from './DataTable.icons'\n\nconst OVERFLOW_REGEX = /\\boverflow-(x-|y-)?(auto|hidden|scroll|visible|clip)\\b/\nconst NOOP = () => {}\n\nconst DENSITY_CELL_CLASS: Record<DataTableDensity, string> = {\n compact: 'px-2 py-1.5',\n default: '',\n spacious: 'px-4 py-4',\n}\n\nconst autoSortItems = <T,>(items: T[], column: DataTableColumn<T>, sort: Sorting): T[] => {\n const path = column.name\n return [...items].sort((a, b) => {\n const valueA = get(a as Record<string, any>, path)\n const valueB = get(b as Record<string, any>, path)\n\n if (column.type === 'number') {\n const nA = Number(valueA)\n const nB = Number(valueB)\n return sort === 'asc' || sort === '1' ? nA - nB : nB - nA\n }\n\n if (column.type === 'date') {\n const dA = new Date(valueA).getTime()\n const dB = new Date(valueB).getTime()\n return sort === 'asc' || sort === '1' ? dA - dB : dB - dA\n }\n\n const sA = String(valueA).toLowerCase()\n const sB = String(valueB).toLowerCase()\n if (sA < sB) return sort === 'asc' || sort === '1' ? -1 : 1\n if (sA > sB) return sort === 'asc' || sort === '1' ? 1 : -1\n return 0\n })\n}\n\nexport function DataTable<T extends Record<string, any> = Record<string, any>>({\n items,\n columns,\n sorting = {},\n onSort,\n loading,\n pagination,\n setPagination = NOOP,\n emptyMessage = 'No data found',\n containerClass = '',\n wrapperClass = '',\n tableClass = '',\n headClass = '',\n footerRow,\n rowKey = 'id',\n onRowClick,\n rowClass,\n density = 'default',\n striped = false,\n layout = 'auto',\n selectable = false,\n selectedRowKeys,\n defaultSelectedRowKeys,\n onSelectionChange,\n isRowSelectable,\n stickyHeader = true,\n stickyPagination = true,\n rowHoverActions,\n renderRowHoverActions,\n rowHoverActionHeader,\n rowHoverActionMode = 'overlay',\n rowHoverActionClass,\n paginationClass,\n paginationContainerClass,\n paginationProps,\n renderPagination,\n}: DataTableProps<T>) {\n const [internalSortingState, setInternalSortingState] = useState<SortQuery>({})\n\n const handleSort = useCallback(\n (column: DataTableColumn<T>) => {\n if (!column.sortable) return\n if (onSort) {\n onSort(column)\n } else {\n setInternalSortingState((prev) => updateSortQuery(prev, column.name, column.type))\n }\n },\n [onSort],\n )\n\n const activeSorting = useMemo(\n () => ({ ...sorting, ...internalSortingState }),\n [sorting, internalSortingState],\n )\n\n const sortedItems: T[] = useMemo(() => {\n if (onSort) return items\n const activeSortKey = Object.keys(activeSorting)[0]\n if (!activeSortKey) return items\n const column = columns.find((c) => c.name === activeSortKey)\n if (!column) return items\n return autoSortItems(items, column, activeSorting[activeSortKey])\n }, [items, columns, onSort, activeSorting])\n\n const getKey = useCallback(\n (item: T, idx: number): string | number =>\n typeof rowKey === 'function' ? rowKey(item) : ((item as any)[rowKey] ?? idx),\n [rowKey],\n )\n\n const getRowClass = useCallback(\n (item: T, idx: number): string =>\n typeof rowClass === 'function' ? rowClass(item, idx) : rowClass || '',\n [rowClass],\n )\n\n const getCellClass = useCallback(\n (column: DataTableColumn<T>, item: T): string =>\n typeof column.cellClass === 'function' ? column.cellClass(item) : column.cellClass || '',\n [],\n )\n\n const { isSelected, toggleRow, toggleAll, allSelected, someSelected } = useRowSelection({\n items: sortedItems,\n getKey,\n selectedRowKeys,\n defaultSelectedRowKeys,\n onSelectionChange,\n isRowSelectable,\n })\n\n const hasRowHoverActions = Boolean(rowHoverActions || renderRowHoverActions)\n const isInlineMode = hasRowHoverActions && rowHoverActionMode === 'inline'\n const isOverlayMode = hasRowHoverActions && rowHoverActionMode !== 'inline'\n\n const densityCellClass = DENSITY_CELL_CLASS[density]\n const colSize = columns.length + (selectable ? 1 : 0) + (isInlineMode ? 1 : 0)\n const wrapperHasOverflow = OVERFLOW_REGEX.test(wrapperClass)\n\n const renderActionsContent = useCallback(\n (item: T, idx: number) => {\n if (renderRowHoverActions) return renderRowHoverActions(item, idx)\n if (!rowHoverActions) return null\n return rowHoverActions(item, idx).map((act) => {\n const isDisabled = typeof act.disabled === 'function' ? act.disabled(item) : act.disabled\n const isIconOnly = Boolean(act.icon && !act.label)\n\n return (\n <Button\n key={act.id}\n size=\"xs\"\n theme={act.theme || 'secondary'}\n variant={act.variant || 'plain'}\n disabled={isDisabled}\n title={act.title || (typeof act.label === 'string' ? act.label : undefined)}\n className={buildClassName(\n isIconOnly\n ? 'p-1.5 rounded-full hover:bg-black/5 dark:hover:bg-white/10'\n : 'px-2 py-1',\n act.className,\n )}\n onClick={(e) => {\n e.stopPropagation()\n act.onClick(item, idx, e)\n }}\n >\n {act.icon && <span className=\"shrink-0\">{act.icon}</span>}\n {act.label && <span>{act.label}</span>}\n </Button>\n )\n })\n },\n [renderRowHoverActions, rowHoverActions],\n )\n\n return (\n <div className={buildClassName('w-full rounded-lg relative', containerClass)}>\n <div\n className={buildClassName(\n !wrapperHasOverflow && 'overflow-x-auto',\n 'rounded-lg border border-[var(--ui-border)]',\n wrapperClass,\n pagination && 'rounded-b-none border-b-0',\n )}\n >\n <Table\n className={buildClassName('relative w-full max-w-full h-fit', tableClass)}\n layout={layout}\n >\n <TableHead className={headClass}>\n {selectable && (\n <TableHeaderCell\n className={buildClassName(\n 'bg-gray-50 dark:bg-gray-800 w-px',\n densityCellClass,\n stickyHeader && 'sticky top-0 z-20 shadow-[0_1px_2px_rgba(0,0,0,0.06)]',\n )}\n >\n <Checkbox\n aria-label=\"Select all rows\"\n checked={allSelected}\n ref={(el) => {\n if (el) el.indeterminate = someSelected\n }}\n onChange={toggleAll}\n />\n </TableHeaderCell>\n )}\n {columns.map((column) => {\n const sortState = activeSorting[column.name]\n const ariaSortValue = column.sortable\n ? sortState === 'asc' || sortState === '1'\n ? 'ascending'\n : sortState === 'desc' || sortState === '-1'\n ? 'descending'\n : 'none'\n : undefined\n\n return (\n <TableHeaderCell\n key={column.name}\n align={column.headerAlign}\n style={{ width: column.width || 'auto' }}\n aria-sort={ariaSortValue}\n className={buildClassName(\n 'bg-gray-50 dark:bg-gray-800',\n densityCellClass,\n stickyHeader && 'sticky top-0 z-20 shadow-[0_1px_2px_rgba(0,0,0,0.06)]',\n column.sticky === 'left' &&\n 'sticky left-0 z-30 shadow-[2px_0_6px_rgba(0,0,0,0.06)]',\n column.sticky === 'right' &&\n 'sticky right-0 z-30 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]',\n column.headerClass,\n )}\n >\n <TextContent\n role={column.sortable ? 'button' : undefined}\n tabIndex={column.sortable ? 0 : undefined}\n aria-label={column.sortable ? `Sort by ${column.label}` : undefined}\n className={buildClassName(\n 'group',\n column.sortable &&\n 'inline-flex items-center gap-2 cursor-pointer select-none focus:outline-none focus-visible:ring-1 focus-visible:ring-blue-500 rounded',\n )}\n onClick={() => handleSort(column)}\n onKeyDown={(e) => {\n if (column.sortable && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault()\n handleSort(column)\n }\n }}\n >\n <TextContent className=\"shrink-0\">{column.label}</TextContent>\n {column.sortable ? getSortIcon(activeSorting[column.name]) : null}\n </TextContent>\n </TableHeaderCell>\n )\n })}\n {isInlineMode && (\n <TableHeaderCell\n align=\"right\"\n className={buildClassName(\n 'bg-gray-50 dark:bg-gray-800 text-right w-px',\n densityCellClass,\n stickyHeader && 'sticky top-0 z-20 shadow-[0_1px_2px_rgba(0,0,0,0.06)]',\n )}\n >\n {rowHoverActionHeader ?? ''}\n </TableHeaderCell>\n )}\n {isOverlayMode && (\n <TableHeaderCell\n align=\"right\"\n style={{ padding: 0, width: 0, minWidth: 0, maxWidth: 0 }}\n className={buildClassName(\n 'sticky right-0 z-20 !p-0 !pr-0 !pl-0 !py-0 w-0 max-w-0 min-w-0 border-0 bg-gray-50 dark:bg-gray-800',\n stickyHeader && 'top-0',\n )}\n >\n {null}\n </TableHeaderCell>\n )}\n </TableHead>\n\n <TableBody loading={loading} colSize={colSize} rowSize={pagination?.limit || 5}>\n {!loading && sortedItems.length === 0 ? (\n <EmptyTableRow colSpan={colSize}>{emptyMessage}</EmptyTableRow>\n ) : (\n sortedItems.map((item, idx) => {\n const key = getKey(item, idx)\n const rowSelectable = !isRowSelectable || isRowSelectable(item)\n\n return (\n <TableRow\n key={key}\n className={buildClassName(\n 'group',\n onRowClick && 'cursor-pointer',\n striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40',\n getRowClass(item, idx),\n )}\n onClick={onRowClick ? () => onRowClick(item, idx) : undefined}\n >\n {selectable && (\n <TableCell\n className={buildClassName(\n densityCellClass,\n striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40',\n )}\n >\n <span onClick={(e) => e.stopPropagation()}>\n <Checkbox\n aria-label=\"Select row\"\n checked={isSelected(key)}\n disabled={!rowSelectable}\n onChange={() => toggleRow(key)}\n />\n </span>\n </TableCell>\n )}\n {columns.map((column) => (\n <TableCell\n key={column.name}\n align={column.align}\n className={buildClassName(\n densityCellClass,\n striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40',\n column.sticky === 'left' &&\n 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]',\n column.sticky === 'right' &&\n 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]',\n getCellClass(column, item),\n )}\n >\n {column.render\n ? column.render(item)\n : ((get(item, column.name) as any) ?? 'Not set')}\n </TableCell>\n ))}\n {isInlineMode && (\n <TableCell\n align=\"right\"\n className={buildClassName(\n densityCellClass,\n striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40',\n )}\n onClick={(e) => e.stopPropagation()}\n >\n <div\n className={buildClassName(\n 'opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity duration-150 flex items-center justify-end gap-1.5',\n rowHoverActionClass,\n )}\n data-testid={`row-hover-actions-${key}`}\n >\n {renderActionsContent(item, idx)}\n </div>\n </TableCell>\n )}\n {isOverlayMode && (\n <TableCell\n align=\"right\"\n style={{ padding: 0, width: 0, minWidth: 0, maxWidth: 0 }}\n className=\"sticky right-0 z-20 !p-0 !pr-0 !pl-0 !py-0 w-0 max-w-0 min-w-0 border-0 overflow-visible text-right\"\n onClick={(e) => e.stopPropagation()}\n >\n <div\n className={buildClassName(\n 'absolute right-0 top-0 bottom-0 h-full opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity duration-150 flex items-center justify-end gap-1 px-3 z-30 pointer-events-none group-hover:pointer-events-auto whitespace-nowrap',\n striped && idx % 2 === 1\n ? 'bg-gray-100 dark:bg-gray-800'\n : 'bg-white group-hover:bg-gray-50 dark:bg-gray-900 dark:group-hover:bg-gray-800',\n rowHoverActionClass,\n )}\n data-testid={`row-hover-actions-${key}`}\n >\n {renderActionsContent(item, idx)}\n </div>\n </TableCell>\n )}\n </TableRow>\n )\n })\n )}\n </TableBody>\n\n {footerRow && <TableFoot>{footerRow}</TableFoot>}\n </Table>\n </div>\n\n {pagination && (\n <div\n className={buildClassName(\n stickyPagination && 'sticky bottom-0 z-20 bg-white dark:bg-gray-800',\n paginationClass,\n paginationContainerClass,\n )}\n >\n {renderPagination ? (\n renderPagination(pagination, setPagination)\n ) : (\n <Pagination\n {...pagination}\n {...paginationProps}\n className={buildClassName(\n 'rounded-t-none rounded-b-lg border border-[var(--ui-border)]',\n stickyPagination && 'sticky bottom-0 z-20 bg-white dark:bg-gray-800',\n paginationProps?.className,\n )}\n onChange={setPagination}\n />\n )}\n </div>\n )}\n </div>\n )\n}\n\nDataTable.displayName = 'DataTable'\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"DataTable.js","sources":["../../../../../src/components/DataTable/DataTable.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n EmptyTableRow,\n Table,\n TableBody,\n TableCell,\n TableFoot,\n TableHead,\n TableHeaderCell,\n TableRow,\n} from '../Table'\nimport { buildClassName } from '../../utils/build-classname'\nimport type {\n DataTableProps,\n DataTableColumn,\n DataTableDensity,\n Sorting,\n SortQuery,\n} from './DataTable.types'\nimport { TextContent } from '../TextContent'\nimport { Pagination } from '../Pagination'\nimport { Checkbox } from '../Checkbox'\nimport { Button } from '../Button'\nimport { get } from '../../utils/get'\nimport { updateSortQuery, useRowSelection } from './DataTable.utils'\nimport { getSortIcon } from './DataTable.icons'\n\nconst OVERFLOW_REGEX = /\\boverflow-(x-|y-)?(auto|hidden|scroll|visible|clip)\\b/\nconst NOOP = () => {}\n\nconst DENSITY_CELL_CLASS: Record<DataTableDensity, string> = {\n compact: 'px-2 py-1.5',\n default: '',\n spacious: 'px-4 py-4',\n}\n\nconst autoSortItems = <T,>(items: T[], column: DataTableColumn<T>, sort: Sorting): T[] => {\n const path = column.name\n return [...items].sort((a, b) => {\n const valueA = get(a as Record<string, any>, path)\n const valueB = get(b as Record<string, any>, path)\n\n if (column.type === 'number') {\n const nA = Number(valueA)\n const nB = Number(valueB)\n return sort === 'asc' || sort === '1' ? nA - nB : nB - nA\n }\n\n if (column.type === 'date') {\n const dA = new Date(valueA).getTime()\n const dB = new Date(valueB).getTime()\n return sort === 'asc' || sort === '1' ? dA - dB : dB - dA\n }\n\n const sA = String(valueA).toLowerCase()\n const sB = String(valueB).toLowerCase()\n if (sA < sB) return sort === 'asc' || sort === '1' ? -1 : 1\n if (sA > sB) return sort === 'asc' || sort === '1' ? 1 : -1\n return 0\n })\n}\n\nexport function DataTable<T extends Record<string, any> = Record<string, any>>({\n items,\n columns,\n sorting = {},\n onSort,\n loading,\n pagination,\n setPagination = NOOP,\n emptyMessage = 'No data found',\n containerClass = '',\n wrapperClass = '',\n tableClass = '',\n headClass = '',\n footerRow,\n rowKey = 'id',\n onRowClick,\n rowClass,\n density = 'default',\n striped = false,\n layout = 'auto',\n selectable = false,\n selectedRowKeys,\n defaultSelectedRowKeys,\n onSelectionChange,\n isRowSelectable,\n stickyHeader = true,\n stickyPagination = true,\n rowHoverActions,\n renderRowHoverActions,\n rowHoverActionHeader,\n rowHoverActionMode = 'overlay',\n rowHoverActionClass,\n paginationClass,\n paginationContainerClass,\n paginationProps,\n renderPagination,\n}: DataTableProps<T>) {\n const [internalSortingState, setInternalSortingState] = useState<SortQuery>({})\n\n const handleSort = useCallback(\n (column: DataTableColumn<T>) => {\n if (!column.sortable) return\n if (onSort) {\n onSort(column)\n } else {\n setInternalSortingState((prev) => updateSortQuery(prev, column.name, column.type))\n }\n },\n [onSort],\n )\n\n const activeSorting = useMemo(\n () => ({ ...sorting, ...internalSortingState }),\n [sorting, internalSortingState],\n )\n\n const sortedItems: T[] = useMemo(() => {\n if (onSort) return items\n const activeSortKey = Object.keys(activeSorting)[0]\n if (!activeSortKey) return items\n const column = columns.find((c) => c.name === activeSortKey)\n if (!column) return items\n return autoSortItems(items, column, activeSorting[activeSortKey])\n }, [items, columns, onSort, activeSorting])\n\n const getKey = useCallback(\n (item: T, idx: number): string | number =>\n typeof rowKey === 'function' ? rowKey(item) : ((item as any)[rowKey] ?? idx),\n [rowKey],\n )\n\n const getRowClass = useCallback(\n (item: T, idx: number): string =>\n typeof rowClass === 'function' ? rowClass(item, idx) : rowClass || '',\n [rowClass],\n )\n\n const getCellClass = useCallback(\n (column: DataTableColumn<T>, item: T): string =>\n typeof column.cellClass === 'function' ? column.cellClass(item) : column.cellClass || '',\n [],\n )\n\n const { isSelected, toggleRow, toggleAll, allSelected, someSelected } = useRowSelection({\n items: sortedItems,\n getKey,\n selectedRowKeys,\n defaultSelectedRowKeys,\n onSelectionChange,\n isRowSelectable,\n })\n\n const hasRowHoverActions = Boolean(rowHoverActions || renderRowHoverActions)\n const isInlineMode = hasRowHoverActions && rowHoverActionMode === 'inline'\n const isOverlayMode = hasRowHoverActions && rowHoverActionMode !== 'inline'\n\n const densityCellClass = DENSITY_CELL_CLASS[density]\n const colSize = columns.length + (selectable ? 1 : 0) + (isInlineMode ? 1 : 0)\n const wrapperHasOverflow = OVERFLOW_REGEX.test(wrapperClass)\n\n const renderActionsContent = useCallback(\n (item: T, idx: number) => {\n if (renderRowHoverActions) return renderRowHoverActions(item, idx)\n if (!rowHoverActions) return null\n return rowHoverActions(item, idx).map((act) => {\n const isDisabled = typeof act.disabled === 'function' ? act.disabled(item) : act.disabled\n const isIconOnly = Boolean(act.icon && !act.label)\n\n return (\n <Button\n key={act.id}\n size=\"xs\"\n theme={act.theme || 'secondary'}\n variant={act.variant || 'plain'}\n disabled={isDisabled}\n title={act.title || (typeof act.label === 'string' ? act.label : undefined)}\n className={buildClassName(\n isIconOnly\n ? 'p-1.5 rounded-full hover:bg-black/5 dark:hover:bg-white/10'\n : 'px-2 py-1',\n act.className,\n )}\n onClick={(e) => {\n e.stopPropagation()\n act.onClick(item, idx, e)\n }}\n >\n {act.icon && <span className=\"shrink-0\">{act.icon}</span>}\n {act.label && <span>{act.label}</span>}\n </Button>\n )\n })\n },\n [renderRowHoverActions, rowHoverActions],\n )\n\n return (\n <div className={buildClassName('w-full rounded-lg relative', containerClass)}>\n <div\n className={buildClassName(\n !wrapperHasOverflow && 'overflow-x-auto',\n 'rounded-lg border border-[var(--ui-border)]',\n wrapperClass,\n pagination && 'rounded-b-none border-b-0',\n )}\n >\n <Table\n className={buildClassName('relative w-full max-w-full h-fit', tableClass)}\n layout={layout}\n >\n <TableHead className={headClass}>\n {selectable && (\n <TableHeaderCell\n className={buildClassName(\n 'bg-gray-50 dark:bg-gray-800 w-px',\n densityCellClass,\n stickyHeader && 'sticky top-0 z-20 shadow-[0_1px_2px_rgba(0,0,0,0.06)]',\n )}\n >\n <Checkbox\n aria-label=\"Select all rows\"\n checked={allSelected}\n ref={(el) => {\n if (el) el.indeterminate = someSelected\n }}\n onChange={toggleAll}\n />\n </TableHeaderCell>\n )}\n {columns.map((column) => {\n const sortState = activeSorting[column.name]\n const ariaSortValue = column.sortable\n ? sortState === 'asc' || sortState === '1'\n ? 'ascending'\n : sortState === 'desc' || sortState === '-1'\n ? 'descending'\n : 'none'\n : undefined\n\n return (\n <TableHeaderCell\n key={column.name}\n align={column.headerAlign}\n style={{ width: column.width || 'auto' }}\n aria-sort={ariaSortValue}\n className={buildClassName(\n 'bg-gray-50 dark:bg-gray-800',\n densityCellClass,\n stickyHeader && 'sticky top-0 z-20 shadow-[0_1px_2px_rgba(0,0,0,0.06)]',\n column.sticky === 'left' &&\n 'sticky left-0 z-30 shadow-[2px_0_6px_rgba(0,0,0,0.06)]',\n column.sticky === 'right' &&\n 'sticky right-0 z-30 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]',\n column.headerClass,\n )}\n >\n <TextContent\n role={column.sortable ? 'button' : undefined}\n tabIndex={column.sortable ? 0 : undefined}\n aria-label={column.sortable ? `Sort by ${column.label}` : undefined}\n className={buildClassName(\n 'group',\n column.sortable &&\n 'inline-flex items-center gap-2 cursor-pointer select-none focus:outline-none focus-visible:ring-1 focus-visible:ring-blue-500 rounded',\n )}\n onClick={() => handleSort(column)}\n onKeyDown={(e) => {\n if (column.sortable && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault()\n handleSort(column)\n }\n }}\n >\n <TextContent className=\"shrink-0\">{column.label}</TextContent>\n {column.sortable ? getSortIcon(activeSorting[column.name]) : null}\n </TextContent>\n </TableHeaderCell>\n )\n })}\n {isInlineMode && (\n <TableHeaderCell\n align=\"right\"\n className={buildClassName(\n 'bg-gray-50 dark:bg-gray-800 text-right w-px',\n densityCellClass,\n stickyHeader && 'sticky top-0 z-20 shadow-[0_1px_2px_rgba(0,0,0,0.06)]',\n )}\n >\n {rowHoverActionHeader ?? ''}\n </TableHeaderCell>\n )}\n {isOverlayMode && (\n <TableHeaderCell\n align=\"right\"\n style={{ padding: 0, width: 0, minWidth: 0, maxWidth: 0 }}\n className={buildClassName(\n 'sticky right-0 z-20 !p-0 !pr-0 !pl-0 !py-0 w-0 max-w-0 min-w-0 border-0 bg-gray-50 dark:bg-gray-800',\n stickyHeader && 'top-0',\n )}\n >\n {null}\n </TableHeaderCell>\n )}\n </TableHead>\n\n <TableBody loading={loading} colSize={colSize} rowSize={pagination?.limit || 5}>\n {!loading && sortedItems.length === 0 ? (\n <EmptyTableRow colSpan={colSize}>{emptyMessage}</EmptyTableRow>\n ) : (\n sortedItems.map((item, idx) => {\n const key = getKey(item, idx)\n const rowSelectable = !isRowSelectable || isRowSelectable(item)\n\n return (\n <TableRow\n key={key}\n className={buildClassName(\n 'group',\n onRowClick && 'cursor-pointer',\n striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40',\n getRowClass(item, idx),\n )}\n onClick={onRowClick ? () => onRowClick(item, idx) : undefined}\n >\n {selectable && (\n <TableCell\n className={buildClassName(\n densityCellClass,\n striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40',\n )}\n >\n <span onClick={(e) => e.stopPropagation()}>\n <Checkbox\n aria-label=\"Select row\"\n checked={isSelected(key)}\n disabled={!rowSelectable}\n onChange={() => toggleRow(key)}\n />\n </span>\n </TableCell>\n )}\n {columns.map((column) => (\n <TableCell\n key={column.name}\n align={column.align}\n className={buildClassName(\n densityCellClass,\n striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40',\n column.sticky === 'left' &&\n 'sticky left-0 z-10 shadow-[2px_0_6px_rgba(0,0,0,0.06)]',\n column.sticky === 'right' &&\n 'sticky right-0 z-10 shadow-[-2px_0_6px_rgba(0,0,0,0.06)]',\n getCellClass(column, item),\n )}\n >\n {column.render\n ? column.render(item)\n : ((get(item, column.name) as any) ?? 'Not set')}\n </TableCell>\n ))}\n {isInlineMode && (\n <TableCell\n align=\"right\"\n className={buildClassName(\n densityCellClass,\n striped && idx % 2 === 1 && 'bg-gray-50 dark:bg-gray-800/40',\n )}\n onClick={(e) => e.stopPropagation()}\n >\n <div\n className={buildClassName(\n 'opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity duration-150 flex items-center justify-end gap-1.5',\n rowHoverActionClass,\n )}\n data-testid={`row-hover-actions-${key}`}\n >\n {renderActionsContent(item, idx)}\n </div>\n </TableCell>\n )}\n {isOverlayMode && (\n <TableCell\n align=\"right\"\n style={{ padding: 0, width: 0, minWidth: 0, maxWidth: 0 }}\n className=\"sticky right-0 z-20 !p-0 !pr-0 !pl-0 !py-0 w-0 max-w-0 min-w-0 border-0 overflow-visible text-right\"\n onClick={(e) => e.stopPropagation()}\n >\n <div\n className={buildClassName(\n 'absolute right-0 top-0 bottom-0 h-full opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity duration-150 flex items-center justify-end gap-1 px-3 z-30 pointer-events-none group-hover:pointer-events-auto whitespace-nowrap',\n striped && idx % 2 === 1\n ? 'bg-gray-100 dark:bg-gray-800'\n : 'bg-white group-hover:bg-gray-50 dark:bg-gray-900 dark:group-hover:bg-gray-800',\n rowHoverActionClass,\n )}\n data-testid={`row-hover-actions-${key}`}\n >\n {renderActionsContent(item, idx)}\n </div>\n </TableCell>\n )}\n </TableRow>\n )\n })\n )}\n </TableBody>\n\n {footerRow && <TableFoot>{footerRow}</TableFoot>}\n </Table>\n </div>\n\n {pagination && (\n <div\n className={buildClassName(\n stickyPagination && 'sticky bottom-0 z-20',\n paginationContainerClass,\n )}\n >\n {renderPagination ? (\n renderPagination(pagination, setPagination)\n ) : (\n <Pagination\n {...pagination}\n {...paginationProps}\n className={buildClassName(\n 'rounded-t-none rounded-b-lg border border-[var(--ui-border)] bg-white dark:bg-gray-800',\n paginationClass,\n paginationProps?.className,\n )}\n onChange={setPagination}\n />\n )}\n </div>\n )}\n </div>\n )\n}\n\nDataTable.displayName = 'DataTable'\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -14,6 +14,7 @@ const COLUMN_GRID_MAP = {
14
14
  const RadioGroup = (props) => {
15
15
  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;
16
16
  const groupId = useId();
17
+ const groupName = name || groupId;
17
18
  const items = useMemo(() => {
18
19
  var _a;
19
20
  return (_a = options === null || options === void 0 ? void 0 : options.map((option) => typeof option === 'string'
@@ -38,13 +39,14 @@ const RadioGroup = (props) => {
38
39
  : 'flex flex-col gap-3'), children: items.map((item) => {
39
40
  const isSelected = value === item.value;
40
41
  const isItemDisabled = disabled || Boolean(item.disabled);
42
+ const radioItemId = `${groupName}-${item.value}`;
41
43
  if (isCards) {
42
- return (jsxs("label", { htmlFor: `${name}-${item.value}`, className: buildClassName('relative flex items-start gap-3 p-4 rounded-xl border transition-all cursor-pointer select-none min-w-[200px] flex-1', isSelected
44
+ return (jsxs("label", { htmlFor: radioItemId, className: 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
43
45
  ? 'border-[var(--ui-primary)] bg-blue-50/40 dark:bg-blue-950/30 ring-2 ring-[var(--ui-primary-ring)]/30'
44
46
  : 'border-[var(--ui-border)] bg-white dark:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600', isItemDisabled &&
45
- 'opacity-50 cursor-not-allowed pointer-events-none bg-gray-50 dark:bg-gray-800/50'), children: [jsx(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" }), jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2", children: [item.icon && (jsx("span", { className: "shrink-0 text-gray-500 dark:text-gray-400", children: item.icon })), jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-white truncate", children: item.label })] }), item.description && (jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400 font-normal leading-relaxed", children: item.description }))] })] }, item.value));
47
+ 'opacity-50 cursor-not-allowed pointer-events-none bg-gray-50 dark:bg-gray-800/50'), children: [jsx(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" }), jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2", children: [item.icon && (jsx("span", { className: "shrink-0 text-gray-500 dark:text-gray-400", children: item.icon })), jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-white truncate", children: item.label })] }), item.description && (jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400 font-normal leading-relaxed", children: item.description }))] })] }, item.value));
46
48
  }
47
- return (jsx(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));
49
+ return (jsx(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));
48
50
  }) }), showErrorMessage && error && (jsx("div", { className: "mt-1.5", children: jsx(TextContent, { error: true, small: true, id: errorId, children: error }) }))] }));
49
51
  };
50
52
  RadioGroup.displayName = 'RadioGroup';
@@ -1 +1 @@
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\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\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 id={errorId}>\n {error}\n </TextContent>\n </div>\n )}\n </div>\n )\n}\n\nRadioGroup.displayName = 'RadioGroup'\n"],"names":["_jsxs","_jsx"],"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":["_jsxs","_jsx"],"mappings":"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"}