@donotdev/components 0.0.13 → 0.0.14

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 (57) hide show
  1. package/dist/advanced/Code/CodeContent.d.ts.map +1 -1
  2. package/dist/advanced/Code/CodeContent.js +5 -1
  3. package/dist/advanced/Code/CodeSkeleton.d.ts.map +1 -1
  4. package/dist/advanced/Code/CodeSkeleton.js +2 -1
  5. package/dist/advanced/JsonViewer/JsonViewer.d.ts.map +1 -1
  6. package/dist/advanced/JsonViewer/JsonViewer.js +2 -1
  7. package/dist/atomic/Button/index.d.ts.map +1 -1
  8. package/dist/atomic/Checkbox/index.d.ts +16 -2
  9. package/dist/atomic/Checkbox/index.d.ts.map +1 -1
  10. package/dist/atomic/Checkbox/index.js +20 -4
  11. package/dist/atomic/Collapsible/index.d.ts.map +1 -1
  12. package/dist/atomic/Collapsible/index.js +5 -1
  13. package/dist/atomic/Icons/Partner/providerIcons.d.ts.map +1 -1
  14. package/dist/atomic/Icons/Partner/providerIcons.js +17 -1
  15. package/dist/atomic/Input/index.d.ts +6 -1
  16. package/dist/atomic/Input/index.d.ts.map +1 -1
  17. package/dist/atomic/Input/index.js +10 -5
  18. package/dist/atomic/Label/FloatingLabel.d.ts +3 -1
  19. package/dist/atomic/Label/FloatingLabel.d.ts.map +1 -1
  20. package/dist/atomic/Label/FloatingLabel.js +2 -2
  21. package/dist/atomic/Pagination/index.d.ts +7 -29
  22. package/dist/atomic/Pagination/index.d.ts.map +1 -1
  23. package/dist/atomic/Pagination/index.js +101 -71
  24. package/dist/atomic/PasswordInput/index.d.ts.map +1 -1
  25. package/dist/atomic/PasswordInput/index.js +1 -1
  26. package/dist/atomic/RangeInput/index.d.ts +45 -0
  27. package/dist/atomic/RangeInput/index.d.ts.map +1 -0
  28. package/dist/atomic/RangeInput/index.js +63 -0
  29. package/dist/atomic/Select/index.d.ts.map +1 -1
  30. package/dist/atomic/Select/index.js +1 -1
  31. package/dist/atomic/Slider/index.d.ts.map +1 -1
  32. package/dist/atomic/Slider/index.js +7 -4
  33. package/dist/atomic/Table/index.d.ts +18 -5
  34. package/dist/atomic/Table/index.d.ts.map +1 -1
  35. package/dist/atomic/Table/index.js +91 -31
  36. package/dist/atomic/Textarea/index.d.ts +4 -0
  37. package/dist/atomic/Textarea/index.d.ts.map +1 -1
  38. package/dist/atomic/Textarea/index.js +3 -3
  39. package/dist/atomic/Toaster/Toast.types.d.ts +17 -0
  40. package/dist/atomic/Toaster/Toast.types.d.ts.map +1 -0
  41. package/dist/atomic/Toaster/Toast.types.js +2 -0
  42. package/dist/atomic/Toaster/ToastPrimitive.d.ts +1 -1
  43. package/dist/atomic/Toaster/ToastPrimitive.d.ts.map +1 -1
  44. package/dist/atomic/VideoPlayer/index.d.ts +11 -1
  45. package/dist/atomic/VideoPlayer/index.d.ts.map +1 -1
  46. package/dist/atomic/VideoPlayer/index.js +6 -8
  47. package/dist/atomic/index.d.ts +2 -0
  48. package/dist/atomic/index.d.ts.map +1 -1
  49. package/dist/atomic/index.js +1 -0
  50. package/dist/hooks/index.d.ts +2 -1
  51. package/dist/hooks/index.d.ts.map +1 -1
  52. package/dist/hooks/useToast.d.ts +1 -8
  53. package/dist/hooks/useToast.d.ts.map +1 -1
  54. package/dist/hooks/useToast.js +1 -0
  55. package/dist/index.js +4 -4
  56. package/dist/styles/index.css +186 -72
  57. package/package.json +1 -1
