@dev-dga/react 0.9.1 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/chunk-B6ODWTVF.js +1 -0
  3. package/dist/chunk-CZCIERDM.cjs +1 -0
  4. package/dist/{chunk-M46YSH6K.cjs.map → chunk-CZCIERDM.cjs.map} +1 -1
  5. package/dist/{chunk-YJQZQS7P.js → chunk-GNL72FRN.js} +2 -2
  6. package/dist/chunk-HIZSEYQY.js +35 -0
  7. package/dist/chunk-HIZSEYQY.js.map +1 -0
  8. package/dist/chunk-J7GWUCFM.cjs +35 -0
  9. package/dist/chunk-J7GWUCFM.cjs.map +1 -0
  10. package/dist/{chunk-H4B2B4SV.cjs → chunk-KRIWNW4A.cjs} +1 -1
  11. package/dist/{chunk-H4B2B4SV.cjs.map → chunk-KRIWNW4A.cjs.map} +1 -1
  12. package/dist/{chunk-W6B7GJLN.cjs → chunk-NU3WUSG7.cjs} +2 -2
  13. package/dist/chunk-NU3WUSG7.cjs.map +1 -0
  14. package/dist/{chunk-FWGFOC2T.js → chunk-RSXDPFXK.js} +2 -2
  15. package/dist/chunk-RSXDPFXK.js.map +1 -0
  16. package/dist/{chunk-UAECZXU5.js → chunk-TXQK3BAO.js} +9 -2
  17. package/dist/{chunk-UAECZXU5.js.map → chunk-TXQK3BAO.js.map} +1 -1
  18. package/dist/{chunk-2HZGIP5V.cjs → chunk-VMAJ34DC.cjs} +3 -3
  19. package/dist/{chunk-2HZGIP5V.cjs.map → chunk-VMAJ34DC.cjs.map} +1 -1
  20. package/dist/{chunk-PAUY27WX.cjs → chunk-VYOETLZU.cjs} +9 -2
  21. package/dist/chunk-VYOETLZU.cjs.map +1 -0
  22. package/dist/{chunk-TO7F4EHC.js → chunk-WOJUO43J.js} +1 -1
  23. package/dist/chunk-WOJUO43J.js.map +1 -0
  24. package/dist/components/FileUpload/FileUpload.cjs +3 -3
  25. package/dist/components/FileUpload/FileUpload.js +2 -2
  26. package/dist/components/FileUpload/index.cjs +3 -3
  27. package/dist/components/FileUpload/index.js +2 -2
  28. package/dist/components/Pagination/index.cjs +6 -2
  29. package/dist/components/Pagination/index.cjs.map +1 -1
  30. package/dist/components/Pagination/index.js +5 -1
  31. package/dist/components/Pagination/paginationRange.cjs +7 -0
  32. package/dist/components/Pagination/paginationRange.cjs.map +1 -0
  33. package/dist/components/Pagination/paginationRange.js +7 -0
  34. package/dist/components/Pagination/paginationRange.js.map +1 -0
  35. package/dist/components/Progress/Progress.cjs +2 -2
  36. package/dist/components/Progress/Progress.js +1 -1
  37. package/dist/components/Progress/index.cjs +2 -2
  38. package/dist/components/Progress/index.js +1 -1
  39. package/dist/components/ScrollArea/ScrollArea.cjs +2 -2
  40. package/dist/components/ScrollArea/ScrollArea.js +1 -1
  41. package/dist/components/ScrollArea/index.cjs +2 -2
  42. package/dist/components/ScrollArea/index.js +1 -1
  43. package/dist/components/Sidebar/SidebarMenu.cjs +1 -1
  44. package/dist/components/Sidebar/SidebarMenu.js +1 -1
  45. package/dist/components/Sidebar/index.cjs +1 -1
  46. package/dist/components/Sidebar/index.cjs.map +1 -1
  47. package/dist/components/Sidebar/index.js +1 -1
  48. package/dist/components/Stat/Stat.cjs +2 -2
  49. package/dist/components/Stat/Stat.js +1 -1
  50. package/dist/components/Stat/index.cjs +2 -2
  51. package/dist/components/Stat/index.js +1 -1
  52. package/dist/index.cjs +30 -26
  53. package/dist/index.cjs.map +1 -1
  54. package/dist/index.d.cts +41 -1
  55. package/dist/index.d.ts +41 -1
  56. package/dist/index.js +38 -34
  57. package/package.json +3 -3
  58. package/dist/chunk-FWGFOC2T.js.map +0 -1
  59. package/dist/chunk-KPONZTP7.js +0 -1
  60. package/dist/chunk-M46YSH6K.cjs +0 -1
  61. package/dist/chunk-PAUY27WX.cjs.map +0 -1
  62. package/dist/chunk-TO7F4EHC.js.map +0 -1
  63. package/dist/chunk-W6B7GJLN.cjs.map +0 -1
  64. /package/dist/{chunk-KPONZTP7.js.map → chunk-B6ODWTVF.js.map} +0 -0
  65. /package/dist/{chunk-YJQZQS7P.js.map → chunk-GNL72FRN.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @dev-dga/react
2
2
 
3
+ ## 0.10.1
4
+
5
+ ### Patch Changes
6
+
7
+ - **Progress — the determinate bar fills the correct direction in RTL.** The fill used a physical `translateX(${pct - 100}%)`, which always slides left — so under `dir="rtl"` the bar mirrored as an LTR fill. It now sizes the indicator via the logical `inline-size` (anchored to the track's inline-start), so it fills from the right in RTL automatically, with no JS direction read. No API change — bars simply mirror correctly. Also adds a repo gate (a test that flags new physical-direction CSS / inline `translateX` in source). Rides the `@dev-dga/css` change in lockstep.
8
+
9
+ ## 0.10.0
10
+
11
+ ### Minor Changes
12
+
13
+ - **Pagination — new `paginationRange(page, count, { siblings, boundaries })` util.** Computes the page-window slots (page numbers interleaved with `'ellipsis'`) so consumers stop hand-rolling the logic. Guarantees a **constant slot count** once the count exceeds the window, so the pager keeps a fixed width while navigating — buttons don't shift under the cursor (when a gap is exactly one page it shows the page instead of an ellipsis, preserving the length). Pair it with the existing `Pagination*` parts; exported types `PaginationSlot` / `PaginationRangeOptions`.
14
+
15
+ ### Patch Changes
16
+
17
+ - **ScrollArea — wide content is no longer clipped in a vertical scroll area.** A vertical-orientation `ScrollArea` now constrains Radix's inline `display:table` content wrapper (a `--vertical` viewport modifier + matching CSS) so a wider-than-viewport child (e.g. a `Table`) stays at viewport width and scrolls its own overflow instead of expanding past the viewport with its trailing columns unreachable (worst on mobile, which has no horizontal scrollbar in vertical mode). `horizontal` / `both` orientations are unchanged. **You can delete any `[data-radix-scroll-area-viewport] > div { display: block !important }` workaround.**
18
+ - **Stat — docs.** JSDoc clarifies the supported composition: prop mode (`label` / `value` / `change` / `trend` / `icon`) **plus** a `<StatChart>` child is the blessed hybrid; don't duplicate a prop slot as a child (e.g. a `value` prop _and_ a `<StatValue>` child) — both render.
19
+ - Rides the `@dev-dga/css` ScrollArea + StatGroup fixes in lockstep. Released in lockstep with `@dev-dga/css` and `@dev-dga/tokens`.
20
+
3
21
  ## 0.9.1
4
22
 
5
23
  ### Patch Changes
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-B6ODWTVF.js.map
@@ -0,0 +1 @@
1
+ "use strict";//# sourceMappingURL=chunk-CZCIERDM.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-M46YSH6K.cjs"],"names":[],"mappings":"AAAA","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-M46YSH6K.cjs"}
1
+ {"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-CZCIERDM.cjs"],"names":[],"mappings":"AAAA","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-CZCIERDM.cjs"}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Progress
3
- } from "./chunk-FWGFOC2T.js";
3
+ } from "./chunk-RSXDPFXK.js";
4
4
  import {
5
5
  Button
6
6
  } from "./chunk-4RU33BRQ.js";