@@ -0,0 +1,45 @@
1
+ import type { InputHTMLAttributes } from 'react';
2
+ import './RangeInput.css';
3
+ export interface RangeInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value'> {
4
+ /** Label for the range (single FloatingLabel wrapping both inputs) */
5
+ label?: string;
6
+ /** Placeholder for min input */
7
+ minPlaceholder?: string;
8
+ /** Placeholder for max input */
9
+ maxPlaceholder?: string;
10
+ /** Current min value */
11
+ minValue?: string;
12
+ /** Current max value */
13
+ maxValue?: string;
14
+ /** Actual min value from data (for auto-populate on focus) */
15
+ actualMin?: string | number;
16
+ /** Actual max value from data (for auto-populate on focus) */
17
+ actualMax?: string | number;
18
+ /** Change handler: (min, max) => void */
19
+ onChange: (min: string, max: string) => void;
20
+ /** Clear handler - required, X button always visible */
21
+ onClear: () => void;
22
+ }
23
+ /**
24
+ * RangeInput - Two-input component for min/max ranges
25
+ *
26
+ * Features:
27
+ * - Single FloatingLabel wrapping both inputs (when label provided)
28
+ * - Auto-populates with actual data min/max on focus if empty
29
+ * - Selects all text on focus
30
+ * - Clear button always visible (disabled when empty)
31
+ *
32
+ * @component
33
+ * @example
34
+ * ```tsx
35
+ * <RangeInput
36
+ * type="number"
37
+ * label="Price"
38
+ * onChange={(min, max) => setFilter({ min, max })}
39
+ * onClear={() => setFilter({ min: '', max: '' })}
40
+ * />
41
+ * ```
42
+ */
43
+ export declare function RangeInput({ type, label, minPlaceholder, maxPlaceholder, minValue, maxValue, actualMin, actualMax, min, max, onChange, onClear, ...props }: RangeInputProps): import("react/jsx-runtime").JSX.Element;
44
+ export default RangeInput;
45
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/RangeInput/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAEjD,OAAO,kBAAkB,CAAC;AAE1B,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,UAAU,GAAG,OAAO,CACrB;IACC,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,yCAAyC;IACzC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,wDAAwD;IACxD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAe,EACf,KAAK,EACL,cAAsB,EACtB,cAAsB,EACtB,QAAa,EACb,QAAa,EACb,SAAS,EACT,SAAS,EACT,GAAG,EACH,GAAG,EACH,QAAQ,EACR,OAAO,EACP,GAAG,KAAK,EACT,EAAE,eAAe,2CA+EjB;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // packages/components/src/atomic/RangeInput/index.tsx
3
+ /**
4
+ * @fileoverview RangeInput component
5
+ * @description Two-input range component for min/max values (e.g., price ranges, date ranges)
6
+ *
7
+ * @version 0.0.2
8
+ * @since 0.0.1
9
+ * @author AMBROISE PARK Consulting
10
+ */
11
+ import { X } from 'lucide-react';
12
+ import Button from '../Button';
13
+ import Input from '../Input';
14
+ import { FloatingLabel } from '../Label';
15
+ import Text from '../Text';
16
+ import './RangeInput.css';
17
+ /**
18
+ * RangeInput - Two-input component for min/max ranges
19
+ *
20
+ * Features:
21
+ * - Single FloatingLabel wrapping both inputs (when label provided)
22
+ * - Auto-populates with actual data min/max on focus if empty
23
+ * - Selects all text on focus
24
+ * - Clear button always visible (disabled when empty)
25
+ *
26
+ * @component
27
+ * @example
28
+ * ```tsx
29
+ * <RangeInput
30
+ * type="number"
31
+ * label="Price"
32
+ * onChange={(min, max) => setFilter({ min, max })}
33
+ * onClear={() => setFilter({ min: '', max: '' })}
34
+ * />
35
+ * ```
36
+ */
37
+ export function RangeInput({ type = 'number', label, minPlaceholder = 'Min', maxPlaceholder = 'Max', minValue = '', maxValue = '', actualMin, actualMax, min, max, onChange, onClear, ...props }) {
38
+ const handleMinFocus = (e) => {
39
+ e.target.select();
40
+ if (!minValue &&
41
+ actualMin !== null &&
42
+ actualMin !== undefined &&
43
+ actualMin !== '') {
44
+ onChange(String(actualMin), maxValue);
45
+ }
46
+ };
47
+ const handleMaxFocus = (e) => {
48
+ e.target.select();
49
+ if (!maxValue &&
50
+ actualMax !== null &&
51
+ actualMax !== undefined &&
52
+ actualMax !== '') {
53
+ onChange(minValue, String(actualMax));
54
+ }
55
+ };
56
+ const hasValue = !!(minValue || maxValue);
57
+ const inputs = (_jsxs(_Fragment, { children: [_jsx(Input, { type: type, placeholder: minPlaceholder, value: minValue, min: min, max: max, bare: true, onFocus: handleMinFocus, onChange: (e) => onChange(e.target.value, maxValue), ...props }), _jsx(Text, { level: "small", variant: "muted", className: "dndev-range-input-separator", children: "\u2013" }), _jsx(Input, { type: type, placeholder: maxPlaceholder, value: maxValue, min: min, max: max, bare: true, onFocus: handleMaxFocus, onChange: (e) => onChange(minValue, e.target.value), ...props }), _jsx(Button, { icon: X, variant: "ghost", display: "compact", onClick: onClear, disabled: !hasValue, "aria-label": "Clear", className: "dndev-range-input-clear" })] }));
58
+ if (label) {
59
+ return (_jsx(FloatingLabel, { label: label, className: "dndev-range-input", children: inputs }));
60
+ }
61
+ return _jsx("div", { className: "dndev-range-input", children: inputs });
62
+ }
63
+ export default RangeInput;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Select/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,mBAON,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAEvD,OAAO,cAAc,CAAC;AAEtB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,WAAY,SAAQ,IAAI,CACvC,cAAc,CAAC,OAAO,mBAAmB,CAAC,EAC1C,UAAU,CACX;IACC,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB;IACvB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mGAAmG;IACnG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,QAAA,MAAM,MAAM,GAAI,uHAYb,WAAW,4CAwHb,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Select/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,mBAON,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAEvD,OAAO,cAAc,CAAC;AAEtB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,WAAY,SAAQ,IAAI,CACvC,cAAc,CAAC,OAAO,mBAAmB,CAAC,EAC1C,UAAU,CACX;IACC,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB;IACvB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mGAAmG;IACnG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,QAAA,MAAM,MAAM,GAAI,uHAYb,WAAW,4CAyHb,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -40,7 +40,7 @@ const Select = ({ value, onValueChange, placeholder = 'Select an option...', opt
40
40
  const id = useId();
41
41
  const [isOpen, setIsOpen] = useState(false);
42
42
  const hasLabel = !!label;
43
- const triggerElement = (_jsxs(SelectTriggerPrimitive, { id: id, className: "dndev-input dndev-select-trigger", disabled: disabled, children: [isLoading ? (_jsxs("div", { className: "dndev-select-loading-container", children: [_jsx("div", { className: "dndev-animate-spin dndev-select-loading-spinner" }), _jsx("span", { children: "Loading..." })] })) : (_jsx(SelectValuePrimitive, { placeholder: placeholder })), _jsx(SelectRadix.Icon, { asChild: true, children: _jsx(ChevronDown, {}) })] }));
43
+ const triggerElement = (_jsxs(SelectTriggerPrimitive, { id: id, className: "dndev-input dndev-select-trigger", disabled: disabled, "data-bare": hasLabel || undefined, children: [isLoading ? (_jsxs("div", { className: "dndev-select-loading-container", children: [_jsx("div", { className: "dndev-animate-spin dndev-select-loading-spinner" }), _jsx("span", { children: "Loading..." })] })) : (_jsx(SelectValuePrimitive, { placeholder: placeholder })), _jsx(SelectRadix.Icon, { asChild: true, children: _jsx(ChevronDown, {}) })] }));
44
44
  const customTrigger = trigger ? (_jsx(SelectTriggerPrimitive, { asChild: true, disabled: disabled, className: "dndev-input dndev-select-trigger", children: trigger })) : hasLabel ? (_jsx(FloatingLabel, { htmlFor: id, label: label, disabled: disabled, required: required, children: triggerElement })) : (triggerElement);
45
45
  return (_jsxs(SelectRootPrimitive, { value: value, onValueChange: onValueChange, defaultValue: defaultValue, disabled: disabled, onOpenChange: setIsOpen, ...props, children: [customTrigger, _jsx(SelectRadix.Portal, { children: _jsx(SelectContentPrimitive, { className: "dndev-floating dndev-menu-content dndev-z-tooltip dndev-select-content", position: "popper", side: "bottom", sideOffset: 4, align: "start", "data-glow": "blank", children: _jsx(SelectRadix.Viewport, { children: _jsx(ScrollArea, { className: "dndev-menu-scroll-area", end: true, children: options.map((option) => {
46
46
  if (option.value === '__label__') {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Slider/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAI1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,cAAc,CAAC;AAEtB,MAAM,WAAW,WAAY,SAAQ,cAAc,CACjD,OAAO,eAAe,CAAC,IAAI,CAC5B;IACC,6BAA6B;IAC7B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,yBAAyB;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAoBD;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,MAAM,GAAI,kEAOb,WAAW,4CA2Bb,CAAC;AAEF,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,eAAe,IAAI,cAAc,EAAE,CAAC;AAC9D,YAAY,EAAE,cAAc,IAAI,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Slider/index.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAI1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,cAAc,CAAC;AAEtB,MAAM,WAAW,WAAY,SAAQ,cAAc,CACjD,OAAO,eAAe,CAAC,IAAI,CAC5B;IACC,6BAA6B;IAC7B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,yBAAyB;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAoBD;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,MAAM,GAAI,kEAOb,WAAW,4CAmCb,CAAC;AAEF,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,eAAe,IAAI,cAAc,EAAE,CAAC;AAC9D,YAAY,EAAE,cAAc,IAAI,aAAa,EAAE,CAAC"}
@@ -47,10 +47,13 @@ const sliderVariants = cva('dndev-slider', {
47
47
  const Slider = ({ className, variant, showValue, value, defaultValue, ...props }) => {
48
48
  const variantAttrs = getVariantDataAttrs({ variant });
49
49
  const currentValue = value ?? defaultValue;
50
- const displayValue = Array.isArray(currentValue)
51
- ? currentValue[0]
52
- : currentValue;
53
- return (_jsx("div", { className: "dndev-slider-container", children: _jsxs(SliderPrimitive.Root, { className: cn(sliderVariants({ variant }), className), value: value, defaultValue: defaultValue, ...variantAttrs, ...props, children: [_jsx(SliderPrimitive.Track, { className: cn('dndev-slider-track'), children: _jsx(SliderPrimitive.Range, { className: cn('dndev-slider-range') }) }), _jsx(SliderPrimitive.Thumb, { className: cn('dndev-slider-thumb'), children: showValue && displayValue !== undefined && (_jsx("span", { className: "dndev-slider-value", children: displayValue })) })] }) }));
50
+ // Handle array values (for range sliders) or single values
51
+ const values = Array.isArray(currentValue)
52
+ ? currentValue
53
+ : currentValue !== undefined
54
+ ? [currentValue]
55
+ : [];
56
+ return (_jsx("div", { className: "dndev-slider-container", children: _jsxs(SliderPrimitive.Root, { className: cn(sliderVariants({ variant }), className), value: value, defaultValue: defaultValue, ...variantAttrs, ...props, children: [_jsx(SliderPrimitive.Track, { className: cn('dndev-slider-track'), children: _jsx(SliderPrimitive.Range, { className: cn('dndev-slider-range') }) }), values.map((val, index) => (_jsx(SliderPrimitive.Thumb, { className: cn('dndev-slider-thumb'), children: showValue && val !== undefined && (_jsx("span", { className: "dndev-slider-value", children: val })) }, index)))] }) }));
54
57
  };
55
58
  export default Slider;
56
59
  export { SliderPrimitive, CONTROL_VARIANT as SLIDER_VARIANT };
@@ -18,6 +18,7 @@ export interface TableColumn<T = any> {
18
18
  title: string | ReactNode;
19
19
  dataIndex?: keyof T;
20
20
  sortable?: boolean;
21
+ /** Enable column header filter (Excel-style dropdown) */
21
22
  filterable?: boolean;
22
23
  /**
23
24
  * Render prop for custom cell content - RENDER PROP EXCEPTION
@@ -56,12 +57,26 @@ export interface DataTableProps<T = any> {
56
57
  selectable?: boolean;
57
58
  /** Enable search */
58
59
  searchable?: boolean;
59
- /** Enable filtering (placeholder UI) */
60
- filterable?: boolean;
61
60
  /** Enable pagination */
62
61
  pagination?: boolean;
62
+ /** Current page (1-indexed) */
63
+ currentPage?: number;
63
64
  /** Page size */
64
65
  pageSize?: number;
66
+ /** Total number of items (for server-side pagination) */
67
+ total?: number;
68
+ /** Callback when page changes */
69
+ onPageChange?: (page: number) => void;
70
+ /** Callback when page size changes */
71
+ onPageSizeChange?: (pageSize: number) => void;
72
+ /** Label for "Showing X to Y of Z" text (default: "Showing {{from}} to {{to}} of {{total}} results") */
73
+ showingLabel?: string;
74
+ /** Label for previous button (passed to Pagination) */
75
+ paginationPreviousLabel?: string;
76
+ /** Label for next button (passed to Pagination) */
77
+ paginationNextLabel?: string;
78
+ /** Placeholder for items per page selector (passed to Pagination) */
79
+ paginationItemsPerPagePlaceholder?: string;
65
80
  /** Loading state */
66
81
  loading?: boolean;
67
82
  /** Excel-like grid lines (borders on all cells) */
@@ -72,8 +87,6 @@ export interface DataTableProps<T = any> {
72
87
  onSelect?: (selectedRows: T[]) => void;
73
88
  /** Callback when search query changes */
74
89
  onSearch?: (query: string) => void;
75
- /** Callback when filters change */
76
- onFilter?: (filters: Record<string, any>) => void;
77
90
  /** Callback when a row is clicked */
78
91
  onRowClick?: (row: T) => void;
79
92
  /** Additional CSS classes */
@@ -110,7 +123,7 @@ declare function TableCaption({ className, ...props }: HTMLAttributes<HTMLTableC
110
123
  * @param {DataTableProps} props - The props for the data table
111
124
  * @returns {ReactNode} The rendered data table
112
125
  */
113
- declare const DataTable: <T = any>({ data, columns, sortable, selectable, searchable, filterable, pagination, pageSize, loading, gridLines, onSort, onSelect, onSearch, onFilter, onRowClick, className, }: DataTableProps<T>) => ReactNode;
126
+ declare const DataTable: <T = any>({ data, columns, sortable, selectable, searchable, pagination, currentPage: currentPageProp, pageSize: pageSizeProp, total: totalProp, onPageChange, onPageSizeChange, showingLabel, paginationPreviousLabel, paginationNextLabel, paginationItemsPerPagePlaceholder, loading, gridLines, onSort, onSelect, onSearch, onRowClick, className, }: DataTableProps<T>) => ReactNode;
114
127
  export default Table;
115
128
  export { TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, DataTable, };
116
129
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Table/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Table/index.tsx"],"names":[],"mappings":"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"}
@@ -8,13 +8,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  * @since 0.0.1
9
9
  * @author AMBROISE PARK Consulting
10
10
  */
11
- import { ChevronUp, ChevronDown, Search, Filter } from 'lucide-react';
11
+ import { ChevronUp, ChevronDown, Search } from 'lucide-react';
12
12
  import { useState, useMemo, } from 'react';
13
13
  import { cn } from '../../utils/helpers';
14
14
  import Button, { BUTTON_VARIANT } from '../Button';
15
15
  import Checkbox from '../Checkbox';
16
16
  import Input from '../Input';
17
- import Skeleton from '../Skeleton';
17
+ import Pagination from '../Pagination';
18
+ import Select from '../Select';
18
19
  import Stack from '../Stack';
19
20
  import Text from '../Text';
20
21
  import './Table.css';
@@ -66,12 +67,38 @@ function TableCaption({ className, ...props }) {
66
67
  * @param {DataTableProps} props - The props for the data table
67
68
  * @returns {ReactNode} The rendered data table
68
69
  */
69
- const DataTable = ({ data, columns, sortable = true, selectable = false, searchable = true, filterable = false, pagination = true, pageSize = 10, loading = false, gridLines = false, onSort, onSelect, onSearch, onFilter, onRowClick, className, }) => {
70
+ const DataTable = ({ data, columns, sortable = true, selectable = false, searchable = true, pagination = true, currentPage: currentPageProp, pageSize: pageSizeProp, total: totalProp, onPageChange, onPageSizeChange, showingLabel, paginationPreviousLabel, paginationNextLabel, paginationItemsPerPagePlaceholder, loading = false, gridLines = false, onSort, onSelect, onSearch, onRowClick, className, }) => {
70
71
  const [sortColumn, setSortColumn] = useState('');
71
72
  const [sortDirection, setSortDirection] = useState('asc');
72
73
  const [searchQuery, setSearchQuery] = useState('');
73
74
  const [selectedRows, setSelectedRows] = useState([]);
74
- const [currentPage, setCurrentPage] = useState(1);
75
+ // Page size state (for client-side pagination) - default 12
76
+ const [internalPageSize, setInternalPageSize] = useState(12);
77
+ const effectivePageSize = pageSizeProp ?? internalPageSize;
78
+ // Controlled vs uncontrolled pagination
79
+ const isControlledPagination = currentPageProp !== undefined && onPageChange !== undefined;
80
+ const [internalPage, setInternalPage] = useState(1);
81
+ const currentPage = isControlledPagination ? currentPageProp : internalPage;
82
+ const handlePageChange = (page) => {
83
+ if (isControlledPagination) {
84
+ onPageChange?.(page);
85
+ }
86
+ else {
87
+ setInternalPage(page);
88
+ }
89
+ };
90
+ // Handle page size change
91
+ const handlePageSizeChange = (newPageSize) => {
92
+ if (onPageSizeChange) {
93
+ // Controlled mode (server-side)
94
+ onPageSizeChange(newPageSize);
95
+ }
96
+ else {
97
+ // Uncontrolled mode (client-side) - update internal state
98
+ setInternalPageSize(newPageSize);
99
+ setInternalPage(1); // Reset to page 1
100
+ }
101
+ };
75
102
  // Filter and sort data
76
103
  const processedData = useMemo(() => {
77
104
  let filtered = data;
@@ -98,11 +125,19 @@ const DataTable = ({ data, columns, sortable = true, selectable = false, searcha
98
125
  }
99
126
  return filtered;
100
127
  }, [data, searchQuery, sortColumn, sortDirection, columns]);
101
- // Pagination
102
- const totalPages = Math.ceil(processedData.length / pageSize);
103
- const paginatedData = pagination
104
- ? processedData.slice((currentPage - 1) * pageSize, currentPage * pageSize)
105
- : processedData;
128
+ // Pagination: use server-side total if provided, otherwise client-side
129
+ const total = totalProp ?? processedData.length;
130
+ // Handle "All" case (pageSize = 0 means show all)
131
+ const isShowingAll = effectivePageSize === 0;
132
+ const pageSize = isShowingAll ? total : effectivePageSize;
133
+ const totalPages = isShowingAll ? 1 : Math.ceil(total / pageSize);
134
+ // For server-side pagination, data is already paginated - use as-is
135
+ // For client-side pagination, slice the data
136
+ const displayData = isControlledPagination && totalProp !== undefined
137
+ ? processedData // Server-side: data already paginated
138
+ : pagination && !isShowingAll
139
+ ? processedData.slice((currentPage - 1) * pageSize, currentPage * pageSize)
140
+ : processedData;
106
141
  const handleSort = (column) => {
107
142
  if (!sortable)
108
143
  return;
@@ -112,7 +147,7 @@ const DataTable = ({ data, columns, sortable = true, selectable = false, searcha
112
147
  onSort?.(column, newDirection);
113
148
  };
114
149
  const handleSelectAll = (checked) => {
115
- const newSelection = checked ? paginatedData : [];
150
+ const newSelection = checked ? displayData : [];
116
151
  setSelectedRows(newSelection);
117
152
  onSelect?.(newSelection);
118
153
  };
@@ -127,12 +162,12 @@ const DataTable = ({ data, columns, sortable = true, selectable = false, searcha
127
162
  setSearchQuery(query);
128
163
  onSearch?.(query);
129
164
  };
130
- // Skeleton loading state - show real headers with simple skeleton rows
131
- if (loading) {
132
- return (_jsxs(Stack, { gap: "medium", children: [(searchable || filterable) && (_jsxs(Stack, { direction: "row", align: "center", justify: "between", gap: "tight", children: [searchable && (_jsx(Skeleton, { className: "dndev-h-touch dndev-flex-1" })), filterable && (_jsx(Skeleton, { className: "dndev-h-touch dndev-w-24" }))] })), _jsxs(Table, { className: cn(gridLines && 'dndev-table-grid'), children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [selectable && (_jsx(TableHead, { className: "dndev-w-touch", children: _jsx(Checkbox, { checked: false, disabled: true, "aria-label": "Select all rows" }) })), columns.map((column) => (_jsx(TableHead, { className: cn(column.sortable && 'dndev-cursor-default'), "data-sortable": column.sortable, "data-align": column.align, style: { width: column.width }, children: _jsxs(Stack, { direction: "row", align: "center", gap: "tight", children: [typeof column.title === 'string' ? (_jsx(Text, { level: "body", style: { paddingInline: 'var(--gap-sm)' }, children: column.title })) : (column.title), column.sortable && (_jsx(ChevronUp, { className: "dndev-size-md dndev-opacity-30" }))] }) }, column.key)))] }) }), _jsx(TableBody, { children: Array.from({ length: 3 }, (_, rowIndex) => (_jsxs(TableRow, { children: [selectable && (_jsx(TableCell, { className: "dndev-w-touch", children: _jsx(Skeleton, { className: "dndev-h-4 dndev-w-4" }) })), columns.map((column) => (_jsx(TableCell, { "data-align": column.align, style: { width: column.width }, children: _jsx(Skeleton, { size: "text" }) }, `skeleton-cell-${rowIndex}-${column.key}`)))] }, `skeleton-row-${rowIndex}`))) })] })] }));
133
- }
134
- return (_jsxs(Stack, { gap: "medium", children: [(searchable || filterable) && (_jsxs(Stack, { direction: "row", align: "center", justify: "between", gap: "tight", children: [searchable && (_jsxs(Stack, { direction: "row", align: "center", className: "dndev-relative dndev-flex-1 dndev-table-search-container", children: [_jsx(Search, { className: "dndev-table-search-icon" }), _jsx(Input, { placeholder: "Search...", value: searchQuery, onChange: (e) => handleSearch(e.target.value), className: "dndev-table-search-input" })] })), filterable && (_jsx(Button, { variant: BUTTON_VARIANT.OUTLINE, icon: Filter, children: "Filters" }))] })), _jsxs(Table, { className: cn(gridLines && 'dndev-table-grid'), children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [selectable && (_jsx(TableHead, { className: "dndev-w-touch", children: _jsx(Checkbox, { checked: selectedRows.length === paginatedData.length &&
135
- paginatedData.length > 0, onCheckedChange: handleSelectAll, "aria-label": "Select all rows" }) })), columns.map((column) => (_jsx(TableHead, { className: cn(column.sortable && 'dndev-cursor-pointer'), "data-sortable": column.sortable, "data-align": column.align, style: { width: column.width }, onClick: (e) => {
165
+ // Industry standard pattern: When loading, pass empty rows to render actual structure
166
+ // Component will detect empty data and render skeleton bars in cells
167
+ const skeletonRows = Array.from({ length: 3 }, () => ({}));
168
+ const finalDisplayData = loading ? skeletonRows : displayData;
169
+ return (_jsxs(Stack, { gap: "medium", children: [searchable && (_jsxs(Stack, { direction: "row", align: "center", className: "dndev-relative dndev-flex-1 dndev-table-search-container", children: [_jsx(Search, { className: "dndev-table-search-icon" }), _jsx(Input, { placeholder: "Search...", value: searchQuery, onChange: (e) => handleSearch(e.target.value), className: "dndev-table-search-input" })] })), _jsxs(Table, { className: cn(gridLines && 'dndev-table-grid'), children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [selectable && (_jsx(TableHead, { className: "dndev-w-touch", children: _jsx(Checkbox, { checked: selectedRows.length === displayData.length &&
170
+ displayData.length > 0, onCheckedChange: handleSelectAll, "aria-label": "Select all rows" }) })), columns.map((column) => (_jsx(TableHead, { className: cn(column.sortable && 'dndev-cursor-pointer'), "data-sortable": column.sortable, "data-align": column.align, style: { width: column.width }, onClick: (e) => {
136
171
  // Only sort if clicking on header, not on interactive elements (buttons, inputs, etc.)
137
172
  if (column.sortable) {
138
173
  const target = e.target;
@@ -141,22 +176,47 @@ const DataTable = ({ data, columns, sortable = true, selectable = false, searcha
141
176
  handleSort(column.key);
142
177
  }
143
178
  }
144
- }, children: _jsxs(Stack, { direction: "row", align: "center", gap: "tight", children: [typeof column.title === 'string' ? (_jsx(Text, { level: "body", style: { paddingInline: 'var(--gap-sm)' }, children: column.title })) : (column.title), column.sortable &&
145
- sortColumn === column.key &&
146
- (sortDirection === 'asc' ? (_jsx(ChevronUp, { className: "dndev-size-md" })) : (_jsx(ChevronDown, { className: "dndev-size-md" })))] }) }, column.key)))] }) }), _jsx(TableBody, { children: paginatedData.map((row, index) => (_jsxs(TableRow, { onClick: (e) => {
147
- if (onRowClick) {
148
- const target = e.target;
149
- // Prevent row click if clicking interactive elements
150
- const isInteractive = target.closest('button, a, input, [role="button"], label');
151
- if (!isInteractive) {
152
- onRowClick(row);
179
+ }, children: _jsxs(Stack, { direction: "row", align: "center", justify: column.align || 'start', gap: "tight", children: [typeof column.title === 'string' ? (_jsx(Text, { level: "body", children: column.title })) : (column.title), column.sortable &&
180
+ (sortColumn === column.key ? (sortDirection === 'asc' ? (_jsx(ChevronUp, { className: "dndev-size-md" })) : (_jsx(ChevronDown, { className: "dndev-size-md" }))) : (_jsx(ChevronUp, { className: "dndev-size-md", style: { opacity: 0.3 } })))] }) }, column.key)))] }) }), _jsx(TableBody, { children: finalDisplayData.map((row, index) => {
181
+ const isSkeletonRow = loading &&
182
+ Object.keys(row).length === 0;
183
+ return (_jsxs(TableRow, { onClick: (e) => {
184
+ if (onRowClick && !isSkeletonRow) {
185
+ const target = e.target;
186
+ // Prevent row click if clicking interactive elements
187
+ const isInteractive = target.closest('button, a, input, [role="button"], label');
188
+ if (!isInteractive) {
189
+ onRowClick(row);
190
+ }
153
191
  }
154
- }
155
- }, className: cn(onRowClick && 'dndev-cursor-pointer dndev-hover-bg-muted'), children: [selectable && (_jsx(TableCell, { children: _jsx(Checkbox, { checked: selectedRows.includes(row), onCheckedChange: (checked) => handleSelectRow(row, !!checked), "aria-label": `Select row ${index + 1}` }) })), columns.map((column) => (_jsx(TableCell, { "data-align": column.align, children: column.render
156
- ? column.render(column.dataIndex ? row[column.dataIndex] : null, row, index)
157
- : column.dataIndex
158
- ? String(row[column.dataIndex] || '')
159
- : '' }, column.key)))] }, index))) })] }), pagination && totalPages > 1 && (_jsxs(Stack, { direction: "row", align: "center", justify: "between", children: [_jsxs("div", { className: "dndev-text-sm dndev-text-muted", children: ["Showing ", (currentPage - 1) * pageSize + 1, " to", ' ', Math.min(currentPage * pageSize, processedData.length), " of", ' ', processedData.length, " results"] }), _jsxs(Stack, { direction: "row", align: "center", gap: "tight", children: [_jsx(Button, { variant: BUTTON_VARIANT.OUTLINE, onClick: () => setCurrentPage(Math.max(1, currentPage - 1)), disabled: currentPage === 1, children: "Previous" }), _jsxs("span", { className: "dndev-text-sm", children: ["Page ", currentPage, " of ", totalPages] }), _jsx(Button, { variant: BUTTON_VARIANT.OUTLINE, onClick: () => setCurrentPage(Math.min(totalPages, currentPage + 1)), disabled: currentPage === totalPages, children: "Next" })] })] }))] }));
192
+ }, className: cn(isSkeletonRow && 'dndev-skeleton-row', onRowClick &&
193
+ !isSkeletonRow &&
194
+ 'dndev-cursor-pointer dndev-hover-bg-muted'), children: [selectable && (_jsx(TableCell, { children: isSkeletonRow ? (_jsx("div", { className: "dndev-skeleton dndev-skeleton-pulse", style: {
195
+ width: 'var(--icon-md)',
196
+ height: 'var(--icon-md)',
197
+ borderRadius: 'var(--radius)',
198
+ }, "aria-hidden": "true" })) : (_jsx(Checkbox, { checked: selectedRows.includes(row), onCheckedChange: (checked) => handleSelectRow(row, !!checked), "aria-label": `Select row ${index + 1}` })) })), columns.map((column) => {
199
+ const cellValue = column.dataIndex
200
+ ? row[column.dataIndex]
201
+ : null;
202
+ const isEmpty = cellValue === null ||
203
+ cellValue === undefined ||
204
+ cellValue === '';
205
+ // Always call render function if it exists (for action columns, etc.)
206
+ // Let the render function decide what to show for empty/skeleton states
207
+ if (column.render) {
208
+ return (_jsx(TableCell, { "data-align": column.align, children: column.render(cellValue, row, index) }, column.key));
209
+ }
210
+ // For data columns: show skeleton only when loading AND empty
211
+ // When not loading but empty, show empty string (fallback)
212
+ return (_jsx(TableCell, { "data-align": column.align, children: isSkeletonRow ? (_jsx("div", { className: "dndev-skeleton dndev-skeleton-pulse", style: {
213
+ height: 'var(--gap-md)',
214
+ width: index % 2 === 0 ? '80%' : '60%',
215
+ borderRadius: 'var(--radius)',
216
+ }, "aria-hidden": "true" })) : isEmpty ? ('' // Empty state - show nothing, not skeleton
217
+ ) : (String(cellValue || '')) }, column.key));
218
+ })] }, index));
219
+ }) })] }), pagination && totalPages > 1 && (_jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, pageSize: pageSize, total: total, onPageSizeChange: handlePageSizeChange, showingLabel: showingLabel, previousLabel: paginationPreviousLabel, nextLabel: paginationNextLabel, itemsPerPagePlaceholder: paginationItemsPerPagePlaceholder }))] }));
160
220
  };
161
221
  export default Table;
162
222
  export { TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, DataTable, };
@@ -1,5 +1,9 @@
1
1
  import type { ComponentPropsWithRef } from 'react';
2
2
  export interface TextareaProps extends ComponentPropsWithRef<'textarea'> {
3
+ /**
4
+ * Bare mode - no border/shadow (for use inside FloatingLabel or custom wrappers)
5
+ */
6
+ bare?: boolean;
3
7
  }
4
8
  /**
5
9
  * Textarea component with ref forwarding.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Textarea/index.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAEnD,MAAM,WAAW,aAAc,SAAQ,qBAAqB,CAAC,UAAU,CAAC;CAAG;AAE3E;;GAEG;AACH,QAAA,MAAM,QAAQ,4HAMb,CAAC;AAIF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/Textarea/index.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAEnD,MAAM,WAAW,aAAc,SAAQ,qBAAqB,CAAC,UAAU,CAAC;IACtE;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,QAAA,MAAM,QAAQ,4HAWb,CAAC;AAIF,eAAe,QAAQ,CAAC"}
@@ -4,7 +4,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
4
4
  * @fileoverview Textarea component
5
5
  * @description Accessible textarea component with mobile-friendly touch targets
6
6
  *
7
- * @version 0.0.1
7
+ * @version 0.0.2
8
8
  * @since 0.0.1
9
9
  * @author AMBROISE PARK Consulting
10
10
  */
@@ -13,8 +13,8 @@ import { cn } from '../../utils/helpers';
13
13
  /**
14
14
  * Textarea component with ref forwarding.
15
15
  */
16
- const Textarea = forwardRef(({ className, ...props }, ref) => {
17
- return (_jsx("textarea", { ref: ref, className: cn('dndev-input', className), ...props }));
16
+ const Textarea = forwardRef(({ className, bare, ...props }, ref) => {
17
+ return (_jsx("textarea", { ref: ref, className: cn('dndev-input', className), "data-bare": bare || undefined, ...props }));
18
18
  });
19
19
  Textarea.displayName = 'Textarea';
20
20
  export default Textarea;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @fileoverview Toast Types
3
+ * @description Type definitions for toast notifications
4
+ *
5
+ * @version 0.0.1
6
+ * @since 0.0.1
7
+ * @author AMBROISE PARK Consulting
8
+ */
9
+ /**
10
+ * Toast type variants
11
+ *
12
+ * @version 0.0.1
13
+ * @since 0.0.1
14
+ * @author AMBROISE PARK Consulting
15
+ */
16
+ export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info';
17
+ //# sourceMappingURL=Toast.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast.types.d.ts","sourceRoot":"","sources":["../../../src/atomic/Toaster/Toast.types.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ // packages/components/src/atomic/Toaster/Toast.types.ts
2
+ export {};
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import * as ToastPrimitives from '@radix-ui/react-toast';
10
10
  import { type VariantProps } from 'class-variance-authority';
11
- import type { ToastType } from '../../hooks/useToast';
11
+ import type { ToastType } from './Toast.types';
12
12
  import type { ComponentProps, ReactElement } from 'react';
13
13
  declare const ToastProvider: import("react").FC<ToastPrimitives.ToastProviderProps>;
14
14
  declare function ToastViewport({ className, ...props }: ComponentProps<typeof ToastPrimitives.Viewport>): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"ToastPrimitive.d.ts","sourceRoot":"","sources":["../../../src/atomic/Toaster/ToastPrimitive.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAKlE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1D,QAAA,MAAM,aAAa,wDAA2B,CAAC;AAE/C,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,QAAQ,CAAC,2CAOjD;AAED,QAAA,MAAM,aAAa;;8EAajB,CAAC;AAEH,UAAU,UACR,SACE,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,EAC3C,YAAY,CAAC,OAAO,aAAa,CAAC;IACpC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,KAAK,kBAAkB,GAAG,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AAE3D,iBAAS,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,2CA6BrE;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,2CAQ/C;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,2CAyB9C;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,2CAO9C;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,WAAW,CAAC,2CAOpD;AAED,eAAe,KAAK,CAAC;AACrB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,aAAa,EACb,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,WAAW,GACZ,CAAC"}
1
+ {"version":3,"file":"ToastPrimitive.d.ts","sourceRoot":"","sources":["../../../src/atomic/Toaster/ToastPrimitive.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAKlE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1D,QAAA,MAAM,aAAa,wDAA2B,CAAC;AAE/C,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,QAAQ,CAAC,2CAOjD;AAED,QAAA,MAAM,aAAa;;8EAajB,CAAC;AAEH,UAAU,UACR,SACE,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,EAC3C,YAAY,CAAC,OAAO,aAAa,CAAC;IACpC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,KAAK,kBAAkB,GAAG,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AAE3D,iBAAS,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,2CA6BrE;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,MAAM,CAAC,2CAQ/C;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,2CAyB9C;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,2CAO9C;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,eAAe,CAAC,WAAW,CAAC,2CAOpD;AAED,eAAe,KAAK,CAAC;AACrB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,aAAa,EACb,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,WAAW,GACZ,CAAC"}
@@ -97,7 +97,17 @@ export interface VideoPlayerProps {
97
97
  * @default true
98
98
  */
99
99
  allowFullscreen?: boolean;
100
+ /**
101
+ * Aria label for the play button/thumbnail
102
+ * @default 'Click to watch video'
103
+ */
104
+ playButtonLabel?: string;
105
+ /**
106
+ * Aria label for loading state
107
+ * @default 'Loading video'
108
+ */
109
+ loadingLabel?: string;
100
110
  }
101
- declare const VideoPlayer: ({ url, trigger, thumbnail, eager, title, modal, aspectRatio, className, autoplay, allowFullscreen, }: VideoPlayerProps) => import("react/jsx-runtime").JSX.Element;
111
+ declare const VideoPlayer: ({ url, trigger, thumbnail, eager, title, modal, aspectRatio, className, autoplay, allowFullscreen, playButtonLabel, loadingLabel, }: VideoPlayerProps) => import("react/jsx-runtime").JSX.Element;
102
112
  export default VideoPlayer;
103
113
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/VideoPlayer/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,eAAe;IACf,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,qFAAqF;IACrF,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA4JD,QAAA,MAAM,WAAW,GAAI,sGAWlB,gBAAgB,4CAwJlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atomic/VideoPlayer/index.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,eAAe;IACf,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,qFAAqF;IACrF,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA4JD,QAAA,MAAM,WAAW,GAAI,qIAalB,gBAAgB,4CAuJlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -9,9 +9,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  * @author AMBROISE PARK Consulting
10
10
  */
11
11
  import { Play } from 'lucide-react';
12
- import { useState, useEffect, useRef } from 'react';
13
- import { useIntersectionObserver } from '@donotdev/components';
14
- import { useTranslation } from '@donotdev/core';
12
+ import { useState, useEffect } from 'react';
13
+ import { useIntersectionObserver } from '../../hooks/useIntersectionObserver';
15
14
  import { cn } from '../../utils/helpers';
16
15
  import Button, { BUTTON_VARIANT } from '../Button';
17
16
  import Dialog from '../Dialog';
@@ -139,8 +138,7 @@ const getThumbnailUrl = (urlOrConfig) => {
139
138
  * Lazy-loads actual thumbnail on intersection
140
139
  */
141
140
  const VideoPlaceholder = ({ aspectRatio, className, }) => (_jsxs("svg", { className: cn('dndev-video-placeholder', className), viewBox: "0 0 16 9", style: { aspectRatio, width: '100%', display: 'block' }, preserveAspectRatio: "xMidYMid meet", "aria-hidden": "true", children: [_jsx("rect", { width: "16", height: "9", fill: "var(--muted)" }), _jsx("circle", { cx: "8", cy: "4.5", r: "1.5", fill: "var(--foreground)", opacity: "0.8" }), _jsx("path", { d: "M7 3.5L7 5.5L9 4.5Z", fill: "var(--background)" })] }));
142
- const VideoPlayer = ({ url = { platform: 'youtube', id: 'dQw4w9WgXcQ' }, trigger, thumbnail, eager = false, title = 'Video', modal = true, aspectRatio = '16/9', className, autoplay = false, allowFullscreen = true, }) => {
143
- const { t } = useTranslation(['dndev']);
141
+ const VideoPlayer = ({ url = { platform: 'youtube', id: 'dQw4w9WgXcQ' }, trigger, thumbnail, eager = false, title = 'Video', modal = true, aspectRatio = '16/9', className, autoplay = false, allowFullscreen = true, playButtonLabel = 'Click to watch video', loadingLabel = 'Loading video', }) => {
144
142
  const [isOpen, setIsOpen] = useState(false);
145
143
  const [isLoaded, setIsLoaded] = useState(false);
146
144
  const [iframeReady, setIframeReady] = useState(false);
@@ -176,17 +174,17 @@ const VideoPlayer = ({ url = { platform: 'youtube', id: 'dQw4w9WgXcQ' }, trigger
176
174
  e.preventDefault();
177
175
  setIsLoaded(true);
178
176
  }
179
- }, className: cn('dndev-video-thumbnail', className), style: { aspectRatio }, "aria-label": t('video.clickToWatch', 'Click to watch video'), children: [thumbnailLoaded && thumbnailUrl ? (_jsx("img", { src: thumbnailUrl, alt: title, loading: "eager", fetchPriority: "high", decoding: "async" })) : (_jsx(VideoPlaceholder, { aspectRatio: aspectRatio })), _jsx("div", { className: "dndev-video-play-overlay", children: _jsx(Play, { className: "dndev-video-play-icon" }) })] }));
177
+ }, className: cn('dndev-video-thumbnail', className), style: { aspectRatio }, "aria-label": playButtonLabel, children: [thumbnailLoaded && thumbnailUrl ? (_jsx("img", { src: thumbnailUrl, alt: title, loading: "eager", fetchPriority: "high", decoding: "async" })) : (_jsx(VideoPlaceholder, { aspectRatio: aspectRatio })), _jsx("div", { className: "dndev-video-play-overlay", children: _jsx(Play, { className: "dndev-video-play-icon" }) })] }));
180
178
  }
181
179
  // Clicked - show iframe with thumbnail overlay until iframe loads
182
180
  return (_jsxs("div", { className: cn('dndev-video-container', className), style: { aspectRatio, position: 'relative' }, children: [videoFrame, !iframeReady && thumbnailUrl && (_jsxs("div", { className: "dndev-video-thumbnail dndev-video-loading-overlay", style: {
183
181
  position: 'absolute',
184
182
  inset: 0,
185
183
  pointerEvents: 'none',
186
- }, children: [_jsx("img", { src: thumbnailUrl, alt: title, loading: "eager", decoding: "async" }), _jsx("div", { className: "dndev-video-play-overlay dndev-video-loading", children: _jsx(Spinner, { "aria-label": t('video.loading', 'Loading video') }) })] }))] }));
184
+ }, children: [_jsx("img", { src: thumbnailUrl, alt: title, loading: "eager", decoding: "async" }), _jsx("div", { className: "dndev-video-play-overlay dndev-video-loading", children: _jsx(Spinner, { "aria-label": loadingLabel }) })] }))] }));
187
185
  }
188
186
  // Modal mode - lazy-load iframe when modal opens
189
- const defaultTrigger = (_jsxs("button", { ref: thumbnailRef, type: "button", className: "dndev-video-thumbnail", style: { aspectRatio }, "aria-label": t('video.clickToWatch', 'Click to watch video'), children: [thumbnailLoaded && thumbnailUrl ? (_jsx("img", { src: thumbnailUrl, alt: title, loading: "eager", fetchPriority: "high", decoding: "async" })) : (_jsx(VideoPlaceholder, { aspectRatio: aspectRatio })), _jsx("div", { className: "dndev-video-play-overlay", children: _jsx(Play, { className: "dndev-video-play-icon" }) })] }));
187
+ const defaultTrigger = (_jsxs("button", { ref: thumbnailRef, type: "button", className: "dndev-video-thumbnail", style: { aspectRatio }, "aria-label": playButtonLabel, children: [thumbnailLoaded && thumbnailUrl ? (_jsx("img", { src: thumbnailUrl, alt: title, loading: "eager", fetchPriority: "high", decoding: "async" })) : (_jsx(VideoPlaceholder, { aspectRatio: aspectRatio })), _jsx("div", { className: "dndev-video-play-overlay", children: _jsx(Play, { className: "dndev-video-play-icon" }) })] }));
190
188
  return (_jsx(Dialog, { trigger: trigger || defaultTrigger, title: title, open: isOpen, onOpenChange: setIsOpen, showClose: true, className: "dndev-video-dialog", children: videoFrame }));
191
189
  };
192
190
  export default VideoPlayer;
@@ -105,6 +105,8 @@ export type { ProgressProps } from './Progress';
105
105
  export { default as RadioGroup } from './RadioGroup';
106
106
  export * from './RadioGroup/RadioGroupPrimitive';
107
107
  export type { RadioOption, RadioGroupProps, RadioGroupVariant, } from './RadioGroup';
108
+ export { default as RangeInput } from './RangeInput';
109
+ export type { RangeInputProps } from './RangeInput';
108
110
  export { default as ScrollArea, ScrollBar } from './ScrollArea';
109
111
  export * from './ScrollArea/ScrollAreaPrimitive';
110
112
  export type { ScrollAreaProps, ScrollBarProps } from './ScrollArea';