@@ -221,4 +221,4 @@ function FileUpload({
221
221
  export {
222
222
  FileUpload
223
223
  };
224
- //# sourceMappingURL=chunk-YJQZQS7P.js.map
224
+ //# sourceMappingURL=chunk-GNL72FRN.js.map
@@ -0,0 +1,35 @@
1
+ // src/components/Pagination/paginationRange.ts
2
+ var range = (start, end) => start > end ? [] : Array.from({ length: end - start + 1 }, (_, i) => start + i);
3
+ function paginationRange(page, count, options = {}) {
4
+ const siblings = Math.max(0, Math.trunc(options.siblings ?? 1));
5
+ const boundaries = Math.max(0, Math.trunc(options.boundaries ?? 1));
6
+ const total = Math.max(0, Math.trunc(count));
7
+ if (total === 0) return [];
8
+ const current = Math.min(Math.max(1, Math.trunc(page)), total);
9
+ const windowSize = boundaries * 2 + siblings * 2 + 3;
10
+ if (windowSize >= total) return range(1, total);
11
+ const startPages = range(1, boundaries);
12
+ const endPages = range(total - boundaries + 1, total);
13
+ const siblingsStart = Math.max(
14
+ Math.min(current - siblings, total - boundaries - siblings * 2 - 1),
15
+ boundaries + 2
16
+ );
17
+ const siblingsEnd = Math.min(
18
+ Math.max(current + siblings, boundaries + siblings * 2 + 2),
19
+ endPages.length > 0 ? endPages[0] - 2 : total - 1
20
+ );
21
+ const leftGap = siblingsStart > boundaries + 2 ? ["ellipsis"] : boundaries + 1 < total - boundaries ? [boundaries + 1] : [];
22
+ const rightGap = siblingsEnd < total - boundaries - 1 ? ["ellipsis"] : total - boundaries > boundaries ? [total - boundaries] : [];
23
+ return [
24
+ ...startPages,
25
+ ...leftGap,
26
+ ...range(siblingsStart, siblingsEnd),
27
+ ...rightGap,
28
+ ...endPages
29
+ ];
30
+ }
31
+
32
+ export {
33
+ paginationRange
34
+ };
35
+ //# sourceMappingURL=chunk-HIZSEYQY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Pagination/paginationRange.ts"],"sourcesContent":["export type PaginationSlot = number | 'ellipsis';\n\nexport interface PaginationRangeOptions {\n /** Pages shown on each side of the current page. Default `1`. */\n siblings?: number;\n /** Pages pinned at the very start and end. Default `1`. */\n boundaries?: number;\n}\n\nconst range = (start: number, end: number): number[] =>\n start > end ? [] : Array.from({ length: end - start + 1 }, (_, i) => start + i);\n\n/**\n * Compute which page slots a pager should render — page numbers interleaved with\n * `'ellipsis'` markers — so consumers don't hand-roll the windowing logic.\n *\n * **Constant-width invariant:** once the page count exceeds the visible window\n * (`boundaries * 2 + siblings * 2 + 3`), the returned array is the **same length\n * for every `page`**. That keeps the pager a constant width while navigating, so\n * the buttons don't shift under the cursor. When collapsing a gap would hide\n * exactly one page, that page is shown instead of an `'ellipsis'` (same length).\n *\n * Pair it with the `Pagination*` parts (`PaginationItem` / `PaginationLink` /\n * `PaginationEllipsis`).\n *\n * @param page Current page, 1-based (clamped to `[1, count]`).\n * @param count Total number of pages.\n * @returns Slots to render, e.g. `[1, 'ellipsis', 9, 10, 11, 'ellipsis', 20]`.\n */\nexport function paginationRange(\n page: number,\n count: number,\n options: PaginationRangeOptions = {},\n): PaginationSlot[] {\n const siblings = Math.max(0, Math.trunc(options.siblings ?? 1));\n const boundaries = Math.max(0, Math.trunc(options.boundaries ?? 1));\n const total = Math.max(0, Math.trunc(count));\n if (total === 0) return [];\n const current = Math.min(Math.max(1, Math.trunc(page)), total);\n\n // Slots when the full window is shown with both ellipses: start boundary + end\n // boundary + current + 2 ellipses + siblings on each side.\n const windowSize = boundaries * 2 + siblings * 2 + 3;\n // Everything fits → list every page (the constant-length rule only applies past\n // this threshold).\n if (windowSize >= total) return range(1, total);\n\n const startPages = range(1, boundaries);\n const endPages = range(total - boundaries + 1, total);\n\n const siblingsStart = Math.max(\n Math.min(current - siblings, total - boundaries - siblings * 2 - 1),\n boundaries + 2,\n );\n const siblingsEnd = Math.min(\n Math.max(current + siblings, boundaries + siblings * 2 + 2),\n endPages.length > 0 ? endPages[0] - 2 : total - 1,\n );\n\n // Left gap: an ellipsis — unless collapsing would hide exactly one page, in\n // which case show that page (keeps the slot count constant).\n const leftGap: PaginationSlot[] =\n siblingsStart > boundaries + 2\n ? ['ellipsis']\n : boundaries + 1 < total - boundaries\n ? [boundaries + 1]\n : [];\n const rightGap: PaginationSlot[] =\n siblingsEnd < total - boundaries - 1\n ? ['ellipsis']\n : total - boundaries > boundaries\n ? [total - boundaries]\n : [];\n\n return [\n ...startPages,\n ...leftGap,\n ...range(siblingsStart, siblingsEnd),\n ...rightGap,\n ...endPages,\n ];\n}\n"],"mappings":";AASA,IAAM,QAAQ,CAAC,OAAe,QAC5B,QAAQ,MAAM,CAAC,IAAI,MAAM,KAAK,EAAE,QAAQ,MAAM,QAAQ,EAAE,GAAG,CAAC,GAAG,MAAM,QAAQ,CAAC;AAmBzE,SAAS,gBACd,MACA,OACA,UAAkC,CAAC,GACjB;AAClB,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,YAAY,CAAC,CAAC;AAC9D,QAAM,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,cAAc,CAAC,CAAC;AAClE,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AAC3C,MAAI,UAAU,EAAG,QAAO,CAAC;AACzB,QAAM,UAAU,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,GAAG,KAAK;AAI7D,QAAM,aAAa,aAAa,IAAI,WAAW,IAAI;AAGnD,MAAI,cAAc,MAAO,QAAO,MAAM,GAAG,KAAK;AAE9C,QAAM,aAAa,MAAM,GAAG,UAAU;AACtC,QAAM,WAAW,MAAM,QAAQ,aAAa,GAAG,KAAK;AAEpD,QAAM,gBAAgB,KAAK;AAAA,IACzB,KAAK,IAAI,UAAU,UAAU,QAAQ,aAAa,WAAW,IAAI,CAAC;AAAA,IAClE,aAAa;AAAA,EACf;AACA,QAAM,cAAc,KAAK;AAAA,IACvB,KAAK,IAAI,UAAU,UAAU,aAAa,WAAW,IAAI,CAAC;AAAA,IAC1D,SAAS,SAAS,IAAI,SAAS,CAAC,IAAI,IAAI,QAAQ;AAAA,EAClD;AAIA,QAAM,UACJ,gBAAgB,aAAa,IACzB,CAAC,UAAU,IACX,aAAa,IAAI,QAAQ,aACvB,CAAC,aAAa,CAAC,IACf,CAAC;AACT,QAAM,WACJ,cAAc,QAAQ,aAAa,IAC/B,CAAC,UAAU,IACX,QAAQ,aAAa,aACnB,CAAC,QAAQ,UAAU,IACnB,CAAC;AAET,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG,MAAM,eAAe,WAAW;AAAA,IACnC,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACF;","names":[]}
@@ -0,0 +1,35 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/components/Pagination/paginationRange.ts
2
+ var range = (start, end) => start > end ? [] : Array.from({ length: end - start + 1 }, (_, i) => start + i);
3
+ function paginationRange(page, count, options = {}) {
4
+ const siblings = Math.max(0, Math.trunc(_nullishCoalesce(options.siblings, () => ( 1))));
5
+ const boundaries = Math.max(0, Math.trunc(_nullishCoalesce(options.boundaries, () => ( 1))));
6
+ const total = Math.max(0, Math.trunc(count));
7
+ if (total === 0) return [];
8
+ const current = Math.min(Math.max(1, Math.trunc(page)), total);
9
+ const windowSize = boundaries * 2 + siblings * 2 + 3;
10
+ if (windowSize >= total) return range(1, total);
11
+ const startPages = range(1, boundaries);
12
+ const endPages = range(total - boundaries + 1, total);
13
+ const siblingsStart = Math.max(
14
+ Math.min(current - siblings, total - boundaries - siblings * 2 - 1),
15
+ boundaries + 2
16
+ );
17
+ const siblingsEnd = Math.min(
18
+ Math.max(current + siblings, boundaries + siblings * 2 + 2),
19
+ endPages.length > 0 ? endPages[0] - 2 : total - 1
20
+ );
21
+ const leftGap = siblingsStart > boundaries + 2 ? ["ellipsis"] : boundaries + 1 < total - boundaries ? [boundaries + 1] : [];
22
+ const rightGap = siblingsEnd < total - boundaries - 1 ? ["ellipsis"] : total - boundaries > boundaries ? [total - boundaries] : [];
23
+ return [
24
+ ...startPages,
25
+ ...leftGap,
26
+ ...range(siblingsStart, siblingsEnd),
27
+ ...rightGap,
28
+ ...endPages
29
+ ];
30
+ }
31
+
32
+
33
+
34
+ exports.paginationRange = paginationRange;
35
+ //# sourceMappingURL=chunk-J7GWUCFM.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-J7GWUCFM.cjs","../src/components/Pagination/paginationRange.ts"],"names":[],"mappings":"AAAA;ACSA,IAAM,MAAA,EAAQ,CAAC,KAAA,EAAe,GAAA,EAAA,GAC5B,MAAA,EAAQ,IAAA,EAAM,CAAC,EAAA,EAAI,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAQ,EAAE,CAAA,EAAG,CAAC,CAAA,EAAG,CAAA,EAAA,GAAM,MAAA,EAAQ,CAAC,CAAA;AAmBzE,SAAS,eAAA,CACd,IAAA,EACA,KAAA,EACA,QAAA,EAAkC,CAAC,CAAA,EACjB;AAClB,EAAA,MAAM,SAAA,EAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,kBAAM,OAAA,CAAQ,QAAA,UAAY,GAAC,CAAC,CAAA;AAC9D,EAAA,MAAM,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,kBAAM,OAAA,CAAQ,UAAA,UAAc,GAAC,CAAC,CAAA;AAClE,EAAA,MAAM,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAC3C,EAAA,GAAA,CAAI,MAAA,IAAU,CAAA,EAAG,OAAO,CAAC,CAAA;AACzB,EAAA,MAAM,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,IAAI,CAAC,CAAA,EAAG,KAAK,CAAA;AAI7D,EAAA,MAAM,WAAA,EAAa,WAAA,EAAa,EAAA,EAAI,SAAA,EAAW,EAAA,EAAI,CAAA;AAGnD,EAAA,GAAA,CAAI,WAAA,GAAc,KAAA,EAAO,OAAO,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAE9C,EAAA,MAAM,WAAA,EAAa,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA;AACtC,EAAA,MAAM,SAAA,EAAW,KAAA,CAAM,MAAA,EAAQ,WAAA,EAAa,CAAA,EAAG,KAAK,CAAA;AAEpD,EAAA,MAAM,cAAA,EAAgB,IAAA,CAAK,GAAA;AAAA,IACzB,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,QAAA,EAAU,MAAA,EAAQ,WAAA,EAAa,SAAA,EAAW,EAAA,EAAI,CAAC,CAAA;AAAA,IAClE,WAAA,EAAa;AAAA,EACf,CAAA;AACA,EAAA,MAAM,YAAA,EAAc,IAAA,CAAK,GAAA;AAAA,IACvB,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,QAAA,EAAU,WAAA,EAAa,SAAA,EAAW,EAAA,EAAI,CAAC,CAAA;AAAA,IAC1D,QAAA,CAAS,OAAA,EAAS,EAAA,EAAI,QAAA,CAAS,CAAC,EAAA,EAAI,EAAA,EAAI,MAAA,EAAQ;AAAA,EAClD,CAAA;AAIA,EAAA,MAAM,QAAA,EACJ,cAAA,EAAgB,WAAA,EAAa,EAAA,EACzB,CAAC,UAAU,EAAA,EACX,WAAA,EAAa,EAAA,EAAI,MAAA,EAAQ,WAAA,EACvB,CAAC,WAAA,EAAa,CAAC,EAAA,EACf,CAAC,CAAA;AACT,EAAA,MAAM,SAAA,EACJ,YAAA,EAAc,MAAA,EAAQ,WAAA,EAAa,EAAA,EAC/B,CAAC,UAAU,EAAA,EACX,MAAA,EAAQ,WAAA,EAAa,WAAA,EACnB,CAAC,MAAA,EAAQ,UAAU,EAAA,EACnB,CAAC,CAAA;AAET,EAAA,OAAO;AAAA,IACL,GAAG,UAAA;AAAA,IACH,GAAG,OAAA;AAAA,IACH,GAAG,KAAA,CAAM,aAAA,EAAe,WAAW,CAAA;AAAA,IACnC,GAAG,QAAA;AAAA,IACH,GAAG;AAAA,EACL,CAAA;AACF;ADnDA;AACA;AACE;AACF,0CAAC","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-J7GWUCFM.cjs","sourcesContent":[null,"export type PaginationSlot = number | 'ellipsis';\n\nexport interface PaginationRangeOptions {\n /** Pages shown on each side of the current page. Default `1`. */\n siblings?: number;\n /** Pages pinned at the very start and end. Default `1`. */\n boundaries?: number;\n}\n\nconst range = (start: number, end: number): number[] =>\n start > end ? [] : Array.from({ length: end - start + 1 }, (_, i) => start + i);\n\n/**\n * Compute which page slots a pager should render — page numbers interleaved with\n * `'ellipsis'` markers — so consumers don't hand-roll the windowing logic.\n *\n * **Constant-width invariant:** once the page count exceeds the visible window\n * (`boundaries * 2 + siblings * 2 + 3`), the returned array is the **same length\n * for every `page`**. That keeps the pager a constant width while navigating, so\n * the buttons don't shift under the cursor. When collapsing a gap would hide\n * exactly one page, that page is shown instead of an `'ellipsis'` (same length).\n *\n * Pair it with the `Pagination*` parts (`PaginationItem` / `PaginationLink` /\n * `PaginationEllipsis`).\n *\n * @param page Current page, 1-based (clamped to `[1, count]`).\n * @param count Total number of pages.\n * @returns Slots to render, e.g. `[1, 'ellipsis', 9, 10, 11, 'ellipsis', 20]`.\n */\nexport function paginationRange(\n page: number,\n count: number,\n options: PaginationRangeOptions = {},\n): PaginationSlot[] {\n const siblings = Math.max(0, Math.trunc(options.siblings ?? 1));\n const boundaries = Math.max(0, Math.trunc(options.boundaries ?? 1));\n const total = Math.max(0, Math.trunc(count));\n if (total === 0) return [];\n const current = Math.min(Math.max(1, Math.trunc(page)), total);\n\n // Slots when the full window is shown with both ellipses: start boundary + end\n // boundary + current + 2 ellipses + siblings on each side.\n const windowSize = boundaries * 2 + siblings * 2 + 3;\n // Everything fits → list every page (the constant-length rule only applies past\n // this threshold).\n if (windowSize >= total) return range(1, total);\n\n const startPages = range(1, boundaries);\n const endPages = range(total - boundaries + 1, total);\n\n const siblingsStart = Math.max(\n Math.min(current - siblings, total - boundaries - siblings * 2 - 1),\n boundaries + 2,\n );\n const siblingsEnd = Math.min(\n Math.max(current + siblings, boundaries + siblings * 2 + 2),\n endPages.length > 0 ? endPages[0] - 2 : total - 1,\n );\n\n // Left gap: an ellipsis — unless collapsing would hide exactly one page, in\n // which case show that page (keeps the slot count constant).\n const leftGap: PaginationSlot[] =\n siblingsStart > boundaries + 2\n ? ['ellipsis']\n : boundaries + 1 < total - boundaries\n ? [boundaries + 1]\n : [];\n const rightGap: PaginationSlot[] =\n siblingsEnd < total - boundaries - 1\n ? ['ellipsis']\n : total - boundaries > boundaries\n ? [total - boundaries]\n : [];\n\n return [\n ...startPages,\n ...leftGap,\n ...range(siblingsStart, siblingsEnd),\n ...rightGap,\n ...endPages,\n ];\n}\n"]}
@@ -128,4 +128,4 @@ function StatChange({ trend, sentiment, variant, className, children, ...props }
128
128
 
129
129
 
130
130
  exports.statVariants = statVariants; exports.Stat = Stat; exports.StatLabel = StatLabel; exports.StatValue = StatValue; exports.StatChart = StatChart; exports.StatChange = StatChange;
131
- //# sourceMappingURL=chunk-H4B2B4SV.cjs.map
131
+ //# sourceMappingURL=chunk-KRIWNW4A.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-H4B2B4SV.cjs","../src/components/Stat/Stat.tsx"],"names":[],"mappings":"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","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-H4B2B4SV.cjs","sourcesContent":[null,"'use client';\n\nimport { type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { CaretUp, CaretDown, Minus } from '../../internal/icons';\n\n// ─── 1. Variants (cva) ─── //\n\nconst statVariants = cva('ddga-stat', {\n variants: {\n variant: {\n flat: 'ddga-stat--flat',\n elevated: 'ddga-stat--elevated',\n accent: 'ddga-stat--accent',\n // Soft sentiment-tinted gradient surface (reuses the accent tint vars).\n gradient: 'ddga-stat--gradient',\n },\n size: {\n sm: 'ddga-stat--sm',\n md: 'ddga-stat--md',\n lg: 'ddga-stat--lg',\n // Hero/display size for headline KPIs (display-scale value).\n xl: 'ddga-stat--xl',\n },\n },\n defaultVariants: {\n variant: 'flat',\n size: 'md',\n },\n});\n\ntype ChangeVariant = 'text' | 'chip';\n\ntype Trend = 'up' | 'down' | 'flat';\ntype Sentiment = 'positive' | 'negative' | 'neutral';\n\n// trend → caret icon (carried aria-hidden; carets are RTL-neutral).\nconst TREND_ICONS: Record<Trend, ReactNode> = {\n up: <CaretUp aria-hidden=\"true\" />,\n down: <CaretDown aria-hidden=\"true\" />,\n flat: <Minus aria-hidden=\"true\" />,\n};\n\n// Default sentiment when none is given explicitly.\nconst TREND_SENTIMENT: Record<Trend, Sentiment> = {\n up: 'positive',\n down: 'negative',\n flat: 'neutral',\n};\n\n// Explicit sentiment wins; else derive from trend; else undefined (no color).\nfunction resolveSentiment(trend?: Trend, sentiment?: Sentiment): Sentiment | undefined {\n if (sentiment) return sentiment;\n if (trend) return TREND_SENTIMENT[trend];\n return undefined;\n}\n\n// ─── 2. Types ─── //\n\ninterface StatProps extends React.ComponentProps<'div'>, VariantProps<typeof statVariants> {\n /** Small, muted label above the value. */\n label?: ReactNode;\n /** The metric, pre-formatted by the consumer (e.g. \"3,204\", \"SAR 1.2M\"). */\n value?: ReactNode;\n /** Change text — include the sign (e.g. \"+12.5%\") so AT conveys direction. */\n change?: ReactNode;\n /** Muted context beside the change (e.g. \"vs last month\"). */\n changeLabel?: ReactNode;\n /** Arrow direction: up → CaretUp, down → CaretDown, flat → Minus. */\n trend?: Trend;\n /** Change color. Omitted → derived from `trend`. Explicit always wins. */\n sentiment?: Sentiment;\n /**\n * How the change renders: `'text'` (default — colored text + caret) or\n * `'chip'` (the same, wrapped in a sentiment-tinted pill). Threaded to the\n * inner `StatChange`.\n */\n changeVariant?: ChangeVariant;\n /** Optional icon at the inline-end of the label row (decorative). */\n icon?: ReactNode;\n}\n\ntype StatLabelProps = React.ComponentProps<'div'>;\ntype StatValueProps = React.ComponentProps<'div'>;\ntype StatChartProps = React.ComponentProps<'div'>;\ninterface StatChangeProps extends React.ComponentProps<'div'> {\n trend?: Trend;\n sentiment?: Sentiment;\n /** `'chip'` wraps the change in a sentiment-tinted pill. Defaults to `'text'`. */\n variant?: ChangeVariant;\n}\n\n// ─── 3. Components ─── //\n\nfunction Stat({\n variant,\n size,\n label,\n value,\n change,\n changeLabel,\n trend,\n sentiment,\n changeVariant,\n icon,\n className,\n children,\n ...props\n}: StatProps) {\n const resolvedSentiment = resolveSentiment(trend, sentiment);\n return (\n <div\n data-slot=\"stat\"\n data-variant={variant ?? 'flat'}\n data-trend={trend}\n data-sentiment={resolvedSentiment}\n className={cn(statVariants({ variant, size }), className)}\n {...props}\n >\n {label || icon ? (\n <div className=\"ddga-stat__label-row\">\n {label ? <StatLabel>{label}</StatLabel> : null}\n {icon ? (\n <span className=\"ddga-stat__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n ) : null}\n </div>\n ) : null}\n {value ? <StatValue>{value}</StatValue> : null}\n {change || changeLabel ? (\n <div className=\"ddga-stat__change-row\">\n {change ? (\n <StatChange trend={trend} sentiment={sentiment} variant={changeVariant}>\n {change}\n </StatChange>\n ) : null}\n {changeLabel ? <span className=\"ddga-stat__change-label\">{changeLabel}</span> : null}\n </div>\n ) : null}\n {children}\n </div>\n );\n}\n\nfunction StatLabel({ className, ...props }: StatLabelProps) {\n return <div data-slot=\"stat-label\" className={cn('ddga-stat__label', className)} {...props} />;\n}\n\nfunction StatValue({ className, ...props }: StatValueProps) {\n return <div data-slot=\"stat-value\" className={cn('ddga-stat__value', className)} {...props} />;\n}\n\n/**\n * Styled slot for a consumer-supplied sparkline / mini-chart. The library ships\n * no charting dependency — drop your own `<svg>`/chart in here and it gets a\n * consistent height + spacing, stretched to the tile width.\n */\nfunction StatChart({ className, ...props }: StatChartProps) {\n return <div data-slot=\"stat-chart\" className={cn('ddga-stat__chart', className)} {...props} />;\n}\n\nfunction StatChange({ trend, sentiment, variant, className, children, ...props }: StatChangeProps) {\n const resolvedSentiment = resolveSentiment(trend, sentiment);\n return (\n <div\n data-slot=\"stat-change\"\n data-trend={trend}\n data-sentiment={resolvedSentiment}\n className={cn(\n 'ddga-stat__change',\n resolvedSentiment ? `ddga-stat__change--${resolvedSentiment}` : null,\n variant === 'chip' && 'ddga-stat__change--chip',\n className,\n )}\n {...props}\n >\n {trend ? <span className=\"ddga-stat__change-icon\">{TREND_ICONS[trend]}</span> : null}\n {children}\n </div>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { Stat, StatLabel, StatValue, StatChart, StatChange, statVariants };\nexport type { StatProps, StatLabelProps, StatValueProps, StatChartProps, StatChangeProps };\n"]}
1
+ {"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-KRIWNW4A.cjs","../src/components/Stat/Stat.tsx"],"names":[],"mappings":"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","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-KRIWNW4A.cjs","sourcesContent":[null,"'use client';\n\nimport { type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { CaretUp, CaretDown, Minus } from '../../internal/icons';\n\n// ─── 1. Variants (cva) ─── //\n\nconst statVariants = cva('ddga-stat', {\n variants: {\n variant: {\n flat: 'ddga-stat--flat',\n elevated: 'ddga-stat--elevated',\n accent: 'ddga-stat--accent',\n // Soft sentiment-tinted gradient surface (reuses the accent tint vars).\n gradient: 'ddga-stat--gradient',\n },\n size: {\n sm: 'ddga-stat--sm',\n md: 'ddga-stat--md',\n lg: 'ddga-stat--lg',\n // Hero/display size for headline KPIs (display-scale value).\n xl: 'ddga-stat--xl',\n },\n },\n defaultVariants: {\n variant: 'flat',\n size: 'md',\n },\n});\n\ntype ChangeVariant = 'text' | 'chip';\n\ntype Trend = 'up' | 'down' | 'flat';\ntype Sentiment = 'positive' | 'negative' | 'neutral';\n\n// trend → caret icon (carried aria-hidden; carets are RTL-neutral).\nconst TREND_ICONS: Record<Trend, ReactNode> = {\n up: <CaretUp aria-hidden=\"true\" />,\n down: <CaretDown aria-hidden=\"true\" />,\n flat: <Minus aria-hidden=\"true\" />,\n};\n\n// Default sentiment when none is given explicitly.\nconst TREND_SENTIMENT: Record<Trend, Sentiment> = {\n up: 'positive',\n down: 'negative',\n flat: 'neutral',\n};\n\n// Explicit sentiment wins; else derive from trend; else undefined (no color).\nfunction resolveSentiment(trend?: Trend, sentiment?: Sentiment): Sentiment | undefined {\n if (sentiment) return sentiment;\n if (trend) return TREND_SENTIMENT[trend];\n return undefined;\n}\n\n// ─── 2. Types ─── //\n\ninterface StatProps extends React.ComponentProps<'div'>, VariantProps<typeof statVariants> {\n /** Small, muted label above the value. */\n label?: ReactNode;\n /** The metric, pre-formatted by the consumer (e.g. \"3,204\", \"SAR 1.2M\"). */\n value?: ReactNode;\n /** Change text — include the sign (e.g. \"+12.5%\") so AT conveys direction. */\n change?: ReactNode;\n /** Muted context beside the change (e.g. \"vs last month\"). */\n changeLabel?: ReactNode;\n /** Arrow direction: up → CaretUp, down → CaretDown, flat → Minus. */\n trend?: Trend;\n /** Change color. Omitted → derived from `trend`. Explicit always wins. */\n sentiment?: Sentiment;\n /**\n * How the change renders: `'text'` (default — colored text + caret) or\n * `'chip'` (the same, wrapped in a sentiment-tinted pill). Threaded to the\n * inner `StatChange`.\n */\n changeVariant?: ChangeVariant;\n /** Optional icon at the inline-end of the label row (decorative). */\n icon?: ReactNode;\n}\n\ntype StatLabelProps = React.ComponentProps<'div'>;\ntype StatValueProps = React.ComponentProps<'div'>;\ntype StatChartProps = React.ComponentProps<'div'>;\ninterface StatChangeProps extends React.ComponentProps<'div'> {\n trend?: Trend;\n sentiment?: Sentiment;\n /** `'chip'` wraps the change in a sentiment-tinted pill. Defaults to `'text'`. */\n variant?: ChangeVariant;\n}\n\n// ─── 3. Components ─── //\n\n/**\n * KPI / metric tile. Two ways to fill it, designed to combine:\n *\n * - **Prop mode** (the common case): pass `label` / `value` / `change` /\n * `changeLabel` / `trend` / `icon` and Stat renders the standard layout.\n * - **Compound children**: append extra content as children — it renders AFTER\n * the prop-mode rows.\n *\n * The blessed hybrid is **prop mode + a `<StatChart>` child** (a sparkline under\n * the metric). Do NOT also pass a child that duplicates a prop slot (e.g. a\n * `value` prop *and* a `<StatValue>` child) — both render and you get a\n * double. One source per slot. Stat owns its surface; use it directly (don't\n * wrap a bare `<Card>`), and lay tiles out with `<StatGroup>`.\n */\nfunction Stat({\n variant,\n size,\n label,\n value,\n change,\n changeLabel,\n trend,\n sentiment,\n changeVariant,\n icon,\n className,\n children,\n ...props\n}: StatProps) {\n const resolvedSentiment = resolveSentiment(trend, sentiment);\n return (\n <div\n data-slot=\"stat\"\n data-variant={variant ?? 'flat'}\n data-trend={trend}\n data-sentiment={resolvedSentiment}\n className={cn(statVariants({ variant, size }), className)}\n {...props}\n >\n {label || icon ? (\n <div className=\"ddga-stat__label-row\">\n {label ? <StatLabel>{label}</StatLabel> : null}\n {icon ? (\n <span className=\"ddga-stat__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n ) : null}\n </div>\n ) : null}\n {value ? <StatValue>{value}</StatValue> : null}\n {change || changeLabel ? (\n <div className=\"ddga-stat__change-row\">\n {change ? (\n <StatChange trend={trend} sentiment={sentiment} variant={changeVariant}>\n {change}\n </StatChange>\n ) : null}\n {changeLabel ? <span className=\"ddga-stat__change-label\">{changeLabel}</span> : null}\n </div>\n ) : null}\n {children}\n </div>\n );\n}\n\nfunction StatLabel({ className, ...props }: StatLabelProps) {\n return <div data-slot=\"stat-label\" className={cn('ddga-stat__label', className)} {...props} />;\n}\n\nfunction StatValue({ className, ...props }: StatValueProps) {\n return <div data-slot=\"stat-value\" className={cn('ddga-stat__value', className)} {...props} />;\n}\n\n/**\n * Styled slot for a consumer-supplied sparkline / mini-chart. The library ships\n * no charting dependency — drop your own `<svg>`/chart in here and it gets a\n * consistent height + spacing, stretched to the tile width.\n */\nfunction StatChart({ className, ...props }: StatChartProps) {\n return <div data-slot=\"stat-chart\" className={cn('ddga-stat__chart', className)} {...props} />;\n}\n\nfunction StatChange({ trend, sentiment, variant, className, children, ...props }: StatChangeProps) {\n const resolvedSentiment = resolveSentiment(trend, sentiment);\n return (\n <div\n data-slot=\"stat-change\"\n data-trend={trend}\n data-sentiment={resolvedSentiment}\n className={cn(\n 'ddga-stat__change',\n resolvedSentiment ? `ddga-stat__change--${resolvedSentiment}` : null,\n variant === 'chip' && 'ddga-stat__change--chip',\n className,\n )}\n {...props}\n >\n {trend ? <span className=\"ddga-stat__change-icon\">{TREND_ICONS[trend]}</span> : null}\n {children}\n </div>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { Stat, StatLabel, StatValue, StatChart, StatChange, statVariants };\nexport type { StatProps, StatLabelProps, StatValueProps, StatChartProps, StatChangeProps };\n"]}
@@ -60,7 +60,7 @@ function Progress({ value = null, max = 100, size, color, className, ...props })
60
60
  {
61
61
  "data-slot": "progress-indicator",
62
62
  className: "ddga-progress__indicator",
63
- style: isIndeterminate ? void 0 : { transform: `translateX(${pct - 100}%)` }
63
+ style: isIndeterminate ? void 0 : { inlineSize: `${pct}%` }
64
64
  }
65
65
  )
66
66
  }
@@ -186,4 +186,4 @@ function CircularProgress({
186
186
 
187
187
 
188
188
  exports.progressVariants = progressVariants; exports.circularProgressVariants = circularProgressVariants; exports.Progress = Progress; exports.CircularProgress = CircularProgress;
189
- //# sourceMappingURL=chunk-W6B7GJLN.cjs.map
189
+ //# sourceMappingURL=chunk-NU3WUSG7.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-NU3WUSG7.cjs","../src/components/Progress/Progress.tsx"],"names":[],"mappings":"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","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-NU3WUSG7.cjs","sourcesContent":[null,"'use client';\n\nimport { Progress as ProgressPrimitive } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\n\n// ─── 1. Variants ─── //\n\nconst progressVariants = cva('ddga-progress', {\n variants: {\n size: {\n sm: 'ddga-progress--sm',\n md: 'ddga-progress--md',\n lg: 'ddga-progress--lg',\n },\n color: {\n primary: 'ddga-progress--primary',\n success: 'ddga-progress--success',\n warning: 'ddga-progress--warning',\n destructive: 'ddga-progress--destructive',\n },\n },\n defaultVariants: {\n size: 'md',\n color: 'primary',\n },\n});\n\nconst circularProgressVariants = cva('ddga-circular-progress', {\n variants: {\n size: {\n sm: 'ddga-circular-progress--sm',\n md: 'ddga-circular-progress--md',\n lg: 'ddga-circular-progress--lg',\n },\n color: {\n primary: 'ddga-circular-progress--primary',\n success: 'ddga-circular-progress--success',\n warning: 'ddga-circular-progress--warning',\n destructive: 'ddga-circular-progress--destructive',\n },\n },\n defaultVariants: {\n size: 'md',\n color: 'primary',\n },\n});\n\n// ─── 2. Linear Progress (Radix) ─── //\n\ntype ProgressOwnProps = VariantProps<typeof progressVariants> & {\n /**\n * Current progress. `null` (or omitted) renders the indeterminate animation.\n * Otherwise clamp yourself to `[0, max]` — Radix Progress assumes the value\n * is in range.\n */\n value?: number | null;\n /** Maximum value. Defaults to 100. */\n max?: number;\n /**\n * Accessible label for the progressbar. Required for assistive tech —\n * Radix logs a warning if neither `aria-label` nor `aria-labelledby` is set.\n */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n};\n\ntype ProgressProps = ProgressOwnProps &\n Omit<React.ComponentProps<typeof ProgressPrimitive.Root>, keyof ProgressOwnProps>;\n\nfunction Progress({ value = null, max = 100, size, color, className, ...props }: ProgressProps) {\n const isIndeterminate = value === null;\n const pct = isIndeterminate ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n\n return (\n <ProgressPrimitive.Root\n data-slot=\"progress\"\n value={value}\n max={max}\n className={cn(progressVariants({ size, color }), className)}\n {...props}\n >\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className=\"ddga-progress__indicator\"\n // Fill via logical `inline-size`, not a physical `translateX`: the\n // indicator is anchored to the track's inline-start, so it fills from\n // the left in LTR and the right in RTL automatically — no direction\n // read in JS. (A `translateX(-N%)` always slid left, mirroring wrong.)\n style={isIndeterminate ? undefined : { inlineSize: `${pct}%` }}\n />\n </ProgressPrimitive.Root>\n );\n}\n\n// ─── 3. Circular Progress (custom SVG) ─── //\n\ntype CircularProgressOwnProps = VariantProps<typeof circularProgressVariants> & {\n value?: number | null;\n max?: number;\n /** Stroke width in px. Defaults to 4 (sm) / 5 (md) / 6 (lg). */\n thickness?: number;\n /**\n * Render the ring as `segments` discrete arcs (a radial stepper) instead of a\n * continuous arc. Pass an integer `>= 2`; values below that fall back to the\n * continuous ring. The number of filled segments is `round(pct × segments)`,\n * so `value={3} max={5} segments={5}` fills 3. Segmented mode is determinate —\n * a `null` value renders 0 filled (no spinner).\n */\n segments?: number;\n /** Render the label inside the ring (`%`, or `filled/segments` when segmented). */\n showLabel?: boolean;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n};\n\ntype CircularProgressProps = CircularProgressOwnProps &\n Omit<React.ComponentProps<'div'>, keyof CircularProgressOwnProps>;\n\nconst CIRCULAR_SIZES = { sm: 32, md: 48, lg: 72 } as const;\nconst CIRCULAR_DEFAULT_THICKNESS = { sm: 4, md: 5, lg: 6 } as const;\n// Fraction of each segment's angular slot left as the gap between segments.\nconst SEGMENT_GAP_FRACTION = 0.16;\n\nfunction CircularProgress({\n value = null,\n max = 100,\n size,\n color,\n thickness,\n segments,\n showLabel = false,\n className,\n ...props\n}: CircularProgressProps) {\n if (process.env.NODE_ENV === 'development' && !props['aria-label'] && !props['aria-labelledby']) {\n // Linear Progress inherits Radix's no-label warning; CircularProgress is a\n // hand-built `role=\"progressbar\"`, so it needs its own. The ring `showLabel`\n // is aria-hidden decoration, not an accessible name.\n console.warn(\n '[dga/Progress] <CircularProgress> has no accessible name. Pass `aria-label` or ' +\n '`aria-labelledby` so screen-reader users know what the progress represents.',\n );\n }\n\n const isIndeterminate = value === null;\n const isSegmented = typeof segments === 'number' && segments >= 2;\n const sizeKey = size ?? 'md';\n const diameter = CIRCULAR_SIZES[sizeKey];\n const strokeWidth = thickness ?? CIRCULAR_DEFAULT_THICKNESS[sizeKey];\n const radius = (diameter - strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n const center = diameter / 2;\n\n const pct = isIndeterminate ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n const dashOffset = isIndeterminate ? circumference * 0.75 : circumference * (1 - pct / 100);\n\n // Mirror Radix Progress's data-state vocabulary so CSS can use a single\n // selector across linear + circular.\n const state = isIndeterminate ? 'indeterminate' : value >= max ? 'complete' : 'loading';\n\n // Segmented (radial-stepper) geometry: split the ring into `segments` arcs\n // with gaps. Each segment is a single dash of `segLen`, rotated into its slot;\n // the gap is centered so segments stay evenly spaced. Determinate-only.\n const segmentEls =\n isSegmented && segments\n ? (() => {\n const filled = isIndeterminate ? 0 : Math.round((pct / 100) * segments);\n const segAngle = 360 / segments;\n const gapAngle = segAngle * SEGMENT_GAP_FRACTION;\n const segLen = circumference * ((1 - SEGMENT_GAP_FRACTION) / segments);\n return Array.from({ length: segments }, (_, i) => (\n <circle\n key={i}\n className={cn(\n 'ddga-circular-progress__segment',\n i < filled && 'ddga-circular-progress__segment--filled',\n )}\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n // Butt caps, not round: round caps extend strokeWidth/2 past each\n // arc end and would swallow the gap (overlapping at small sizes).\n strokeLinecap=\"butt\"\n strokeDasharray={`${segLen} ${circumference}`}\n transform={`rotate(${-90 + i * segAngle + gapAngle / 2} ${center} ${center})`}\n />\n ));\n })()\n : null;\n\n const labelText = isSegmented\n ? `${segments ? Math.round((pct / 100) * segments) : 0}/${segments}`\n : `${Math.round(pct)}%`;\n\n return (\n <div\n data-slot=\"circular-progress\"\n data-state={state}\n data-segmented={isSegmented ? '' : undefined}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={max}\n aria-valuenow={isIndeterminate ? undefined : value}\n className={cn(circularProgressVariants({ size, color }), className)}\n style={{ inlineSize: diameter, blockSize: diameter }}\n {...props}\n >\n <svg\n className=\"ddga-circular-progress__svg\"\n viewBox={`0 0 ${diameter} ${diameter}`}\n width={diameter}\n height={diameter}\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n {isSegmented ? (\n segmentEls\n ) : (\n <>\n <circle\n className=\"ddga-circular-progress__track\"\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n <circle\n className=\"ddga-circular-progress__indicator\"\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={dashOffset}\n transform={`rotate(-90 ${center} ${center})`}\n />\n </>\n )}\n </svg>\n {showLabel && !isIndeterminate ? (\n <span className=\"ddga-circular-progress__label\" aria-hidden=\"true\">\n {labelText}\n </span>\n ) : null}\n </div>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { Progress, CircularProgress, progressVariants, circularProgressVariants };\nexport type { ProgressProps, CircularProgressProps };\n"]}
@@ -60,7 +60,7 @@ function Progress({ value = null, max = 100, size, color, className, ...props })
60
60
  {
61
61
  "data-slot": "progress-indicator",
62
62
  className: "ddga-progress__indicator",
63
- style: isIndeterminate ? void 0 : { transform: `translateX(${pct - 100}%)` }
63
+ style: isIndeterminate ? void 0 : { inlineSize: `${pct}%` }
64
64
  }
65
65
  )
66
66
  }
@@ -186,4 +186,4 @@ export {
186
186
  Progress,
187
187
  CircularProgress
188
188
  };
189
- //# sourceMappingURL=chunk-FWGFOC2T.js.map
189
+ //# sourceMappingURL=chunk-RSXDPFXK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Progress/Progress.tsx"],"sourcesContent":["'use client';\n\nimport { Progress as ProgressPrimitive } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\n\n// ─── 1. Variants ─── //\n\nconst progressVariants = cva('ddga-progress', {\n variants: {\n size: {\n sm: 'ddga-progress--sm',\n md: 'ddga-progress--md',\n lg: 'ddga-progress--lg',\n },\n color: {\n primary: 'ddga-progress--primary',\n success: 'ddga-progress--success',\n warning: 'ddga-progress--warning',\n destructive: 'ddga-progress--destructive',\n },\n },\n defaultVariants: {\n size: 'md',\n color: 'primary',\n },\n});\n\nconst circularProgressVariants = cva('ddga-circular-progress', {\n variants: {\n size: {\n sm: 'ddga-circular-progress--sm',\n md: 'ddga-circular-progress--md',\n lg: 'ddga-circular-progress--lg',\n },\n color: {\n primary: 'ddga-circular-progress--primary',\n success: 'ddga-circular-progress--success',\n warning: 'ddga-circular-progress--warning',\n destructive: 'ddga-circular-progress--destructive',\n },\n },\n defaultVariants: {\n size: 'md',\n color: 'primary',\n },\n});\n\n// ─── 2. Linear Progress (Radix) ─── //\n\ntype ProgressOwnProps = VariantProps<typeof progressVariants> & {\n /**\n * Current progress. `null` (or omitted) renders the indeterminate animation.\n * Otherwise clamp yourself to `[0, max]` — Radix Progress assumes the value\n * is in range.\n */\n value?: number | null;\n /** Maximum value. Defaults to 100. */\n max?: number;\n /**\n * Accessible label for the progressbar. Required for assistive tech —\n * Radix logs a warning if neither `aria-label` nor `aria-labelledby` is set.\n */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n};\n\ntype ProgressProps = ProgressOwnProps &\n Omit<React.ComponentProps<typeof ProgressPrimitive.Root>, keyof ProgressOwnProps>;\n\nfunction Progress({ value = null, max = 100, size, color, className, ...props }: ProgressProps) {\n const isIndeterminate = value === null;\n const pct = isIndeterminate ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n\n return (\n <ProgressPrimitive.Root\n data-slot=\"progress\"\n value={value}\n max={max}\n className={cn(progressVariants({ size, color }), className)}\n {...props}\n >\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className=\"ddga-progress__indicator\"\n // Fill via logical `inline-size`, not a physical `translateX`: the\n // indicator is anchored to the track's inline-start, so it fills from\n // the left in LTR and the right in RTL automatically — no direction\n // read in JS. (A `translateX(-N%)` always slid left, mirroring wrong.)\n style={isIndeterminate ? undefined : { inlineSize: `${pct}%` }}\n />\n </ProgressPrimitive.Root>\n );\n}\n\n// ─── 3. Circular Progress (custom SVG) ─── //\n\ntype CircularProgressOwnProps = VariantProps<typeof circularProgressVariants> & {\n value?: number | null;\n max?: number;\n /** Stroke width in px. Defaults to 4 (sm) / 5 (md) / 6 (lg). */\n thickness?: number;\n /**\n * Render the ring as `segments` discrete arcs (a radial stepper) instead of a\n * continuous arc. Pass an integer `>= 2`; values below that fall back to the\n * continuous ring. The number of filled segments is `round(pct × segments)`,\n * so `value={3} max={5} segments={5}` fills 3. Segmented mode is determinate —\n * a `null` value renders 0 filled (no spinner).\n */\n segments?: number;\n /** Render the label inside the ring (`%`, or `filled/segments` when segmented). */\n showLabel?: boolean;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n};\n\ntype CircularProgressProps = CircularProgressOwnProps &\n Omit<React.ComponentProps<'div'>, keyof CircularProgressOwnProps>;\n\nconst CIRCULAR_SIZES = { sm: 32, md: 48, lg: 72 } as const;\nconst CIRCULAR_DEFAULT_THICKNESS = { sm: 4, md: 5, lg: 6 } as const;\n// Fraction of each segment's angular slot left as the gap between segments.\nconst SEGMENT_GAP_FRACTION = 0.16;\n\nfunction CircularProgress({\n value = null,\n max = 100,\n size,\n color,\n thickness,\n segments,\n showLabel = false,\n className,\n ...props\n}: CircularProgressProps) {\n if (process.env.NODE_ENV === 'development' && !props['aria-label'] && !props['aria-labelledby']) {\n // Linear Progress inherits Radix's no-label warning; CircularProgress is a\n // hand-built `role=\"progressbar\"`, so it needs its own. The ring `showLabel`\n // is aria-hidden decoration, not an accessible name.\n console.warn(\n '[dga/Progress] <CircularProgress> has no accessible name. Pass `aria-label` or ' +\n '`aria-labelledby` so screen-reader users know what the progress represents.',\n );\n }\n\n const isIndeterminate = value === null;\n const isSegmented = typeof segments === 'number' && segments >= 2;\n const sizeKey = size ?? 'md';\n const diameter = CIRCULAR_SIZES[sizeKey];\n const strokeWidth = thickness ?? CIRCULAR_DEFAULT_THICKNESS[sizeKey];\n const radius = (diameter - strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n const center = diameter / 2;\n\n const pct = isIndeterminate ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n const dashOffset = isIndeterminate ? circumference * 0.75 : circumference * (1 - pct / 100);\n\n // Mirror Radix Progress's data-state vocabulary so CSS can use a single\n // selector across linear + circular.\n const state = isIndeterminate ? 'indeterminate' : value >= max ? 'complete' : 'loading';\n\n // Segmented (radial-stepper) geometry: split the ring into `segments` arcs\n // with gaps. Each segment is a single dash of `segLen`, rotated into its slot;\n // the gap is centered so segments stay evenly spaced. Determinate-only.\n const segmentEls =\n isSegmented && segments\n ? (() => {\n const filled = isIndeterminate ? 0 : Math.round((pct / 100) * segments);\n const segAngle = 360 / segments;\n const gapAngle = segAngle * SEGMENT_GAP_FRACTION;\n const segLen = circumference * ((1 - SEGMENT_GAP_FRACTION) / segments);\n return Array.from({ length: segments }, (_, i) => (\n <circle\n key={i}\n className={cn(\n 'ddga-circular-progress__segment',\n i < filled && 'ddga-circular-progress__segment--filled',\n )}\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n // Butt caps, not round: round caps extend strokeWidth/2 past each\n // arc end and would swallow the gap (overlapping at small sizes).\n strokeLinecap=\"butt\"\n strokeDasharray={`${segLen} ${circumference}`}\n transform={`rotate(${-90 + i * segAngle + gapAngle / 2} ${center} ${center})`}\n />\n ));\n })()\n : null;\n\n const labelText = isSegmented\n ? `${segments ? Math.round((pct / 100) * segments) : 0}/${segments}`\n : `${Math.round(pct)}%`;\n\n return (\n <div\n data-slot=\"circular-progress\"\n data-state={state}\n data-segmented={isSegmented ? '' : undefined}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={max}\n aria-valuenow={isIndeterminate ? undefined : value}\n className={cn(circularProgressVariants({ size, color }), className)}\n style={{ inlineSize: diameter, blockSize: diameter }}\n {...props}\n >\n <svg\n className=\"ddga-circular-progress__svg\"\n viewBox={`0 0 ${diameter} ${diameter}`}\n width={diameter}\n height={diameter}\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n {isSegmented ? (\n segmentEls\n ) : (\n <>\n <circle\n className=\"ddga-circular-progress__track\"\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n <circle\n className=\"ddga-circular-progress__indicator\"\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={dashOffset}\n transform={`rotate(-90 ${center} ${center})`}\n />\n </>\n )}\n </svg>\n {showLabel && !isIndeterminate ? (\n <span className=\"ddga-circular-progress__label\" aria-hidden=\"true\">\n {labelText}\n </span>\n ) : null}\n </div>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { Progress, CircularProgress, progressVariants, circularProgressVariants };\nexport type { ProgressProps, CircularProgressProps };\n"],"mappings":"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","names":[]}
@@ -44,7 +44,14 @@ function ScrollArea({
44
44
  ScrollAreaPrimitive.Viewport,
45
45
  {
46
46
  "data-slot": "scroll-area-viewport",
47
- className: cn("ddga-scroll-area__viewport", viewportClassName),
47
+ className: cn(
48
+ "ddga-scroll-area__viewport",
49
+ // Vertical-only: constrain Radix's inline `display:table` content
50
+ // wrapper so wide children don't overflow an axis that has no
51
+ // scrollbar (see scroll-area.css). Horizontal/both keep the default.
52
+ orientation === "vertical" && "ddga-scroll-area__viewport--vertical",
53
+ viewportClassName
54
+ ),
48
55
  ref: viewportRef,
49
56
  tabIndex: 0,
50
57
  role: hasLabel ? "region" : void 0,
@@ -100,4 +107,4 @@ export {
100
107
  scrollAreaVariants,
101
108
  ScrollArea
102
109
  };
103
- //# sourceMappingURL=chunk-UAECZXU5.js.map
110
+ //# sourceMappingURL=chunk-TXQK3BAO.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ScrollArea/ScrollArea.tsx"],"sourcesContent":["'use client';\n\nimport { ScrollArea as ScrollAreaPrimitive } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\n\n// Orientation is driven by which scrollbar(s) render, NOT by a modifier class —\n// so the cva carries only the base class. (It previously emitted dead\n// `--vertical/--horizontal/--both` classes that no stylesheet matched.) Kept as\n// a cva and exported for API compatibility.\nconst scrollAreaVariants = cva('ddga-scroll-area');\n\nfunction warnMissingLabel(ariaLabel?: string, ariaLabelledby?: string) {\n if (process.env.NODE_ENV === 'production') return;\n if (ariaLabel || ariaLabelledby) return;\n // Warn on every render (dev only) — mirrors the Popover sibling's a11y warning.\n console.warn(\n '[dga/ScrollArea] <ScrollArea> has no accessible name. The scroll viewport is ' +\n 'keyboard-focusable; pass `aria-label` or `aria-labelledby` so screen-reader users ' +\n 'know what region they are scrolling. If the content is itself focusable (e.g. a list ' +\n 'of links) and you do not want a labelled region, pass `viewportProps={{ tabIndex: -1 }}`.',\n );\n}\n\ntype ScrollAreaOrientation = 'vertical' | 'horizontal' | 'both';\n\nexport interface ScrollAreaProps\n extends\n Omit<React.ComponentProps<typeof ScrollAreaPrimitive.Root>, 'asChild' | 'orientation'>,\n Omit<VariantProps<typeof scrollAreaVariants>, 'orientation'> {\n /** Which scrollbar(s) to render. Default `'vertical'`. */\n orientation?: ScrollAreaOrientation;\n /** Ref to the scrollable viewport — use for programmatic scrolling. */\n viewportRef?: React.Ref<HTMLDivElement>;\n /**\n * Extra props forwarded to the viewport element (use `viewportRef` for the ref).\n * To drop the extra tab stop when the scrolled content is itself fully focusable\n * (e.g. a list of links), pass `viewportProps={{ tabIndex: -1 }}`.\n */\n viewportProps?: Omit<React.ComponentProps<'div'>, 'ref'>;\n /** Names the scroll region. Warns (dev only) if neither this nor `aria-labelledby` is set. */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n/**\n * Cross-browser, design-system-styled scroll container (wraps Radix ScrollArea).\n *\n * Set the bounding size (height / max-height) on the element via `className` /\n * `style` — without a bounded size nothing scrolls, exactly like native overflow.\n * The viewport is keyboard-focusable (`tabIndex={0}`) so keyboard users can scroll\n * with the arrow / Page keys; pass `aria-label` to name the region.\n *\n * Does not support `asChild`: it is a structural wrapper composing several Radix\n * parts, and the meaningful node — the viewport — is exposed via `viewportRef`.\n */\nexport function ScrollArea({\n className,\n orientation = 'vertical',\n type = 'hover',\n scrollHideDelay = 600,\n viewportRef,\n viewportProps,\n children,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...props\n}: ScrollAreaProps) {\n warnMissingLabel(ariaLabel, ariaLabelledby);\n\n const hasLabel = Boolean(ariaLabel || ariaLabelledby);\n const showVertical = orientation === 'vertical' || orientation === 'both';\n const showHorizontal = orientation === 'horizontal' || orientation === 'both';\n\n const { className: viewportClassName, ...restViewportProps } = viewportProps ?? {};\n\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n type={type}\n scrollHideDelay={scrollHideDelay}\n className={cn(scrollAreaVariants(), className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n data-slot=\"scroll-area-viewport\"\n className={cn('ddga-scroll-area__viewport', viewportClassName)}\n ref={viewportRef}\n tabIndex={0}\n role={hasLabel ? 'region' : undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n {...restViewportProps}\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n {showVertical ? (\n <ScrollAreaPrimitive.Scrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation=\"vertical\"\n className=\"ddga-scroll-area__scrollbar\"\n >\n <ScrollAreaPrimitive.Thumb\n data-slot=\"scroll-area-thumb\"\n className=\"ddga-scroll-area__thumb\"\n />\n </ScrollAreaPrimitive.Scrollbar>\n ) : null}\n {showHorizontal ? (\n <ScrollAreaPrimitive.Scrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation=\"horizontal\"\n className=\"ddga-scroll-area__scrollbar\"\n >\n <ScrollAreaPrimitive.Thumb\n data-slot=\"scroll-area-thumb\"\n className=\"ddga-scroll-area__thumb\"\n />\n </ScrollAreaPrimitive.Scrollbar>\n ) : null}\n {orientation === 'both' ? (\n <ScrollAreaPrimitive.Corner\n data-slot=\"scroll-area-corner\"\n className=\"ddga-scroll-area__corner\"\n />\n ) : null}\n </ScrollAreaPrimitive.Root>\n );\n}\n\nexport { scrollAreaVariants };\nexport type { ScrollAreaOrientation };\n"],"mappings":";;;;;AAEA,SAAS,cAAc,2BAA2B;AAClD,SAAS,WAA8B;AA0EnC,SAOE,KAPF;AAnEJ,IAAM,qBAAqB,IAAI,kBAAkB;AAEjD,SAAS,iBAAiB,WAAoB,gBAAyB;AACrE,MAAI,QAAQ,IAAI,aAAa,aAAc;AAC3C,MAAI,aAAa,eAAgB;AAEjC,UAAQ;AAAA,IACN;AAAA,EAIF;AACF;AAkCO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,cAAc;AAAA,EACd,OAAO;AAAA,EACP,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,GAAG;AACL,GAAoB;AAClB,mBAAiB,WAAW,cAAc;AAE1C,QAAM,WAAW,QAAQ,aAAa,cAAc;AACpD,QAAM,eAAe,gBAAgB,cAAc,gBAAgB;AACnE,QAAM,iBAAiB,gBAAgB,gBAAgB,gBAAgB;AAEvE,QAAM,EAAE,WAAW,mBAAmB,GAAG,kBAAkB,IAAI,iBAAiB,CAAC;AAEjF,SACE;AAAA,IAAC,oBAAoB;AAAA,IAApB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,WAAW,GAAG,mBAAmB,GAAG,SAAS;AAAA,MAC5C,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC,oBAAoB;AAAA,UAApB;AAAA,YACC,aAAU;AAAA,YACV,WAAW,GAAG,8BAA8B,iBAAiB;AAAA,YAC7D,KAAK;AAAA,YACL,UAAU;AAAA,YACV,MAAM,WAAW,WAAW;AAAA,YAC5B,cAAY;AAAA,YACZ,mBAAiB;AAAA,YAChB,GAAG;AAAA,YAEH;AAAA;AAAA,QACH;AAAA,QACC,eACC;AAAA,UAAC,oBAAoB;AAAA,UAApB;AAAA,YACC,aAAU;AAAA,YACV,aAAY;AAAA,YACZ,WAAU;AAAA,YAEV;AAAA,cAAC,oBAAoB;AAAA,cAApB;AAAA,gBACC,aAAU;AAAA,gBACV,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF,IACE;AAAA,QACH,iBACC;AAAA,UAAC,oBAAoB;AAAA,UAApB;AAAA,YACC,aAAU;AAAA,YACV,aAAY;AAAA,YACZ,WAAU;AAAA,YAEV;AAAA,cAAC,oBAAoB;AAAA,cAApB;AAAA,gBACC,aAAU;AAAA,gBACV,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF,IACE;AAAA,QACH,gBAAgB,SACf;AAAA,UAAC,oBAAoB;AAAA,UAApB;AAAA,YACC,aAAU;AAAA,YACV,WAAU;AAAA;AAAA,QACZ,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../src/components/ScrollArea/ScrollArea.tsx"],"sourcesContent":["'use client';\n\nimport { ScrollArea as ScrollAreaPrimitive } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\n\n// Orientation is driven by which scrollbar(s) render, NOT by a modifier class —\n// so the cva carries only the base class. (It previously emitted dead\n// `--vertical/--horizontal/--both` classes that no stylesheet matched.) Kept as\n// a cva and exported for API compatibility.\nconst scrollAreaVariants = cva('ddga-scroll-area');\n\nfunction warnMissingLabel(ariaLabel?: string, ariaLabelledby?: string) {\n if (process.env.NODE_ENV === 'production') return;\n if (ariaLabel || ariaLabelledby) return;\n // Warn on every render (dev only) — mirrors the Popover sibling's a11y warning.\n console.warn(\n '[dga/ScrollArea] <ScrollArea> has no accessible name. The scroll viewport is ' +\n 'keyboard-focusable; pass `aria-label` or `aria-labelledby` so screen-reader users ' +\n 'know what region they are scrolling. If the content is itself focusable (e.g. a list ' +\n 'of links) and you do not want a labelled region, pass `viewportProps={{ tabIndex: -1 }}`.',\n );\n}\n\ntype ScrollAreaOrientation = 'vertical' | 'horizontal' | 'both';\n\nexport interface ScrollAreaProps\n extends\n Omit<React.ComponentProps<typeof ScrollAreaPrimitive.Root>, 'asChild' | 'orientation'>,\n Omit<VariantProps<typeof scrollAreaVariants>, 'orientation'> {\n /** Which scrollbar(s) to render. Default `'vertical'`. */\n orientation?: ScrollAreaOrientation;\n /** Ref to the scrollable viewport — use for programmatic scrolling. */\n viewportRef?: React.Ref<HTMLDivElement>;\n /**\n * Extra props forwarded to the viewport element (use `viewportRef` for the ref).\n * To drop the extra tab stop when the scrolled content is itself fully focusable\n * (e.g. a list of links), pass `viewportProps={{ tabIndex: -1 }}`.\n */\n viewportProps?: Omit<React.ComponentProps<'div'>, 'ref'>;\n /** Names the scroll region. Warns (dev only) if neither this nor `aria-labelledby` is set. */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n/**\n * Cross-browser, design-system-styled scroll container (wraps Radix ScrollArea).\n *\n * Set the bounding size (height / max-height) on the element via `className` /\n * `style` — without a bounded size nothing scrolls, exactly like native overflow.\n * The viewport is keyboard-focusable (`tabIndex={0}`) so keyboard users can scroll\n * with the arrow / Page keys; pass `aria-label` to name the region.\n *\n * Does not support `asChild`: it is a structural wrapper composing several Radix\n * parts, and the meaningful node — the viewport — is exposed via `viewportRef`.\n */\nexport function ScrollArea({\n className,\n orientation = 'vertical',\n type = 'hover',\n scrollHideDelay = 600,\n viewportRef,\n viewportProps,\n children,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...props\n}: ScrollAreaProps) {\n warnMissingLabel(ariaLabel, ariaLabelledby);\n\n const hasLabel = Boolean(ariaLabel || ariaLabelledby);\n const showVertical = orientation === 'vertical' || orientation === 'both';\n const showHorizontal = orientation === 'horizontal' || orientation === 'both';\n\n const { className: viewportClassName, ...restViewportProps } = viewportProps ?? {};\n\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n type={type}\n scrollHideDelay={scrollHideDelay}\n className={cn(scrollAreaVariants(), className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n data-slot=\"scroll-area-viewport\"\n className={cn(\n 'ddga-scroll-area__viewport',\n // Vertical-only: constrain Radix's inline `display:table` content\n // wrapper so wide children don't overflow an axis that has no\n // scrollbar (see scroll-area.css). Horizontal/both keep the default.\n orientation === 'vertical' && 'ddga-scroll-area__viewport--vertical',\n viewportClassName,\n )}\n ref={viewportRef}\n tabIndex={0}\n role={hasLabel ? 'region' : undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n {...restViewportProps}\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n {showVertical ? (\n <ScrollAreaPrimitive.Scrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation=\"vertical\"\n className=\"ddga-scroll-area__scrollbar\"\n >\n <ScrollAreaPrimitive.Thumb\n data-slot=\"scroll-area-thumb\"\n className=\"ddga-scroll-area__thumb\"\n />\n </ScrollAreaPrimitive.Scrollbar>\n ) : null}\n {showHorizontal ? (\n <ScrollAreaPrimitive.Scrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation=\"horizontal\"\n className=\"ddga-scroll-area__scrollbar\"\n >\n <ScrollAreaPrimitive.Thumb\n data-slot=\"scroll-area-thumb\"\n className=\"ddga-scroll-area__thumb\"\n />\n </ScrollAreaPrimitive.Scrollbar>\n ) : null}\n {orientation === 'both' ? (\n <ScrollAreaPrimitive.Corner\n data-slot=\"scroll-area-corner\"\n className=\"ddga-scroll-area__corner\"\n />\n ) : null}\n </ScrollAreaPrimitive.Root>\n );\n}\n\nexport { scrollAreaVariants };\nexport type { ScrollAreaOrientation };\n"],"mappings":";;;;;AAEA,SAAS,cAAc,2BAA2B;AAClD,SAAS,WAA8B;AA0EnC,SAOE,KAPF;AAnEJ,IAAM,qBAAqB,IAAI,kBAAkB;AAEjD,SAAS,iBAAiB,WAAoB,gBAAyB;AACrE,MAAI,QAAQ,IAAI,aAAa,aAAc;AAC3C,MAAI,aAAa,eAAgB;AAEjC,UAAQ;AAAA,IACN;AAAA,EAIF;AACF;AAkCO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,cAAc;AAAA,EACd,OAAO;AAAA,EACP,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,GAAG;AACL,GAAoB;AAClB,mBAAiB,WAAW,cAAc;AAE1C,QAAM,WAAW,QAAQ,aAAa,cAAc;AACpD,QAAM,eAAe,gBAAgB,cAAc,gBAAgB;AACnE,QAAM,iBAAiB,gBAAgB,gBAAgB,gBAAgB;AAEvE,QAAM,EAAE,WAAW,mBAAmB,GAAG,kBAAkB,IAAI,iBAAiB,CAAC;AAEjF,SACE;AAAA,IAAC,oBAAoB;AAAA,IAApB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,WAAW,GAAG,mBAAmB,GAAG,SAAS;AAAA,MAC5C,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC,oBAAoB;AAAA,UAApB;AAAA,YACC,aAAU;AAAA,YACV,WAAW;AAAA,cACT;AAAA;AAAA;AAAA;AAAA,cAIA,gBAAgB,cAAc;AAAA,cAC9B;AAAA,YACF;AAAA,YACA,KAAK;AAAA,YACL,UAAU;AAAA,YACV,MAAM,WAAW,WAAW;AAAA,YAC5B,cAAY;AAAA,YACZ,mBAAiB;AAAA,YAChB,GAAG;AAAA,YAEH;AAAA;AAAA,QACH;AAAA,QACC,eACC;AAAA,UAAC,oBAAoB;AAAA,UAApB;AAAA,YACC,aAAU;AAAA,YACV,aAAY;AAAA,YACZ,WAAU;AAAA,YAEV;AAAA,cAAC,oBAAoB;AAAA,cAApB;AAAA,gBACC,aAAU;AAAA,gBACV,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF,IACE;AAAA,QACH,iBACC;AAAA,UAAC,oBAAoB;AAAA,UAApB;AAAA,YACC,aAAU;AAAA,YACV,aAAY;AAAA,YACZ,WAAU;AAAA,YAEV;AAAA,cAAC,oBAAoB;AAAA,cAApB;AAAA,gBACC,aAAU;AAAA,gBACV,WAAU;AAAA;AAAA,YACZ;AAAA;AAAA,QACF,IACE;AAAA,QACH,gBAAgB,SACf;AAAA,UAAC,oBAAoB;AAAA,UAApB;AAAA,YACC,aAAU;AAAA,YACV,WAAU;AAAA;AAAA,QACZ,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;","names":[]}
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkW6B7GJLNcjs = require('./chunk-W6B7GJLN.cjs');
3
+ var _chunkNU3WUSG7cjs = require('./chunk-NU3WUSG7.cjs');
4
4
 
5
5
 
6
6
  var _chunkUK2SFZIQcjs = require('./chunk-UK2SFZIQ.cjs');
@@ -188,7 +188,7 @@ function FileUpload({
188
188
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "ddga-file-upload__item-meta", children: formatBytes(item.file.size) })
189
189
  ] }),
190
190
  status === "uploading" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
191
- _chunkW6B7GJLNcjs.Progress,
191
+ _chunkNU3WUSG7cjs.Progress,
192
192
  {
193
193
  size: "sm",
194
194
  value: _nullishCoalesce(item.progress, () => ( 0)),
@@ -221,4 +221,4 @@ function FileUpload({
221
221
 
222
222
 
223
223
  exports.FileUpload = FileUpload;
224
- //# sourceMappingURL=chunk-2HZGIP5V.cjs.map
224
+ //# sourceMappingURL=chunk-VMAJ34DC.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-2HZGIP5V.cjs","../src/components/FileUpload/FileUpload.tsx"],"names":[],"mappings":"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","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-2HZGIP5V.cjs","sourcesContent":[null,"'use client';\n\nimport { useRef, useState, type ReactNode } from 'react';\nimport { cn } from '../../utils/cn';\nimport { useFieldA11y, FieldMessage } from '../../field';\nimport { Button } from '../Button';\nimport { Progress } from '../Progress';\nimport { Upload, Check, AlertCircle, Close } from '../../internal/icons';\n\n// ─── 1. Types ─── //\n\ntype FileStatus = 'pending' | 'uploading' | 'success' | 'error';\n\n/** Reason codes attached to a rejected file. */\ntype RejectionCode = 'file-too-large' | 'file-invalid-type' | 'too-many-files';\n\n/**\n * A controlled file entry. The consumer owns this array and is responsible for\n * performing the actual upload, updating `status`/`progress`, and assigning a\n * stable `id` (used as the React key and the `onRemove` target).\n */\ninterface UploadFile {\n /** Stable, consumer-assigned id. Used as the React key and remove target. */\n id: string;\n /** The native File. */\n file: File;\n /** Defaults to `'pending'`. Drives the per-row affordance. */\n status?: FileStatus;\n /** 0–100. Rendered as a {@link Progress} bar while `status === 'uploading'`. */\n progress?: number;\n /** Shown inline (red) while `status === 'error'`. */\n error?: string;\n}\n\ninterface FileRejection {\n file: File;\n errors: RejectionCode[];\n}\n\ninterface FileUploadProps {\n /** Controlled list of files to render. The consumer is the source of truth. */\n files: UploadFile[];\n /** Called with the files that passed validation. The consumer wraps each in\n * an {@link UploadFile} (assigning an `id`) and starts the upload. */\n onFilesAdded: (accepted: File[]) => void;\n /** Called with files that failed validation. Never enter `files`. */\n onFilesRejected?: (rejections: FileRejection[]) => void;\n /** Per-row remove handler. Omit to hide the remove button. */\n onRemove?: (id: string) => void;\n\n /** Native `accept` string (e.g. `'image/*,.pdf'`). Also drives validation. */\n accept?: string;\n /** Maximum size per file, in bytes. */\n maxSize?: number;\n /** Maximum total files (existing + incoming). When `multiple` is false this\n * is forced to 1. */\n maxFiles?: number;\n /** Allow selecting/dropping more than one file. Defaults to true. */\n multiple?: boolean;\n /** Disables the drop zone and the picker. */\n disabled?: boolean;\n /** Marks the field required: renders the asterisk and sets the input's\n * `required` attribute. */\n required?: boolean;\n\n /** Visible field label, auto-associated to the input. */\n label?: ReactNode;\n /** Hint shown below the field. Hidden while an error message is showing. */\n helperText?: ReactNode;\n /** Message shown below the field when `error` is true. */\n errorMessage?: ReactNode;\n /** Marks the field invalid: sets `aria-invalid` and error styling. */\n error?: boolean;\n\n /** Drop-zone instructional copy. Defaults to a bilingual-friendly EN string. */\n hint?: ReactNode;\n /** Accessible label for the per-row remove button. Defaults to `'Remove'`. */\n removeLabel?: string;\n\n id?: string;\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n// ─── 2. Validation helpers (local — no shared util until a 2nd use case) ─── //\n\nfunction matchesAccept(file: File, accept?: string): boolean {\n if (!accept) return true;\n const tokens = accept\n .split(',')\n .map((t) => t.trim().toLowerCase())\n .filter(Boolean);\n if (tokens.length === 0) return true;\n\n const name = file.name.toLowerCase();\n const type = file.type.toLowerCase();\n\n return tokens.some((token) => {\n if (token.startsWith('.')) return name.endsWith(token);\n if (token.endsWith('/*')) return type.startsWith(token.slice(0, token.indexOf('/') + 1));\n return type === token;\n });\n}\n\ninterface ValidationConfig {\n accept?: string;\n maxSize?: number;\n maxFiles?: number;\n /** Files already in the list — counts against `maxFiles`. */\n currentCount: number;\n}\n\nfunction splitFiles(incoming: File[], config: ValidationConfig) {\n const { accept, maxSize, maxFiles, currentCount } = config;\n const accepted: File[] = [];\n const rejections: FileRejection[] = [];\n\n for (const file of incoming) {\n const errors: RejectionCode[] = [];\n if (!matchesAccept(file, accept)) errors.push('file-invalid-type');\n if (maxSize != null && file.size > maxSize) errors.push('file-too-large');\n\n if (errors.length > 0) {\n rejections.push({ file, errors });\n continue;\n }\n // Count check last, and only for otherwise-valid files: a slot is consumed\n // only by a file that would actually be accepted.\n if (maxFiles != null && currentCount + accepted.length >= maxFiles) {\n rejections.push({ file, errors: ['too-many-files'] });\n continue;\n }\n accepted.push(file);\n }\n\n return { accepted, rejections };\n}\n\nconst UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), UNITS.length - 1);\n const value = bytes / 1024 ** exponent;\n // Whole numbers for bytes; one decimal for KB+.\n return `${exponent === 0 ? value : value.toFixed(1)} ${UNITS[exponent]}`;\n}\n\n// ─── 3. Component ─── //\n\nfunction FileUpload({\n files,\n onFilesAdded,\n onFilesRejected,\n onRemove,\n accept,\n maxSize,\n maxFiles,\n multiple = true,\n disabled = false,\n required,\n label,\n helperText,\n errorMessage,\n error,\n hint = 'Drag files here, or click to browse',\n removeLabel = 'Remove',\n id: externalId,\n className,\n ...props\n}: FileUploadProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n const { fieldId, errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps } =\n useFieldA11y({\n name: 'FileUpload',\n id: externalId,\n label,\n error,\n errorMessage,\n helperText,\n 'aria-label': props['aria-label'],\n 'aria-labelledby': props['aria-labelledby'],\n });\n\n // Single-select forces a hard cap of 1, regardless of maxFiles.\n const effectiveMaxFiles = multiple ? maxFiles : 1;\n\n function process(incoming: File[]) {\n if (disabled || incoming.length === 0) return;\n const { accepted, rejections } = splitFiles(incoming, {\n accept,\n maxSize,\n maxFiles: effectiveMaxFiles,\n currentCount: files.length,\n });\n if (accepted.length > 0) onFilesAdded(accepted);\n if (rejections.length > 0) onFilesRejected?.(rejections);\n }\n\n function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {\n process(Array.from(event.target.files ?? []));\n // Reset so selecting the same file again re-fires `change`.\n event.target.value = '';\n }\n\n function handleDrop(event: React.DragEvent<HTMLDivElement>) {\n event.preventDefault();\n setIsDragging(false);\n if (disabled) return;\n process(Array.from(event.dataTransfer.files));\n }\n\n function handleDragOver(event: React.DragEvent<HTMLDivElement>) {\n event.preventDefault();\n if (!disabled) setIsDragging(true);\n }\n\n function handleDragLeave(event: React.DragEvent<HTMLDivElement>) {\n // Ignore dragleave events bubbling up from descendants.\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) {\n setIsDragging(false);\n }\n }\n\n return (\n <div data-slot=\"file-upload-field\" className={cn('ddga-field', 'ddga-file-upload', className)}>\n {label && (\n <label htmlFor={fieldId} className=\"ddga-file-upload__label\">\n {label}\n {required && (\n <span aria-hidden=\"true\" className=\"ddga-file-upload__required\">\n *\n </span>\n )}\n </label>\n )}\n\n {/* The drop zone is a click target that proxies to the hidden input.\n The input itself stays focusable (keyboard users tab to it and press\n Space/Enter to open the picker); drag-and-drop is a mouse-only\n enhancement layered on top. */}\n <div\n data-slot=\"file-upload-dropzone\"\n className={cn(\n 'ddga-file-upload__dropzone',\n hasError && 'ddga-file-upload__dropzone--error',\n )}\n data-dragging={isDragging || undefined}\n data-disabled={disabled || undefined}\n aria-disabled={disabled || undefined}\n onClick={() => {\n if (!disabled) inputRef.current?.click();\n }}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n <Upload className=\"ddga-file-upload__icon\" aria-hidden=\"true\" />\n <span className=\"ddga-file-upload__hint\">{hint}</span>\n <input\n {...controlProps}\n ref={inputRef}\n type=\"file\"\n className=\"ddga-file-upload__input\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n required={required}\n onChange={handleInputChange}\n // The dropzone's onClick calls inputRef.click(); without stopping\n // propagation, that programmatic click bubbles back to the dropzone\n // and re-triggers it — infinite recursion. Native label/keyboard\n // activation of the input is unaffected.\n onClick={(event) => event.stopPropagation()}\n data-slot=\"file-upload-input\"\n />\n </div>\n\n {hasErrorMessage && (\n <FieldMessage id={errorId} variant=\"error\">\n {errorMessage}\n </FieldMessage>\n )}\n {hasHelper && (\n <FieldMessage id={helperId} variant=\"helper\">\n {helperText}\n </FieldMessage>\n )}\n\n {files.length > 0 && (\n <ul data-slot=\"file-upload-list\" className=\"ddga-file-upload__list\">\n {files.map((item) => {\n const status = item.status ?? 'pending';\n return (\n <li\n key={item.id}\n data-slot=\"file-upload-item\"\n data-status={status}\n className=\"ddga-file-upload__item\"\n >\n <span className=\"ddga-file-upload__item-icon\" aria-hidden=\"true\">\n {status === 'success' ? (\n <Check />\n ) : status === 'error' ? (\n <AlertCircle />\n ) : (\n <Upload />\n )}\n </span>\n\n <div className=\"ddga-file-upload__item-main\">\n <div className=\"ddga-file-upload__item-head\">\n <span className=\"ddga-file-upload__item-name\" title={item.file.name}>\n {item.file.name}\n </span>\n <span className=\"ddga-file-upload__item-meta\">\n {formatBytes(item.file.size)}\n </span>\n </div>\n\n {status === 'uploading' && (\n <Progress\n size=\"sm\"\n value={item.progress ?? 0}\n aria-label={`Uploading ${item.file.name}`}\n className=\"ddga-file-upload__item-progress\"\n />\n )}\n\n {status === 'error' && item.error && (\n <span role=\"alert\" className=\"ddga-file-upload__item-error\">\n {item.error}\n </span>\n )}\n </div>\n\n {onRemove && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={`${removeLabel}: ${item.file.name}`}\n onClick={() => onRemove(item.id)}\n className=\"ddga-file-upload__item-remove\"\n >\n <Close aria-hidden=\"true\" />\n </Button>\n )}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { FileUpload };\nexport type { FileUploadProps, UploadFile, FileRejection, FileStatus, RejectionCode };\n"]}
1
+ {"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-VMAJ34DC.cjs","../src/components/FileUpload/FileUpload.tsx"],"names":[],"mappings":"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","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-VMAJ34DC.cjs","sourcesContent":[null,"'use client';\n\nimport { useRef, useState, type ReactNode } from 'react';\nimport { cn } from '../../utils/cn';\nimport { useFieldA11y, FieldMessage } from '../../field';\nimport { Button } from '../Button';\nimport { Progress } from '../Progress';\nimport { Upload, Check, AlertCircle, Close } from '../../internal/icons';\n\n// ─── 1. Types ─── //\n\ntype FileStatus = 'pending' | 'uploading' | 'success' | 'error';\n\n/** Reason codes attached to a rejected file. */\ntype RejectionCode = 'file-too-large' | 'file-invalid-type' | 'too-many-files';\n\n/**\n * A controlled file entry. The consumer owns this array and is responsible for\n * performing the actual upload, updating `status`/`progress`, and assigning a\n * stable `id` (used as the React key and the `onRemove` target).\n */\ninterface UploadFile {\n /** Stable, consumer-assigned id. Used as the React key and remove target. */\n id: string;\n /** The native File. */\n file: File;\n /** Defaults to `'pending'`. Drives the per-row affordance. */\n status?: FileStatus;\n /** 0–100. Rendered as a {@link Progress} bar while `status === 'uploading'`. */\n progress?: number;\n /** Shown inline (red) while `status === 'error'`. */\n error?: string;\n}\n\ninterface FileRejection {\n file: File;\n errors: RejectionCode[];\n}\n\ninterface FileUploadProps {\n /** Controlled list of files to render. The consumer is the source of truth. */\n files: UploadFile[];\n /** Called with the files that passed validation. The consumer wraps each in\n * an {@link UploadFile} (assigning an `id`) and starts the upload. */\n onFilesAdded: (accepted: File[]) => void;\n /** Called with files that failed validation. Never enter `files`. */\n onFilesRejected?: (rejections: FileRejection[]) => void;\n /** Per-row remove handler. Omit to hide the remove button. */\n onRemove?: (id: string) => void;\n\n /** Native `accept` string (e.g. `'image/*,.pdf'`). Also drives validation. */\n accept?: string;\n /** Maximum size per file, in bytes. */\n maxSize?: number;\n /** Maximum total files (existing + incoming). When `multiple` is false this\n * is forced to 1. */\n maxFiles?: number;\n /** Allow selecting/dropping more than one file. Defaults to true. */\n multiple?: boolean;\n /** Disables the drop zone and the picker. */\n disabled?: boolean;\n /** Marks the field required: renders the asterisk and sets the input's\n * `required` attribute. */\n required?: boolean;\n\n /** Visible field label, auto-associated to the input. */\n label?: ReactNode;\n /** Hint shown below the field. Hidden while an error message is showing. */\n helperText?: ReactNode;\n /** Message shown below the field when `error` is true. */\n errorMessage?: ReactNode;\n /** Marks the field invalid: sets `aria-invalid` and error styling. */\n error?: boolean;\n\n /** Drop-zone instructional copy. Defaults to a bilingual-friendly EN string. */\n hint?: ReactNode;\n /** Accessible label for the per-row remove button. Defaults to `'Remove'`. */\n removeLabel?: string;\n\n id?: string;\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n// ─── 2. Validation helpers (local — no shared util until a 2nd use case) ─── //\n\nfunction matchesAccept(file: File, accept?: string): boolean {\n if (!accept) return true;\n const tokens = accept\n .split(',')\n .map((t) => t.trim().toLowerCase())\n .filter(Boolean);\n if (tokens.length === 0) return true;\n\n const name = file.name.toLowerCase();\n const type = file.type.toLowerCase();\n\n return tokens.some((token) => {\n if (token.startsWith('.')) return name.endsWith(token);\n if (token.endsWith('/*')) return type.startsWith(token.slice(0, token.indexOf('/') + 1));\n return type === token;\n });\n}\n\ninterface ValidationConfig {\n accept?: string;\n maxSize?: number;\n maxFiles?: number;\n /** Files already in the list — counts against `maxFiles`. */\n currentCount: number;\n}\n\nfunction splitFiles(incoming: File[], config: ValidationConfig) {\n const { accept, maxSize, maxFiles, currentCount } = config;\n const accepted: File[] = [];\n const rejections: FileRejection[] = [];\n\n for (const file of incoming) {\n const errors: RejectionCode[] = [];\n if (!matchesAccept(file, accept)) errors.push('file-invalid-type');\n if (maxSize != null && file.size > maxSize) errors.push('file-too-large');\n\n if (errors.length > 0) {\n rejections.push({ file, errors });\n continue;\n }\n // Count check last, and only for otherwise-valid files: a slot is consumed\n // only by a file that would actually be accepted.\n if (maxFiles != null && currentCount + accepted.length >= maxFiles) {\n rejections.push({ file, errors: ['too-many-files'] });\n continue;\n }\n accepted.push(file);\n }\n\n return { accepted, rejections };\n}\n\nconst UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), UNITS.length - 1);\n const value = bytes / 1024 ** exponent;\n // Whole numbers for bytes; one decimal for KB+.\n return `${exponent === 0 ? value : value.toFixed(1)} ${UNITS[exponent]}`;\n}\n\n// ─── 3. Component ─── //\n\nfunction FileUpload({\n files,\n onFilesAdded,\n onFilesRejected,\n onRemove,\n accept,\n maxSize,\n maxFiles,\n multiple = true,\n disabled = false,\n required,\n label,\n helperText,\n errorMessage,\n error,\n hint = 'Drag files here, or click to browse',\n removeLabel = 'Remove',\n id: externalId,\n className,\n ...props\n}: FileUploadProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n const { fieldId, errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps } =\n useFieldA11y({\n name: 'FileUpload',\n id: externalId,\n label,\n error,\n errorMessage,\n helperText,\n 'aria-label': props['aria-label'],\n 'aria-labelledby': props['aria-labelledby'],\n });\n\n // Single-select forces a hard cap of 1, regardless of maxFiles.\n const effectiveMaxFiles = multiple ? maxFiles : 1;\n\n function process(incoming: File[]) {\n if (disabled || incoming.length === 0) return;\n const { accepted, rejections } = splitFiles(incoming, {\n accept,\n maxSize,\n maxFiles: effectiveMaxFiles,\n currentCount: files.length,\n });\n if (accepted.length > 0) onFilesAdded(accepted);\n if (rejections.length > 0) onFilesRejected?.(rejections);\n }\n\n function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {\n process(Array.from(event.target.files ?? []));\n // Reset so selecting the same file again re-fires `change`.\n event.target.value = '';\n }\n\n function handleDrop(event: React.DragEvent<HTMLDivElement>) {\n event.preventDefault();\n setIsDragging(false);\n if (disabled) return;\n process(Array.from(event.dataTransfer.files));\n }\n\n function handleDragOver(event: React.DragEvent<HTMLDivElement>) {\n event.preventDefault();\n if (!disabled) setIsDragging(true);\n }\n\n function handleDragLeave(event: React.DragEvent<HTMLDivElement>) {\n // Ignore dragleave events bubbling up from descendants.\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) {\n setIsDragging(false);\n }\n }\n\n return (\n <div data-slot=\"file-upload-field\" className={cn('ddga-field', 'ddga-file-upload', className)}>\n {label && (\n <label htmlFor={fieldId} className=\"ddga-file-upload__label\">\n {label}\n {required && (\n <span aria-hidden=\"true\" className=\"ddga-file-upload__required\">\n *\n </span>\n )}\n </label>\n )}\n\n {/* The drop zone is a click target that proxies to the hidden input.\n The input itself stays focusable (keyboard users tab to it and press\n Space/Enter to open the picker); drag-and-drop is a mouse-only\n enhancement layered on top. */}\n <div\n data-slot=\"file-upload-dropzone\"\n className={cn(\n 'ddga-file-upload__dropzone',\n hasError && 'ddga-file-upload__dropzone--error',\n )}\n data-dragging={isDragging || undefined}\n data-disabled={disabled || undefined}\n aria-disabled={disabled || undefined}\n onClick={() => {\n if (!disabled) inputRef.current?.click();\n }}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n <Upload className=\"ddga-file-upload__icon\" aria-hidden=\"true\" />\n <span className=\"ddga-file-upload__hint\">{hint}</span>\n <input\n {...controlProps}\n ref={inputRef}\n type=\"file\"\n className=\"ddga-file-upload__input\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n required={required}\n onChange={handleInputChange}\n // The dropzone's onClick calls inputRef.click(); without stopping\n // propagation, that programmatic click bubbles back to the dropzone\n // and re-triggers it — infinite recursion. Native label/keyboard\n // activation of the input is unaffected.\n onClick={(event) => event.stopPropagation()}\n data-slot=\"file-upload-input\"\n />\n </div>\n\n {hasErrorMessage && (\n <FieldMessage id={errorId} variant=\"error\">\n {errorMessage}\n </FieldMessage>\n )}\n {hasHelper && (\n <FieldMessage id={helperId} variant=\"helper\">\n {helperText}\n </FieldMessage>\n )}\n\n {files.length > 0 && (\n <ul data-slot=\"file-upload-list\" className=\"ddga-file-upload__list\">\n {files.map((item) => {\n const status = item.status ?? 'pending';\n return (\n <li\n key={item.id}\n data-slot=\"file-upload-item\"\n data-status={status}\n className=\"ddga-file-upload__item\"\n >\n <span className=\"ddga-file-upload__item-icon\" aria-hidden=\"true\">\n {status === 'success' ? (\n <Check />\n ) : status === 'error' ? (\n <AlertCircle />\n ) : (\n <Upload />\n )}\n </span>\n\n <div className=\"ddga-file-upload__item-main\">\n <div className=\"ddga-file-upload__item-head\">\n <span className=\"ddga-file-upload__item-name\" title={item.file.name}>\n {item.file.name}\n </span>\n <span className=\"ddga-file-upload__item-meta\">\n {formatBytes(item.file.size)}\n </span>\n </div>\n\n {status === 'uploading' && (\n <Progress\n size=\"sm\"\n value={item.progress ?? 0}\n aria-label={`Uploading ${item.file.name}`}\n className=\"ddga-file-upload__item-progress\"\n />\n )}\n\n {status === 'error' && item.error && (\n <span role=\"alert\" className=\"ddga-file-upload__item-error\">\n {item.error}\n </span>\n )}\n </div>\n\n {onRemove && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={`${removeLabel}: ${item.file.name}`}\n onClick={() => onRemove(item.id)}\n className=\"ddga-file-upload__item-remove\"\n >\n <Close aria-hidden=\"true\" />\n </Button>\n )}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { FileUpload };\nexport type { FileUploadProps, UploadFile, FileRejection, FileStatus, RejectionCode };\n"]}
@@ -44,7 +44,14 @@ function ScrollArea({
44
44
  _radixui.ScrollArea.Viewport,
45
45
  {
46
46
  "data-slot": "scroll-area-viewport",
47
- className: _chunkV6MXOJQ4cjs.cn.call(void 0, "ddga-scroll-area__viewport", viewportClassName),
47
+ className: _chunkV6MXOJQ4cjs.cn.call(void 0,
48
+ "ddga-scroll-area__viewport",
49
+ // Vertical-only: constrain Radix's inline `display:table` content
50
+ // wrapper so wide children don't overflow an axis that has no
51
+ // scrollbar (see scroll-area.css). Horizontal/both keep the default.
52
+ orientation === "vertical" && "ddga-scroll-area__viewport--vertical",
53
+ viewportClassName
54
+ ),
48
55
  ref: viewportRef,
49
56
  tabIndex: 0,
50
57
  role: hasLabel ? "region" : void 0,
@@ -100,4 +107,4 @@ function ScrollArea({
100
107
 
101
108
 
102
109
  exports.scrollAreaVariants = scrollAreaVariants; exports.ScrollArea = ScrollArea;
103
- //# sourceMappingURL=chunk-PAUY27WX.cjs.map
110
+ //# sourceMappingURL=chunk-VYOETLZU.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-VYOETLZU.cjs","../src/components/ScrollArea/ScrollArea.tsx"],"names":[],"mappings":"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","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-VYOETLZU.cjs","sourcesContent":[null,"'use client';\n\nimport { ScrollArea as ScrollAreaPrimitive } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\n\n// Orientation is driven by which scrollbar(s) render, NOT by a modifier class —\n// so the cva carries only the base class. (It previously emitted dead\n// `--vertical/--horizontal/--both` classes that no stylesheet matched.) Kept as\n// a cva and exported for API compatibility.\nconst scrollAreaVariants = cva('ddga-scroll-area');\n\nfunction warnMissingLabel(ariaLabel?: string, ariaLabelledby?: string) {\n if (process.env.NODE_ENV === 'production') return;\n if (ariaLabel || ariaLabelledby) return;\n // Warn on every render (dev only) — mirrors the Popover sibling's a11y warning.\n console.warn(\n '[dga/ScrollArea] <ScrollArea> has no accessible name. The scroll viewport is ' +\n 'keyboard-focusable; pass `aria-label` or `aria-labelledby` so screen-reader users ' +\n 'know what region they are scrolling. If the content is itself focusable (e.g. a list ' +\n 'of links) and you do not want a labelled region, pass `viewportProps={{ tabIndex: -1 }}`.',\n );\n}\n\ntype ScrollAreaOrientation = 'vertical' | 'horizontal' | 'both';\n\nexport interface ScrollAreaProps\n extends\n Omit<React.ComponentProps<typeof ScrollAreaPrimitive.Root>, 'asChild' | 'orientation'>,\n Omit<VariantProps<typeof scrollAreaVariants>, 'orientation'> {\n /** Which scrollbar(s) to render. Default `'vertical'`. */\n orientation?: ScrollAreaOrientation;\n /** Ref to the scrollable viewport — use for programmatic scrolling. */\n viewportRef?: React.Ref<HTMLDivElement>;\n /**\n * Extra props forwarded to the viewport element (use `viewportRef` for the ref).\n * To drop the extra tab stop when the scrolled content is itself fully focusable\n * (e.g. a list of links), pass `viewportProps={{ tabIndex: -1 }}`.\n */\n viewportProps?: Omit<React.ComponentProps<'div'>, 'ref'>;\n /** Names the scroll region. Warns (dev only) if neither this nor `aria-labelledby` is set. */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n/**\n * Cross-browser, design-system-styled scroll container (wraps Radix ScrollArea).\n *\n * Set the bounding size (height / max-height) on the element via `className` /\n * `style` — without a bounded size nothing scrolls, exactly like native overflow.\n * The viewport is keyboard-focusable (`tabIndex={0}`) so keyboard users can scroll\n * with the arrow / Page keys; pass `aria-label` to name the region.\n *\n * Does not support `asChild`: it is a structural wrapper composing several Radix\n * parts, and the meaningful node — the viewport — is exposed via `viewportRef`.\n */\nexport function ScrollArea({\n className,\n orientation = 'vertical',\n type = 'hover',\n scrollHideDelay = 600,\n viewportRef,\n viewportProps,\n children,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n ...props\n}: ScrollAreaProps) {\n warnMissingLabel(ariaLabel, ariaLabelledby);\n\n const hasLabel = Boolean(ariaLabel || ariaLabelledby);\n const showVertical = orientation === 'vertical' || orientation === 'both';\n const showHorizontal = orientation === 'horizontal' || orientation === 'both';\n\n const { className: viewportClassName, ...restViewportProps } = viewportProps ?? {};\n\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n type={type}\n scrollHideDelay={scrollHideDelay}\n className={cn(scrollAreaVariants(), className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n data-slot=\"scroll-area-viewport\"\n className={cn(\n 'ddga-scroll-area__viewport',\n // Vertical-only: constrain Radix's inline `display:table` content\n // wrapper so wide children don't overflow an axis that has no\n // scrollbar (see scroll-area.css). Horizontal/both keep the default.\n orientation === 'vertical' && 'ddga-scroll-area__viewport--vertical',\n viewportClassName,\n )}\n ref={viewportRef}\n tabIndex={0}\n role={hasLabel ? 'region' : undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n {...restViewportProps}\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n {showVertical ? (\n <ScrollAreaPrimitive.Scrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation=\"vertical\"\n className=\"ddga-scroll-area__scrollbar\"\n >\n <ScrollAreaPrimitive.Thumb\n data-slot=\"scroll-area-thumb\"\n className=\"ddga-scroll-area__thumb\"\n />\n </ScrollAreaPrimitive.Scrollbar>\n ) : null}\n {showHorizontal ? (\n <ScrollAreaPrimitive.Scrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation=\"horizontal\"\n className=\"ddga-scroll-area__scrollbar\"\n >\n <ScrollAreaPrimitive.Thumb\n data-slot=\"scroll-area-thumb\"\n className=\"ddga-scroll-area__thumb\"\n />\n </ScrollAreaPrimitive.Scrollbar>\n ) : null}\n {orientation === 'both' ? (\n <ScrollAreaPrimitive.Corner\n data-slot=\"scroll-area-corner\"\n className=\"ddga-scroll-area__corner\"\n />\n ) : null}\n </ScrollAreaPrimitive.Root>\n );\n}\n\nexport { scrollAreaVariants };\nexport type { ScrollAreaOrientation };\n"]}
@@ -128,4 +128,4 @@ export {
128
128
  StatChart,
129
129
  StatChange
130
130
  };
131
- //# sourceMappingURL=chunk-TO7F4EHC.js.map
131
+ //# sourceMappingURL=chunk-WOJUO43J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Stat/Stat.tsx"],"sourcesContent":["'use client';\n\nimport { type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { CaretUp, CaretDown, Minus } from '../../internal/icons';\n\n// ─── 1. Variants (cva) ─── //\n\nconst statVariants = cva('ddga-stat', {\n variants: {\n variant: {\n flat: 'ddga-stat--flat',\n elevated: 'ddga-stat--elevated',\n accent: 'ddga-stat--accent',\n // Soft sentiment-tinted gradient surface (reuses the accent tint vars).\n gradient: 'ddga-stat--gradient',\n },\n size: {\n sm: 'ddga-stat--sm',\n md: 'ddga-stat--md',\n lg: 'ddga-stat--lg',\n // Hero/display size for headline KPIs (display-scale value).\n xl: 'ddga-stat--xl',\n },\n },\n defaultVariants: {\n variant: 'flat',\n size: 'md',\n },\n});\n\ntype ChangeVariant = 'text' | 'chip';\n\ntype Trend = 'up' | 'down' | 'flat';\ntype Sentiment = 'positive' | 'negative' | 'neutral';\n\n// trend → caret icon (carried aria-hidden; carets are RTL-neutral).\nconst TREND_ICONS: Record<Trend, ReactNode> = {\n up: <CaretUp aria-hidden=\"true\" />,\n down: <CaretDown aria-hidden=\"true\" />,\n flat: <Minus aria-hidden=\"true\" />,\n};\n\n// Default sentiment when none is given explicitly.\nconst TREND_SENTIMENT: Record<Trend, Sentiment> = {\n up: 'positive',\n down: 'negative',\n flat: 'neutral',\n};\n\n// Explicit sentiment wins; else derive from trend; else undefined (no color).\nfunction resolveSentiment(trend?: Trend, sentiment?: Sentiment): Sentiment | undefined {\n if (sentiment) return sentiment;\n if (trend) return TREND_SENTIMENT[trend];\n return undefined;\n}\n\n// ─── 2. Types ─── //\n\ninterface StatProps extends React.ComponentProps<'div'>, VariantProps<typeof statVariants> {\n /** Small, muted label above the value. */\n label?: ReactNode;\n /** The metric, pre-formatted by the consumer (e.g. \"3,204\", \"SAR 1.2M\"). */\n value?: ReactNode;\n /** Change text — include the sign (e.g. \"+12.5%\") so AT conveys direction. */\n change?: ReactNode;\n /** Muted context beside the change (e.g. \"vs last month\"). */\n changeLabel?: ReactNode;\n /** Arrow direction: up → CaretUp, down → CaretDown, flat → Minus. */\n trend?: Trend;\n /** Change color. Omitted → derived from `trend`. Explicit always wins. */\n sentiment?: Sentiment;\n /**\n * How the change renders: `'text'` (default — colored text + caret) or\n * `'chip'` (the same, wrapped in a sentiment-tinted pill). Threaded to the\n * inner `StatChange`.\n */\n changeVariant?: ChangeVariant;\n /** Optional icon at the inline-end of the label row (decorative). */\n icon?: ReactNode;\n}\n\ntype StatLabelProps = React.ComponentProps<'div'>;\ntype StatValueProps = React.ComponentProps<'div'>;\ntype StatChartProps = React.ComponentProps<'div'>;\ninterface StatChangeProps extends React.ComponentProps<'div'> {\n trend?: Trend;\n sentiment?: Sentiment;\n /** `'chip'` wraps the change in a sentiment-tinted pill. Defaults to `'text'`. */\n variant?: ChangeVariant;\n}\n\n// ─── 3. Components ─── //\n\n/**\n * KPI / metric tile. Two ways to fill it, designed to combine:\n *\n * - **Prop mode** (the common case): pass `label` / `value` / `change` /\n * `changeLabel` / `trend` / `icon` and Stat renders the standard layout.\n * - **Compound children**: append extra content as children — it renders AFTER\n * the prop-mode rows.\n *\n * The blessed hybrid is **prop mode + a `<StatChart>` child** (a sparkline under\n * the metric). Do NOT also pass a child that duplicates a prop slot (e.g. a\n * `value` prop *and* a `<StatValue>` child) — both render and you get a\n * double. One source per slot. Stat owns its surface; use it directly (don't\n * wrap a bare `<Card>`), and lay tiles out with `<StatGroup>`.\n */\nfunction Stat({\n variant,\n size,\n label,\n value,\n change,\n changeLabel,\n trend,\n sentiment,\n changeVariant,\n icon,\n className,\n children,\n ...props\n}: StatProps) {\n const resolvedSentiment = resolveSentiment(trend, sentiment);\n return (\n <div\n data-slot=\"stat\"\n data-variant={variant ?? 'flat'}\n data-trend={trend}\n data-sentiment={resolvedSentiment}\n className={cn(statVariants({ variant, size }), className)}\n {...props}\n >\n {label || icon ? (\n <div className=\"ddga-stat__label-row\">\n {label ? <StatLabel>{label}</StatLabel> : null}\n {icon ? (\n <span className=\"ddga-stat__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n ) : null}\n </div>\n ) : null}\n {value ? <StatValue>{value}</StatValue> : null}\n {change || changeLabel ? (\n <div className=\"ddga-stat__change-row\">\n {change ? (\n <StatChange trend={trend} sentiment={sentiment} variant={changeVariant}>\n {change}\n </StatChange>\n ) : null}\n {changeLabel ? <span className=\"ddga-stat__change-label\">{changeLabel}</span> : null}\n </div>\n ) : null}\n {children}\n </div>\n );\n}\n\nfunction StatLabel({ className, ...props }: StatLabelProps) {\n return <div data-slot=\"stat-label\" className={cn('ddga-stat__label', className)} {...props} />;\n}\n\nfunction StatValue({ className, ...props }: StatValueProps) {\n return <div data-slot=\"stat-value\" className={cn('ddga-stat__value', className)} {...props} />;\n}\n\n/**\n * Styled slot for a consumer-supplied sparkline / mini-chart. The library ships\n * no charting dependency — drop your own `<svg>`/chart in here and it gets a\n * consistent height + spacing, stretched to the tile width.\n */\nfunction StatChart({ className, ...props }: StatChartProps) {\n return <div data-slot=\"stat-chart\" className={cn('ddga-stat__chart', className)} {...props} />;\n}\n\nfunction StatChange({ trend, sentiment, variant, className, children, ...props }: StatChangeProps) {\n const resolvedSentiment = resolveSentiment(trend, sentiment);\n return (\n <div\n data-slot=\"stat-change\"\n data-trend={trend}\n data-sentiment={resolvedSentiment}\n className={cn(\n 'ddga-stat__change',\n resolvedSentiment ? `ddga-stat__change--${resolvedSentiment}` : null,\n variant === 'chip' && 'ddga-stat__change--chip',\n className,\n )}\n {...props}\n >\n {trend ? <span className=\"ddga-stat__change-icon\">{TREND_ICONS[trend]}</span> : null}\n {children}\n </div>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { Stat, StatLabel, StatValue, StatChart, StatChange, statVariants };\nexport type { StatProps, StatLabelProps, StatValueProps, StatChartProps, StatChangeProps };\n"],"mappings":"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","names":[]}
@@ -1,9 +1,9 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
2
 
3
3
 
4
- var _chunk2HZGIP5Vcjs = require('../../chunk-2HZGIP5V.cjs');
4
+ var _chunkVMAJ34DCcjs = require('../../chunk-VMAJ34DC.cjs');
5
5
  require('../../chunk-ELDHIKFD.cjs');
6
- require('../../chunk-W6B7GJLN.cjs');
6
+ require('../../chunk-NU3WUSG7.cjs');
7
7
  require('../../chunk-EACNRR3C.cjs');
8
8
  require('../../chunk-UK2SFZIQ.cjs');
9
9
  require('../../chunk-3RUIKBH4.cjs');
@@ -15,5 +15,5 @@ require('../../chunk-NH3KGR65.cjs');
15
15
  require('../../chunk-V6MXOJQ4.cjs');
16
16
 
17
17
 
18
- exports.FileUpload = _chunk2HZGIP5Vcjs.FileUpload;
18
+ exports.FileUpload = _chunkVMAJ34DCcjs.FileUpload;
19
19
  //# sourceMappingURL=FileUpload.cjs.map
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import {
3
3
  FileUpload
4
- } from "../../chunk-YJQZQS7P.js";
4
+ } from "../../chunk-GNL72FRN.js";
5
5
  import "../../chunk-IW7UX7SA.js";
6
- import "../../chunk-FWGFOC2T.js";
6
+ import "../../chunk-RSXDPFXK.js";
7
7
  import "../../chunk-N5JDL4VE.js";
8
8
  import "../../chunk-4RU33BRQ.js";
9
9
  import "../../chunk-TH3ITGUM.js";