@devalok/shilp-sutra 0.53.0 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/AGENTS.md +7 -1
  2. package/BREAKING.json +29 -0
  3. package/MIGRATION.md +55 -0
  4. package/dist/composed/avatar-group.d.ts +11 -9
  5. package/dist/composed/avatar-group.d.ts.map +1 -1
  6. package/dist/composed/avatar-group.js +108 -140
  7. package/dist/composed/avatar-group.js.map +1 -1
  8. package/dist/composed/bulk-action-bar.d.ts +19 -11
  9. package/dist/composed/bulk-action-bar.d.ts.map +1 -1
  10. package/dist/composed/bulk-action-bar.js +81 -110
  11. package/dist/composed/bulk-action-bar.js.map +1 -1
  12. package/dist/composed/error-boundary.d.ts +15 -3
  13. package/dist/composed/error-boundary.d.ts.map +1 -1
  14. package/dist/composed/error-boundary.js +43 -26
  15. package/dist/composed/error-boundary.js.map +1 -1
  16. package/dist/composed/loading-skeleton.d.ts +2 -0
  17. package/dist/composed/loading-skeleton.d.ts.map +1 -1
  18. package/dist/composed/loading-skeleton.js +79 -56
  19. package/dist/composed/loading-skeleton.js.map +1 -1
  20. package/dist/composed/master-detail.d.ts +21 -8
  21. package/dist/composed/master-detail.d.ts.map +1 -1
  22. package/dist/composed/master-detail.js +91 -77
  23. package/dist/composed/master-detail.js.map +1 -1
  24. package/dist/composed/page-skeletons.d.ts +6 -0
  25. package/dist/composed/page-skeletons.d.ts.map +1 -1
  26. package/dist/composed/page-skeletons.js +93 -71
  27. package/dist/composed/page-skeletons.js.map +1 -1
  28. package/dist/shell/index.d.ts +5 -3
  29. package/dist/shell/index.d.ts.map +1 -1
  30. package/dist/shell/index.js +2 -3
  31. package/dist/shell/notification-preferences.d.ts.map +1 -1
  32. package/dist/shell/notification-preferences.js +2 -0
  33. package/dist/shell/notification-preferences.js.map +1 -1
  34. package/dist/ui/combobox.d.ts +1 -1
  35. package/dist/ui/combobox.d.ts.map +1 -1
  36. package/dist/ui/combobox.js +133 -128
  37. package/dist/ui/combobox.js.map +1 -1
  38. package/dist/ui/file-upload.d.ts.map +1 -1
  39. package/dist/ui/file-upload.js +124 -138
  40. package/dist/ui/file-upload.js.map +1 -1
  41. package/dist/ui/form.d.ts +7 -0
  42. package/dist/ui/form.d.ts.map +1 -1
  43. package/dist/ui/form.js +4 -2
  44. package/dist/ui/form.js.map +1 -1
  45. package/dist/ui/icon-button.d.ts +2 -1
  46. package/dist/ui/icon-button.d.ts.map +1 -1
  47. package/dist/ui/icon-button.js +1 -1
  48. package/dist/ui/icon-button.js.map +1 -1
  49. package/dist/ui/label.d.ts.map +1 -1
  50. package/dist/ui/label.js +7 -6
  51. package/dist/ui/label.js.map +1 -1
  52. package/dist/ui/spinner.d.ts.map +1 -1
  53. package/dist/ui/spinner.js +50 -44
  54. package/dist/ui/spinner.js.map +1 -1
  55. package/dist/ui/switch.d.ts.map +1 -1
  56. package/dist/ui/switch.js +24 -24
  57. package/dist/ui/switch.js.map +1 -1
  58. package/dist/ui/table.js +1 -1
  59. package/dist/ui/table.js.map +1 -1
  60. package/docs/components/composed/bulk-action-bar.md +9 -3
  61. package/docs/components/composed/error-boundary.md +18 -2
  62. package/docs/components/composed/master-detail.md +12 -2
  63. package/docs/components/composed/page-skeletons.md +2 -2
  64. package/docs/components/composed/rich-chat-input.md +18 -6
  65. package/docs/components/composed/simple-tooltip.md +1 -1
  66. package/docs/components/shell/app-command-palette.md +2 -1
  67. package/docs/components/shell/bottom-navbar.md +4 -4
  68. package/docs/components/shell/command-registry.md +2 -2
  69. package/docs/components/shell/link-context.md +2 -2
  70. package/docs/components/shell/top-bar.md +1 -1
  71. package/docs/components/ui/search-input.md +2 -2
  72. package/docs/components/ui/slider.md +2 -2
  73. package/docs/components/ui/split-button.md +3 -3
  74. package/llms.txt +2 -2
  75. package/make-kit/Guidelines.md +1 -1
  76. package/make-kit/components/overview.md +2 -2
  77. package/make-kit/foundations/surfaces.md +1 -1
  78. package/mcp-manifest.json +403 -147
  79. package/package.json +1 -6
  80. package/skill/SKILL.md +1 -1
  81. package/skill/chat-skill/README.md +18 -0
  82. package/skill/chat-skill/SKILL.md +78 -0
  83. package/skill/chat-skill/chatgpt-instructions.md +26 -0
  84. package/skill/chat-skill/gemini-instructions.md +25 -0
  85. package/skill/references/components.md +2 -2
  86. package/dist/shell/sidebar.d.ts +0 -113
  87. package/dist/shell/sidebar.d.ts.map +0 -1
  88. package/dist/shell/sidebar.js +0 -293
  89. package/dist/shell/sidebar.js.map +0 -1
  90. package/docs/components/shell/sidebar.md +0 -103
@@ -3,102 +3,125 @@ import { Skeleton as t } from "../ui/skeleton.js";
3
3
  import * as n from "react";
4
4
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
5
5
  //#region src/composed/loading-skeleton.tsx
6
- var a = n.forwardRef(function({ className: n, ...a }, o) {
6
+ var a = (e, t) => Math.max(0, Math.floor(typeof e == "number" && !Number.isNaN(e) ? e : t));
7
+ function o(e) {
8
+ return {
9
+ role: "status",
10
+ "aria-busy": !0,
11
+ "aria-label": e ?? "Loading"
12
+ };
13
+ }
14
+ function s({ label: e }) {
15
+ return /* @__PURE__ */ i("span", {
16
+ className: "sr-only",
17
+ children: [e ?? "Loading", "…"]
18
+ });
19
+ }
20
+ var c = n.forwardRef(function({ className: n, label: a, ...c }, l) {
7
21
  return /* @__PURE__ */ i("div", {
8
- ref: o,
9
- ...a,
10
- className: e("rounded-surface border border-card-strong bg-surface-raised p-ds-05b", n),
22
+ ref: l,
23
+ ...o(a),
24
+ ...c,
25
+ className: e("rounded-surface border border-card bg-surface-raised p-ds-05b", n),
11
26
  children: [
27
+ /* @__PURE__ */ r(s, { label: a }),
12
28
  /* @__PURE__ */ i("div", {
13
29
  className: "flex items-center justify-between pb-ds-05",
14
- children: [/* @__PURE__ */ r(t, { className: "h-ds-05 w-[128px] bg-surface-raised-hover" }), /* @__PURE__ */ r(t, { className: "h-ico-sm w-ico-sm rounded bg-surface-raised-hover" })]
30
+ children: [/* @__PURE__ */ r(t, { className: "h-ds-05 w-ds-13" }), /* @__PURE__ */ r(t, { className: "h-ico-sm w-ico-sm rounded" })]
15
31
  }),
16
32
  /* @__PURE__ */ i("div", {
17
33
  className: "space-y-ds-04",
18
34
  children: [
19
- /* @__PURE__ */ r(t, { className: "h-ds-04 w-full bg-surface-raised-hover" }),
20
- /* @__PURE__ */ r(t, { className: "h-ds-04 w-4/5 bg-surface-raised-hover" }),
21
- /* @__PURE__ */ r(t, { className: "h-ds-04 w-3/5 bg-surface-raised-hover" })
35
+ /* @__PURE__ */ r(t, { className: "h-ds-04 w-full" }),
36
+ /* @__PURE__ */ r(t, { className: "h-ds-04 w-4/5" }),
37
+ /* @__PURE__ */ r(t, { className: "h-ds-04 w-3/5" })
22
38
  ]
23
39
  }),
24
40
  /* @__PURE__ */ i("div", {
25
41
  className: "flex items-center gap-ds-03 pt-ds-05",
26
- children: [/* @__PURE__ */ r(t, { className: "h-ds-xs w-ds-xs rounded-pill bg-surface-raised-hover" }), /* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-11 bg-surface-raised-hover" })]
42
+ children: [/* @__PURE__ */ r(t, { className: "h-ds-xs w-ds-xs rounded-pill" }), /* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-11" })]
27
43
  })
28
44
  ]
29
45
  });
30
46
  });
31
- a.displayName = "CardSkeleton";
32
- var o = n.forwardRef(function({ rows: n = 5, columns: a = 4, className: o, ...s }, c) {
47
+ c.displayName = "CardSkeleton";
48
+ var l = n.forwardRef(function({ rows: n = 5, columns: c = 4, className: l, label: u, ...d }, f) {
49
+ let p = a(n, 5), m = Math.max(1, a(c, 4));
33
50
  return /* @__PURE__ */ i("div", {
34
- ref: c,
35
- ...s,
36
- className: e("overflow-hidden rounded-surface border border-card-strong", o),
37
- children: [/* @__PURE__ */ r("div", {
38
- className: "flex items-center gap-ds-05 border-b border-surface-border-strong bg-surface-raised px-ds-05 py-ds-04",
39
- children: Array.from({ length: a }).map((n, i) => /* @__PURE__ */ r(t, { className: e("h-ds-04 bg-surface-raised-hover", i === 0 ? "w-ds-13" : "flex-1") }, `head-${i}`))
40
- }), Array.from({ length: n }).map((i, o) => /* @__PURE__ */ r("div", {
41
- className: e("flex items-center gap-ds-05 px-ds-05 py-ds-04", o < n - 1 && "border-b border-surface-border-strong"),
42
- style: { animationDelay: `${o * 50}ms` },
43
- children: Array.from({ length: a }).map((n, i) => /* @__PURE__ */ r(t, { className: e("h-ds-04 bg-surface-raised-hover", i === 0 ? "w-ds-13" : "flex-1") }, `cell-${o}-${i}`))
44
- }, `row-${o}`))]
51
+ ref: f,
52
+ ...o(u),
53
+ ...d,
54
+ className: e("overflow-hidden rounded-surface border border-card", l),
55
+ children: [
56
+ /* @__PURE__ */ r(s, { label: u }),
57
+ /* @__PURE__ */ r("div", {
58
+ className: "flex items-center gap-ds-05 border-b border-surface-border-strong bg-surface-raised px-ds-05 py-ds-04",
59
+ children: Array.from({ length: m }).map((n, i) => /* @__PURE__ */ r(t, { className: e("h-ds-04", i === 0 ? "w-ds-13" : "flex-1") }, `head-${i}`))
60
+ }),
61
+ Array.from({ length: p }).map((n, i) => /* @__PURE__ */ r("div", {
62
+ className: e("flex items-center gap-ds-05 px-ds-05 py-ds-04", i < p - 1 && "border-b border-surface-border-strong"),
63
+ children: Array.from({ length: m }).map((n, a) => /* @__PURE__ */ r(t, { className: e("h-ds-04", a === 0 ? "w-ds-13" : "flex-1") }, `cell-${i}-${a}`))
64
+ }, `row-${i}`))
65
+ ]
45
66
  });
46
67
  });
47
- o.displayName = "TableSkeleton";
48
- var s = n.forwardRef(function({ columns: n = 4, cardsPerColumn: a = 3, className: o, ...s }, c) {
49
- return /* @__PURE__ */ r("div", {
50
- ref: c,
51
- ...s,
52
- className: e("flex gap-ds-05 overflow-x-auto", o),
53
- children: Array.from({ length: n }).map((e, n) => /* @__PURE__ */ i("div", {
68
+ l.displayName = "TableSkeleton";
69
+ var u = n.forwardRef(function({ columns: n = 4, cardsPerColumn: c = 3, className: l, label: u, ...d }, f) {
70
+ let p = a(n, 4), m = a(c, 3);
71
+ return /* @__PURE__ */ i("div", {
72
+ ref: f,
73
+ ...o(u),
74
+ ...d,
75
+ className: e("flex gap-ds-05 overflow-x-auto", l),
76
+ children: [/* @__PURE__ */ r(s, { label: u }), Array.from({ length: p }).map((e, n) => /* @__PURE__ */ i("div", {
54
77
  className: "flex w-[272px] shrink-0 flex-col gap-ds-03",
55
78
  children: [/* @__PURE__ */ i("div", {
56
79
  className: "flex items-center justify-between px-ds-02 py-ds-03",
57
80
  children: [/* @__PURE__ */ i("div", {
58
81
  className: "flex items-center gap-ds-03",
59
82
  children: [
60
- /* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-04 rounded bg-surface-raised-hover" }),
61
- /* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-11 bg-surface-raised-hover" }),
62
- /* @__PURE__ */ r(t, { className: "h-ds-05 w-ds-05b rounded-pill bg-surface-raised-hover" })
83
+ /* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-04 rounded" }),
84
+ /* @__PURE__ */ r(t, { className: "h-ds-04 w-ds-11" }),
85
+ /* @__PURE__ */ r(t, { className: "h-ds-05 w-ds-05b rounded-pill" })
63
86
  ]
64
- }), /* @__PURE__ */ r(t, { className: "h-ico-sm w-ico-sm rounded bg-surface-raised-hover" })]
65
- }), Array.from({ length: a }).map((e, o) => /* @__PURE__ */ i("div", {
66
- className: "rounded-surface border border-card-strong bg-surface-raised p-ds-04",
67
- style: { animationDelay: `${(n * a + o) * 50}ms` },
87
+ }), /* @__PURE__ */ r(t, { className: "h-ico-sm w-ico-sm rounded" })]
88
+ }), Array.from({ length: m }).map((e, a) => /* @__PURE__ */ i("div", {
89
+ className: "rounded-surface border border-card bg-surface-raised p-ds-04",
68
90
  children: [/* @__PURE__ */ i("div", {
69
91
  className: "space-y-ds-03",
70
- children: [/* @__PURE__ */ r(t, { className: "h-ds-04 w-4/5 bg-surface-raised-hover" }), /* @__PURE__ */ r(t, { className: "h-ds-04 w-3/5 bg-surface-raised-hover" })]
92
+ children: [/* @__PURE__ */ r(t, { className: "h-ds-04 w-4/5" }), /* @__PURE__ */ r(t, { className: "h-ds-04 w-3/5" })]
71
93
  }), /* @__PURE__ */ i("div", {
72
94
  className: "flex items-center justify-between pt-ds-04",
73
95
  children: [/* @__PURE__ */ i("div", {
74
96
  className: "flex items-center gap-ds-02b",
75
- children: [/* @__PURE__ */ r(t, { className: "h-ico-md w-ico-md rounded-pill bg-surface-raised-hover" }), /* @__PURE__ */ r(t, { className: "h-ds-03 w-ds-10 bg-surface-raised-hover" })]
76
- }), /* @__PURE__ */ r(t, { className: "h-ds-05 w-ds-lg rounded-pill bg-surface-raised-hover" })]
97
+ children: [/* @__PURE__ */ r(t, { className: "h-ico-md w-ico-md rounded-pill" }), /* @__PURE__ */ r(t, { className: "h-ds-03 w-ds-10" })]
98
+ }), /* @__PURE__ */ r(t, { className: "h-ds-05 w-ds-lg rounded-pill" })]
77
99
  })]
78
- }, `card-${n}-${o}`))]
79
- }, `col-${n}`))
100
+ }, `card-${n}-${a}`))]
101
+ }, `col-${n}`))]
80
102
  });
81
103
  });
82
- s.displayName = "BoardSkeleton";
83
- var c = n.forwardRef(function({ rows: n = 6, showAvatar: a = !0, className: o, ...s }, c) {
84
- return /* @__PURE__ */ r("div", {
85
- ref: c,
86
- ...s,
87
- className: e("flex flex-col", o),
88
- children: Array.from({ length: n }).map((o, s) => /* @__PURE__ */ i("div", {
89
- className: e("flex items-center gap-ds-04 py-ds-04", s < n - 1 && "border-b border-surface-border-strong"),
90
- style: { animationDelay: `${s * 50}ms` },
104
+ u.displayName = "BoardSkeleton";
105
+ var d = n.forwardRef(function({ rows: n = 6, showAvatar: c = !0, className: l, label: u, ...d }, f) {
106
+ let p = a(n, 6);
107
+ return /* @__PURE__ */ i("div", {
108
+ ref: f,
109
+ ...o(u),
110
+ ...d,
111
+ className: e("flex flex-col", l),
112
+ children: [/* @__PURE__ */ r(s, { label: u }), Array.from({ length: p }).map((n, a) => /* @__PURE__ */ i("div", {
113
+ className: e("flex items-center gap-ds-04 py-ds-04", a < p - 1 && "border-b border-surface-border-strong"),
91
114
  children: [
92
- a && /* @__PURE__ */ r(t, { className: "h-ds-sm w-ds-sm shrink-0 rounded-pill bg-surface-raised-hover" }),
115
+ c && /* @__PURE__ */ r(t, { className: "h-ds-sm w-ds-sm shrink-0 rounded-pill" }),
93
116
  /* @__PURE__ */ i("div", {
94
117
  className: "flex flex-1 flex-col gap-ds-02b",
95
- children: [/* @__PURE__ */ r(t, { className: "h-ds-04 w-2/5 bg-surface-raised-hover" }), /* @__PURE__ */ r(t, { className: "h-ds-03 w-3/5 bg-surface-raised-hover" })]
118
+ children: [/* @__PURE__ */ r(t, { className: "h-ds-04 w-2/5" }), /* @__PURE__ */ r(t, { className: "h-ds-03 w-3/5" })]
96
119
  }),
97
- /* @__PURE__ */ r(t, { className: "h-ds-05b w-[56px] rounded-pill bg-surface-raised-hover" })
120
+ /* @__PURE__ */ r(t, { className: "h-ds-05b w-ds-09 rounded-pill" })
98
121
  ]
99
- }, `list-${s}`))
122
+ }, `list-${a}`))]
100
123
  });
101
124
  });
102
- c.displayName = "ListSkeleton";
125
+ d.displayName = "ListSkeleton";
103
126
  //#endregion
104
- export { s as BoardSkeleton, a as CardSkeleton, c as ListSkeleton, o as TableSkeleton };
127
+ export { u as BoardSkeleton, c as CardSkeleton, d as ListSkeleton, l as TableSkeleton };
@@ -1 +1 @@
1
- {"version":3,"file":"loading-skeleton.js","names":[],"sources":["../../src/composed/loading-skeleton.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\n\nexport interface CardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {\n className?: string\n}\n\nconst CardSkeleton = React.forwardRef<HTMLDivElement, CardSkeletonProps>(\n function CardSkeleton({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n {...props}\n className={cn(\n 'rounded-surface border border-card-strong bg-surface-raised p-ds-05b',\n className,\n )}\n >\n <div className=\"flex items-center justify-between pb-ds-05\">\n <Skeleton className=\"h-ds-05 w-[128px] bg-surface-raised-hover\" />\n <Skeleton className=\"h-ico-sm w-ico-sm rounded bg-surface-raised-hover\" />\n </div>\n <div className=\"space-y-ds-04\">\n <Skeleton className=\"h-ds-04 w-full bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-4/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-3/5 bg-surface-raised-hover\" />\n </div>\n <div className=\"flex items-center gap-ds-03 pt-ds-05\">\n <Skeleton className=\"h-ds-xs w-ds-xs rounded-pill bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-ds-11 bg-surface-raised-hover\" />\n </div>\n </div>\n )\n},\n)\n\nCardSkeleton.displayName = 'CardSkeleton'\n\nexport interface TableSkeletonProps extends CardSkeletonProps {\n rows?: number\n columns?: number\n}\n\nconst TableSkeleton = React.forwardRef<HTMLDivElement, TableSkeletonProps>(\n function TableSkeleton({\n rows = 5,\n columns = 4,\n className,\n ...props\n}, ref) {\n return (\n <div\n ref={ref}\n {...props}\n className={cn(\n 'overflow-hidden rounded-surface border border-card-strong',\n className,\n )}\n >\n {/* Header */}\n <div className=\"flex items-center gap-ds-05 border-b border-surface-border-strong bg-surface-raised px-ds-05 py-ds-04\">\n {Array.from({ length: columns }).map((_, i) => (\n <Skeleton\n key={`head-${i}`}\n className={cn(\n 'h-ds-04 bg-surface-raised-hover',\n i === 0 ? 'w-ds-13' : 'flex-1',\n )}\n />\n ))}\n </div>\n\n {/* Rows */}\n {Array.from({ length: rows }).map((_, rowIndex) => (\n <div\n key={`row-${rowIndex}`}\n className={cn(\n 'flex items-center gap-ds-05 px-ds-05 py-ds-04',\n rowIndex < rows - 1 && 'border-b border-surface-border-strong',\n )}\n style={{ animationDelay: `${rowIndex * 50}ms` }}\n >\n {Array.from({ length: columns }).map((_, colIndex) => (\n <Skeleton\n key={`cell-${rowIndex}-${colIndex}`}\n className={cn(\n 'h-ds-04 bg-surface-raised-hover',\n colIndex === 0 ? 'w-ds-13' : 'flex-1',\n )}\n />\n ))}\n </div>\n ))}\n </div>\n )\n},\n)\n\nTableSkeleton.displayName = 'TableSkeleton'\n\nexport interface BoardSkeletonProps extends CardSkeletonProps {\n columns?: number\n cardsPerColumn?: number\n}\n\nconst BoardSkeleton = React.forwardRef<HTMLDivElement, BoardSkeletonProps>(\n function BoardSkeleton({\n columns = 4,\n cardsPerColumn = 3,\n className,\n ...props\n}, ref) {\n return (\n <div ref={ref} {...props} className={cn('flex gap-ds-05 overflow-x-auto', className)}>\n {Array.from({ length: columns }).map((_, colIndex) => (\n <div\n key={`col-${colIndex}`}\n className=\"flex w-[272px] shrink-0 flex-col gap-ds-03\"\n >\n {/* Column header */}\n <div className=\"flex items-center justify-between px-ds-02 py-ds-03\">\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className=\"h-ds-04 w-ds-04 rounded bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-ds-11 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-05 w-ds-05b rounded-pill bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-ico-sm w-ico-sm rounded bg-surface-raised-hover\" />\n </div>\n\n {/* Column cards */}\n {Array.from({ length: cardsPerColumn }).map((_, cardIndex) => (\n <div\n key={`card-${colIndex}-${cardIndex}`}\n className=\"rounded-surface border border-card-strong bg-surface-raised p-ds-04\"\n style={{ animationDelay: `${(colIndex * cardsPerColumn + cardIndex) * 50}ms` }}\n >\n <div className=\"space-y-ds-03\">\n <Skeleton className=\"h-ds-04 w-4/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-3/5 bg-surface-raised-hover\" />\n </div>\n <div className=\"flex items-center justify-between pt-ds-04\">\n <div className=\"flex items-center gap-ds-02b\">\n <Skeleton className=\"h-ico-md w-ico-md rounded-pill bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-03 w-ds-10 bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-ds-05 w-ds-lg rounded-pill bg-surface-raised-hover\" />\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\n )\n},\n)\n\nBoardSkeleton.displayName = 'BoardSkeleton'\n\nexport interface ListSkeletonProps extends CardSkeletonProps {\n rows?: number\n showAvatar?: boolean\n}\n\nconst ListSkeleton = React.forwardRef<HTMLDivElement, ListSkeletonProps>(\n function ListSkeleton({\n rows = 6,\n showAvatar = true,\n className,\n ...props\n}, ref) {\n return (\n <div ref={ref} {...props} className={cn('flex flex-col', className)}>\n {Array.from({ length: rows }).map((_, i) => (\n <div\n key={`list-${i}`}\n className={cn(\n 'flex items-center gap-ds-04 py-ds-04',\n i < rows - 1 && 'border-b border-surface-border-strong',\n )}\n style={{ animationDelay: `${i * 50}ms` }}\n >\n {showAvatar && (\n <Skeleton className=\"h-ds-sm w-ds-sm shrink-0 rounded-pill bg-surface-raised-hover\" />\n )}\n <div className=\"flex flex-1 flex-col gap-ds-02b\">\n <Skeleton className=\"h-ds-04 w-2/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-03 w-3/5 bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-ds-05b w-[56px] rounded-pill bg-surface-raised-hover\" />\n </div>\n ))}\n </div>\n )\n},\n)\n\nListSkeleton.displayName = 'ListSkeleton'\n\nexport { BoardSkeleton, CardSkeleton, ListSkeleton,TableSkeleton }\n"],"mappings":"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"}
1
+ {"version":3,"file":"loading-skeleton.js","names":[],"sources":["../../src/composed/loading-skeleton.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\n\n// Non-negative integer count (guards Array.from against NaN / negatives → RangeError).\nconst clamp = (n: number | undefined, fallback: number) =>\n Math.max(0, Math.floor(typeof n === 'number' && !Number.isNaN(n) ? n : fallback))\n\n// role=status + aria-busy so AT announces the loading region (child Skeletons are\n// aria-hidden). sr-only label gives the announcement text.\nfunction statusProps(label?: string) {\n return { role: 'status' as const, 'aria-busy': true, 'aria-label': label ?? 'Loading' }\n}\nfunction SrLabel({ label }: { label?: string }) {\n return <span className=\"sr-only\">{label ?? 'Loading'}…</span>\n}\n\nexport interface CardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {\n className?: string\n /** Accessible label for the loading region. @default 'Loading' */\n label?: string\n}\n\nconst CardSkeleton = React.forwardRef<HTMLDivElement, CardSkeletonProps>(\n function CardSkeleton({ className, label, ...props }, ref) {\n return (\n <div\n ref={ref}\n {...statusProps(label)}\n {...props}\n className={cn('rounded-surface border border-card bg-surface-raised p-ds-05b', className)}\n >\n <SrLabel label={label} />\n <div className=\"flex items-center justify-between pb-ds-05\">\n <Skeleton className=\"h-ds-05 w-ds-13\" />\n <Skeleton className=\"h-ico-sm w-ico-sm rounded\" />\n </div>\n <div className=\"space-y-ds-04\">\n <Skeleton className=\"h-ds-04 w-full\" />\n <Skeleton className=\"h-ds-04 w-4/5\" />\n <Skeleton className=\"h-ds-04 w-3/5\" />\n </div>\n <div className=\"flex items-center gap-ds-03 pt-ds-05\">\n <Skeleton className=\"h-ds-xs w-ds-xs rounded-pill\" />\n <Skeleton className=\"h-ds-04 w-ds-11\" />\n </div>\n </div>\n )\n },\n)\nCardSkeleton.displayName = 'CardSkeleton'\n\nexport interface TableSkeletonProps extends CardSkeletonProps {\n rows?: number\n columns?: number\n}\n\nconst TableSkeleton = React.forwardRef<HTMLDivElement, TableSkeletonProps>(\n function TableSkeleton({ rows = 5, columns = 4, className, label, ...props }, ref) {\n const r = clamp(rows, 5)\n const c = Math.max(1, clamp(columns, 4))\n return (\n <div\n ref={ref}\n {...statusProps(label)}\n {...props}\n className={cn('overflow-hidden rounded-surface border border-card', className)}\n >\n <SrLabel label={label} />\n {/* Header */}\n <div className=\"flex items-center gap-ds-05 border-b border-surface-border-strong bg-surface-raised px-ds-05 py-ds-04\">\n {Array.from({ length: c }).map((_, i) => (\n <Skeleton key={`head-${i}`} className={cn('h-ds-04', i === 0 ? 'w-ds-13' : 'flex-1')} />\n ))}\n </div>\n {/* Rows */}\n {Array.from({ length: r }).map((_, rowIndex) => (\n <div\n key={`row-${rowIndex}`}\n className={cn(\n 'flex items-center gap-ds-05 px-ds-05 py-ds-04',\n rowIndex < r - 1 && 'border-b border-surface-border-strong',\n )}\n >\n {Array.from({ length: c }).map((_, colIndex) => (\n <Skeleton\n key={`cell-${rowIndex}-${colIndex}`}\n className={cn('h-ds-04', colIndex === 0 ? 'w-ds-13' : 'flex-1')}\n />\n ))}\n </div>\n ))}\n </div>\n )\n },\n)\nTableSkeleton.displayName = 'TableSkeleton'\n\nexport interface BoardSkeletonProps extends CardSkeletonProps {\n columns?: number\n cardsPerColumn?: number\n}\n\nconst BoardSkeleton = React.forwardRef<HTMLDivElement, BoardSkeletonProps>(\n function BoardSkeleton({ columns = 4, cardsPerColumn = 3, className, label, ...props }, ref) {\n const c = clamp(columns, 4)\n const cards = clamp(cardsPerColumn, 3)\n return (\n <div ref={ref} {...statusProps(label)} {...props} className={cn('flex gap-ds-05 overflow-x-auto', className)}>\n <SrLabel label={label} />\n {Array.from({ length: c }).map((_, colIndex) => (\n <div key={`col-${colIndex}`} className=\"flex w-[272px] shrink-0 flex-col gap-ds-03\">\n {/* Column header */}\n <div className=\"flex items-center justify-between px-ds-02 py-ds-03\">\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className=\"h-ds-04 w-ds-04 rounded\" />\n <Skeleton className=\"h-ds-04 w-ds-11\" />\n <Skeleton className=\"h-ds-05 w-ds-05b rounded-pill\" />\n </div>\n <Skeleton className=\"h-ico-sm w-ico-sm rounded\" />\n </div>\n {/* Column cards */}\n {Array.from({ length: cards }).map((_, cardIndex) => (\n <div\n key={`card-${colIndex}-${cardIndex}`}\n className=\"rounded-surface border border-card bg-surface-raised p-ds-04\"\n >\n <div className=\"space-y-ds-03\">\n <Skeleton className=\"h-ds-04 w-4/5\" />\n <Skeleton className=\"h-ds-04 w-3/5\" />\n </div>\n <div className=\"flex items-center justify-between pt-ds-04\">\n <div className=\"flex items-center gap-ds-02b\">\n <Skeleton className=\"h-ico-md w-ico-md rounded-pill\" />\n <Skeleton className=\"h-ds-03 w-ds-10\" />\n </div>\n <Skeleton className=\"h-ds-05 w-ds-lg rounded-pill\" />\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\n )\n },\n)\nBoardSkeleton.displayName = 'BoardSkeleton'\n\nexport interface ListSkeletonProps extends CardSkeletonProps {\n rows?: number\n showAvatar?: boolean\n}\n\nconst ListSkeleton = React.forwardRef<HTMLDivElement, ListSkeletonProps>(\n function ListSkeleton({ rows = 6, showAvatar = true, className, label, ...props }, ref) {\n const r = clamp(rows, 6)\n return (\n <div ref={ref} {...statusProps(label)} {...props} className={cn('flex flex-col', className)}>\n <SrLabel label={label} />\n {Array.from({ length: r }).map((_, i) => (\n <div\n key={`list-${i}`}\n className={cn(\n 'flex items-center gap-ds-04 py-ds-04',\n i < r - 1 && 'border-b border-surface-border-strong',\n )}\n >\n {showAvatar && <Skeleton className=\"h-ds-sm w-ds-sm shrink-0 rounded-pill\" />}\n <div className=\"flex flex-1 flex-col gap-ds-02b\">\n <Skeleton className=\"h-ds-04 w-2/5\" />\n <Skeleton className=\"h-ds-03 w-3/5\" />\n </div>\n <Skeleton className=\"h-ds-05b w-ds-09 rounded-pill\" />\n </div>\n ))}\n </div>\n )\n },\n)\nListSkeleton.displayName = 'ListSkeleton'\n\nexport { BoardSkeleton, CardSkeleton, ListSkeleton, TableSkeleton }\n"],"mappings":";;;;;AAOA,IAAM,KAAS,GAAuB,MACpC,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,KAAM,YAAY,CAAC,OAAO,MAAM,CAAC,IAAI,IAAI,CAAQ,CAAC;AAIlF,SAAS,EAAY,GAAgB;CACnC,OAAO;EAAE,MAAM;EAAmB,aAAa;EAAM,cAAc,KAAS;CAAU;AACxF;AACA,SAAS,EAAQ,EAAE,YAA6B;CAC9C,OAAO,kBAAC,QAAD;EAAM,WAAU;YAAhB,CAA2B,KAAS,WAAU,GAAO;;AAC9D;AAQA,IAAM,IAAe,EAAM,WACzB,SAAsB,EAAE,cAAW,UAAO,GAAG,KAAS,GAAK;CACzD,OACE,kBAAC,OAAD;EACO;EACL,GAAI,EAAY,CAAK;EACrB,GAAI;EACJ,WAAW,EAAG,iEAAiE,CAAS;YAJ1F;GAME,kBAAC,GAAD,EAAgB,SAAQ,CAAA;GACxB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAU,WAAU,kBAAmB,CAAA,GACvC,kBAAC,GAAD,EAAU,WAAU,4BAA6B,CAAA,CAC9C;;GACL,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAU,WAAU,iBAAkB,CAAA;KACtC,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA;KACrC,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA;IAClC;;GACL,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAU,WAAU,+BAAgC,CAAA,GACpD,kBAAC,GAAD,EAAU,WAAU,kBAAmB,CAAA,CACpC;;EACF;;AAET,CACF;AACA,EAAa,cAAc;AAO3B,IAAM,IAAgB,EAAM,WAC1B,SAAuB,EAAE,UAAO,GAAG,aAAU,GAAG,cAAW,UAAO,GAAG,KAAS,GAAK;CACjF,IAAM,IAAI,EAAM,GAAM,CAAC,GACjB,IAAI,KAAK,IAAI,GAAG,EAAM,GAAS,CAAC,CAAC;CACvC,OACE,kBAAC,OAAD;EACO;EACL,GAAI,EAAY,CAAK;EACrB,GAAI;EACJ,WAAW,EAAG,sDAAsD,CAAS;YAJ/E;GAME,kBAAC,GAAD,EAAgB,SAAQ,CAAA;GAExB,kBAAC,OAAD;IAAK,WAAU;cACZ,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,GAAD,EAA4B,WAAW,EAAG,WAAW,MAAM,IAAI,YAAY,QAAQ,EAAI,GAAxE,QAAQ,GAAgE,CACxF;GACE,CAAA;GAEJ,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD;IAEE,WAAW,EACT,iDACA,IAAW,IAAI,KAAK,uCACtB;cAEC,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,GAAD,EAEE,WAAW,EAAG,WAAW,MAAa,IAAI,YAAY,QAAQ,EAC/D,GAFM,QAAQ,EAAS,GAAG,GAE1B,CACF;GACE,GAZE,OAAO,GAYT,CACN;EACE;;AAET,CACF;AACA,EAAc,cAAc;AAO5B,IAAM,IAAgB,EAAM,WAC1B,SAAuB,EAAE,aAAU,GAAG,oBAAiB,GAAG,cAAW,UAAO,GAAG,KAAS,GAAK;CAC3F,IAAM,IAAI,EAAM,GAAS,CAAC,GACpB,IAAQ,EAAM,GAAgB,CAAC;CACrC,OACE,kBAAC,OAAD;EAAU;EAAK,GAAI,EAAY,CAAK;EAAG,GAAI;EAAO,WAAW,EAAG,kCAAkC,CAAS;YAA3G,CACE,kBAAC,GAAD,EAAgB,SAAQ,CAAA,GACvB,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD;GAA6B,WAAU;aAAvC,CAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD,EAAU,WAAU,0BAA2B,CAAA;MAC/C,kBAAC,GAAD,EAAU,WAAU,kBAAmB,CAAA;MACvC,kBAAC,GAAD,EAAU,WAAU,gCAAiC,CAAA;KAClD;QACL,kBAAC,GAAD,EAAU,WAAU,4BAA6B,CAAA,CAC9C;OAEJ,MAAM,KAAK,EAAE,QAAQ,EAAM,CAAC,CAAC,CAAC,KAAK,GAAG,MACrC,kBAAC,OAAD;IAEE,WAAU;cAFZ,CAIE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA,GACrC,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA,CAClC;QACL,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAU,WAAU,iCAAkC,CAAA,GACtD,kBAAC,GAAD,EAAU,WAAU,kBAAmB,CAAA,CACpC;SACL,kBAAC,GAAD,EAAU,WAAU,+BAAgC,CAAA,CACjD;MACF;MAdE,QAAQ,EAAS,GAAG,GActB,CACN,CACE;KA7BK,OAAO,GA6BZ,CACN,CACE;;AAET,CACF;AACA,EAAc,cAAc;AAO5B,IAAM,IAAe,EAAM,WACzB,SAAsB,EAAE,UAAO,GAAG,gBAAa,IAAM,cAAW,UAAO,GAAG,KAAS,GAAK;CACtF,IAAM,IAAI,EAAM,GAAM,CAAC;CACvB,OACE,kBAAC,OAAD;EAAU;EAAK,GAAI,EAAY,CAAK;EAAG,GAAI;EAAO,WAAW,EAAG,iBAAiB,CAAS;YAA1F,CACE,kBAAC,GAAD,EAAgB,SAAQ,CAAA,GACvB,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD;GAEE,WAAW,EACT,wCACA,IAAI,IAAI,KAAK,uCACf;aALF;IAOG,KAAc,kBAAC,GAAD,EAAU,WAAU,wCAAyC,CAAA;IAC5E,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA,GACrC,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA,CAClC;;IACL,kBAAC,GAAD,EAAU,WAAU,gCAAiC,CAAA;GAClD;KAZE,QAAQ,GAYV,CACN,CACE;;AAET,CACF;AACA,EAAa,cAAc"}
@@ -1,13 +1,23 @@
1
1
  "use client";
2
2
  import * as React from 'react';
3
3
  /**
4
- * A responsive master-detail layout. On desktop, shows a fixed-width list panel
5
- * alongside a detail panel. Below the breakpoint, switches to a stacked view
6
- * with animated transitions and a back button.
4
+ * A responsive master-detail layout. Desktop: fixed-width list panel + detail
5
+ * panel. Below the breakpoint: stacked view with a back button. The list is an
6
+ * ARIA `listbox` with roving keyboard nav (Arrow/Home/End + Enter/Space).
7
+ *
8
+ * Selection can be **controlled** (`selected`) or **owned** by the component
9
+ * (`defaultSelected` + `onSelect`, deriving each row's active state from its
10
+ * `value` — no hand-wiring `active` + `onClick` per row).
7
11
  */
8
- export interface MasterDetailProps extends React.HTMLAttributes<HTMLDivElement> {
9
- /** ID of currently selected item. null = no selection (show list on mobile). */
12
+ export interface MasterDetailProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {
13
+ /** Controlled selected item id. `null` = no selection. Omit for uncontrolled. */
10
14
  selected?: string | null;
15
+ /** Uncontrolled initial selection. */
16
+ defaultSelected?: string | null;
17
+ /** Called with a row's `value` when it's chosen (click or Enter/Space). */
18
+ onSelect?: (value: string) => void;
19
+ /** Accessible name for the list (the `listbox`). @default 'Items' */
20
+ label?: string;
11
21
  /** Called when mobile back button is pressed. */
12
22
  onBack?: () => void;
13
23
  /** Master panel width on desktop. @default '280px' */
@@ -16,7 +26,7 @@ export interface MasterDetailProps extends React.HTMLAttributes<HTMLDivElement>
16
26
  breakpoint?: 'sm' | 'md' | 'lg';
17
27
  /** Content to show in the detail pane when nothing is selected. */
18
28
  emptyState?: React.ReactNode;
19
- /** Called when user presses ArrowUp/ArrowDown while the list has focus. */
29
+ /** Called when the user presses ArrowUp/ArrowDown while the list has focus. */
20
30
  onNavigate?: (direction: 'up' | 'down') => void;
21
31
  }
22
32
  interface MasterDetailListProps extends React.HTMLAttributes<HTMLDivElement> {
@@ -24,11 +34,14 @@ interface MasterDetailListProps extends React.HTMLAttributes<HTMLDivElement> {
24
34
  interface MasterDetailDetailProps extends React.HTMLAttributes<HTMLDivElement> {
25
35
  }
26
36
  interface MasterDetailListItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
37
+ /** Explicit active state. Omit to derive from `value` === the selected id. */
27
38
  active?: boolean;
39
+ /** Row id — enables derived selection + auto-fires `onSelect` on activate. */
40
+ value?: string;
28
41
  }
29
- declare function MasterDetailList({ children, className, ...props }: MasterDetailListProps): React.JSX.Element | null;
42
+ declare function MasterDetailList({ children, className, 'aria-label': ariaLabel, ...props }: MasterDetailListProps): React.JSX.Element | null;
30
43
  declare function MasterDetailDetail({ children, className, ...props }: MasterDetailDetailProps): React.JSX.Element | null;
31
- declare function MasterDetailRoot({ selected, onBack, masterWidth, breakpoint, emptyState, onNavigate, children, className, style, ...props }: MasterDetailProps): React.JSX.Element;
44
+ declare function MasterDetailRoot({ selected, defaultSelected, onSelect, label, onBack, masterWidth, breakpoint, emptyState, onNavigate, children, className, style, ...props }: MasterDetailProps): React.JSX.Element;
32
45
  declare const MasterDetail: typeof MasterDetailRoot & {
33
46
  List: typeof MasterDetailList;
34
47
  Detail: typeof MasterDetailDetail;
@@ -1 +1 @@
1
- {"version":3,"file":"master-detail.d.ts","sourceRoot":"","sources":["../../src/composed/master-detail.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAW9B;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC7E,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IAC/B,mEAAmE;IACnE,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAA;CAChD;AAED,UAAU,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;CAAG;AAE/E,UAAU,uBAAwB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;CAAG;AAEjF,UAAU,yBAA0B,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACvF,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AA0DD,iBAAS,gBAAgB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,4BAgFjF;AAED,iBAAS,kBAAkB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,uBAAuB,4BA4BrF;AAwCD,iBAAS,gBAAgB,CAAC,EACxB,QAAe,EACf,MAAM,EACN,WAAqB,EACrB,UAAiB,EACjB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,iBAAiB,qBA4BnB;AAED,QAAA,MAAM,YAAY;;;;CAIhB,CAAA;AAEF,OAAO,EAAE,YAAY,EAAE,CAAA;AACvB,YAAY,EAAE,yBAAyB,EAAE,CAAA"}
1
+ {"version":3,"file":"master-detail.d.ts","sourceRoot":"","sources":["../../src/composed/master-detail.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAEf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC9D,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,sCAAsC;IACtC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IAC/B,mEAAmE;IACnE,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAA;CAChD;AAED,UAAU,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;CAAG;AAC/E,UAAU,uBAAwB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;CAAG;AACjF,UAAU,yBAA0B,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACvF,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AA6CD,iBAAS,gBAAgB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,4BA2D1G;AAED,iBAAS,kBAAkB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,uBAAuB,4BA4BrF;AA4CD,iBAAS,gBAAgB,CAAC,EACxB,QAAQ,EACR,eAAsB,EACtB,QAAQ,EACR,KAAe,EACf,MAAM,EACN,WAAqB,EACrB,UAAiB,EACjB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,iBAAiB,qBAmCnB;AAED,QAAA,MAAM,YAAY;;;;CAIhB,CAAA;AAEF,OAAO,EAAE,YAAY,EAAE,CAAA;AACvB,YAAY,EAAE,yBAAyB,EAAE,CAAA"}
@@ -6,14 +6,14 @@ import { Button as r } from "../ui/button.js";
6
6
  import * as i from "react";
7
7
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
8
8
  import { IconArrowLeft as s } from "@tabler/icons-react";
9
- import { AnimatePresence as c, motion as l } from "framer-motion";
9
+ import { AnimatePresence as c, motion as l, useReducedMotion as u } from "framer-motion";
10
10
  //#region src/composed/master-detail.tsx
11
- var u = {
11
+ var d = {
12
12
  sm: "640px",
13
13
  md: "768px",
14
14
  lg: "1024px"
15
15
  };
16
- function d(e) {
16
+ function f(e) {
17
17
  let [t, n] = i.useState(!1);
18
18
  return i.useEffect(() => {
19
19
  if (typeof window > "u") return;
@@ -23,77 +23,84 @@ function d(e) {
23
23
  return t.addEventListener("change", r), () => t.removeEventListener("change", r);
24
24
  }, [e]), t;
25
25
  }
26
- var f = i.createContext({
26
+ var p = i.createContext({
27
27
  selected: null,
28
+ label: "Items",
28
29
  isMobile: !1,
29
30
  activeIndex: 0,
30
31
  setActiveIndex: () => {},
31
- registerItemRef: () => {},
32
- itemCount: 0,
33
- setItemCount: () => {}
32
+ registerItemRef: () => {}
34
33
  });
35
- function p({ children: e, className: n, ...r }) {
36
- let { selected: o, isMobile: s, onNavigate: c, activeIndex: l, setActiveIndex: u, registerItemRef: d, setItemCount: p } = i.useContext(f), m = i.useRef([]), h = i.Children.count(e);
37
- i.useEffect(() => {
38
- p(h);
39
- }, [h, p]);
40
- let g = i.useMemo(() => {
34
+ function m(e, t) {
35
+ if (!i.isValidElement(e)) return !1;
36
+ let n = e.props;
37
+ return n.active ?? (n.value != null && n.value === t);
38
+ }
39
+ function h({ children: e, className: n, "aria-label": r, ...o }) {
40
+ let { selected: s, label: c, isMobile: l, onNavigate: u, activeIndex: d, setActiveIndex: f, registerItemRef: h } = i.useContext(p), g = i.useRef([]), _ = i.Children.count(e), v = i.useMemo(() => {
41
41
  let t = -1;
42
42
  return i.Children.forEach(e, (e, n) => {
43
- i.isValidElement(e) && e.props.active && (t = n);
43
+ m(e, s) && (t = n);
44
44
  }), t;
45
- }, [e]);
45
+ }, [e, s]);
46
46
  if (i.useEffect(() => {
47
- g >= 0 && u(g);
48
- }, [g, u]), s && o) return null;
49
- function _(e) {
47
+ v >= 0 && f(v);
48
+ }, [v, f]), l && s) return null;
49
+ function y(e) {
50
50
  if (e.key === "ArrowDown") {
51
51
  e.preventDefault();
52
- let t = Math.min(l + 1, h - 1);
53
- u(t), m.current[t]?.focus(), c?.("down");
52
+ let t = Math.min(d + 1, _ - 1);
53
+ f(t), g.current[t]?.focus(), u?.("down");
54
54
  } else if (e.key === "ArrowUp") {
55
55
  e.preventDefault();
56
- let t = Math.max(l - 1, 0);
57
- u(t), m.current[t]?.focus(), c?.("up");
58
- } else if (e.key === "Home") e.preventDefault(), u(0), m.current[0]?.focus();
56
+ let t = Math.max(d - 1, 0);
57
+ f(t), g.current[t]?.focus(), u?.("up");
58
+ } else if (e.key === "Home") e.preventDefault(), f(0), g.current[0]?.focus();
59
59
  else if (e.key === "End") {
60
60
  e.preventDefault();
61
- let t = h - 1;
62
- u(t), m.current[t]?.focus();
61
+ let t = _ - 1;
62
+ f(t), g.current[t]?.focus();
63
63
  }
64
64
  }
65
65
  return /* @__PURE__ */ a("div", {
66
66
  role: "listbox",
67
+ "aria-label": r ?? c,
67
68
  tabIndex: -1,
68
- className: t("overflow-y-auto focus-visible:outline-hidden", !s && "border-r border-surface-border", n),
69
- onKeyDown: _,
70
- ...r,
69
+ className: t("overflow-y-auto focus-visible:outline-hidden", !l && "border-e border-surface-border", n),
70
+ onKeyDown: y,
71
+ ...o,
71
72
  children: i.Children.map(e, (e, t) => i.isValidElement(e) ? i.cloneElement(e, {
72
73
  ref: (e) => {
73
- m.current[t] = e, d(t, e);
74
+ g.current[t] = e, h(t, e);
74
75
  },
75
- tabIndex: t === l ? 0 : -1
76
+ tabIndex: t === d ? 0 : -1
76
77
  }) : e)
77
78
  });
78
79
  }
79
- function m({ children: u, className: d, ...p }) {
80
- let { selected: m, isMobile: h, onBack: g, emptyState: _ } = i.useContext(f);
81
- return h && !m ? null : /* @__PURE__ */ o("div", {
82
- className: t("flex-1 overflow-y-auto", d),
83
- ...p,
84
- children: [h && g && /* @__PURE__ */ a("div", {
80
+ function g({ children: d, className: f, ...m }) {
81
+ let { selected: h, isMobile: g, onBack: _, emptyState: v } = i.useContext(p), y = u();
82
+ return g && !h ? null : /* @__PURE__ */ o("div", {
83
+ role: "region",
84
+ "aria-label": "Detail",
85
+ "aria-live": "polite",
86
+ className: t("flex-1 overflow-y-auto", f),
87
+ ...m,
88
+ children: [g && _ && /* @__PURE__ */ a("div", {
85
89
  className: "border-b border-surface-border px-ds-04 py-ds-03",
86
90
  children: /* @__PURE__ */ a(r, {
87
91
  variant: "ghost",
88
92
  size: "xs",
89
- onClick: g,
90
- startIcon: /* @__PURE__ */ a(n, { icon: s }),
93
+ onClick: _,
94
+ startIcon: /* @__PURE__ */ a(n, {
95
+ icon: s,
96
+ className: "rtl:-scale-x-100"
97
+ }),
91
98
  children: "Back"
92
99
  })
93
100
  }), /* @__PURE__ */ a(c, {
94
101
  mode: "wait",
95
102
  children: /* @__PURE__ */ a(l.div, {
96
- initial: h ? {
103
+ initial: g && !y ? {
97
104
  x: 20,
98
105
  opacity: 0
99
106
  } : !1,
@@ -101,64 +108,71 @@ function m({ children: u, className: d, ...p }) {
101
108
  x: 0,
102
109
  opacity: 1
103
110
  },
104
- exit: h ? {
111
+ exit: g && !y ? {
105
112
  x: -20,
106
113
  opacity: 0
107
114
  } : void 0,
108
- transition: e.snappy,
109
- children: m ? u : _ ?? u
110
- }, m ?? "empty")
115
+ transition: y ? { duration: 0 } : e.snappy,
116
+ children: h ? d : v ?? d
117
+ }, h ?? "empty")
111
118
  })]
112
119
  });
113
120
  }
114
- var h = i.forwardRef(function({ active: e = !1, children: n, className: r, onKeyDown: i, ...o }, s) {
115
- function c(e) {
116
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), e.target.click()), i?.(e);
121
+ var _ = i.forwardRef(function({ active: e, value: n, children: r, className: o, onKeyDown: s, onClick: c, ...l }, u) {
122
+ let { selected: d, onSelect: f } = i.useContext(p), m = e ?? (n != null && n === d);
123
+ function h(e) {
124
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), e.currentTarget.click()), s?.(e);
125
+ }
126
+ function g(e) {
127
+ n != null && f?.(n), c?.(e);
117
128
  }
118
129
  return /* @__PURE__ */ a("button", {
119
- ref: s,
130
+ ref: u,
120
131
  type: "button",
121
132
  role: "option",
122
- "aria-selected": e,
123
- "data-active": e || void 0,
124
- onKeyDown: c,
125
- className: t("flex w-full items-center px-ds-04 py-ds-03 text-left text-body-md font-sans text-surface-fg", "transition-colors duration-fast-01 ease-productive-standard", "hover:bg-surface-raised-hover", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-7 focus-visible:ring-inset", e && "bg-accent-2 text-accent-11 font-medium", r),
126
- ...o,
127
- children: n
133
+ "aria-selected": m,
134
+ "data-active": m || void 0,
135
+ onKeyDown: h,
136
+ onClick: g,
137
+ className: t("flex w-full items-center px-ds-04 py-ds-03 text-left text-body-md font-sans text-surface-fg", "transition-colors duration-fast-01 ease-productive-standard", "hover:bg-surface-raised-hover", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-7 focus-visible:ring-inset", m && "bg-accent-2 text-accent-11 font-medium", o),
138
+ ...l,
139
+ children: r
128
140
  });
129
141
  });
130
- function g({ selected: e = null, onBack: n, masterWidth: r = "280px", breakpoint: o = "md", emptyState: s, onNavigate: c, children: l, className: p, style: m, ...h }) {
131
- let g = d(`(max-width: ${u[o]})`), [_, v] = i.useState(0), [y, b] = i.useState(0), x = i.useRef([]), S = i.useCallback((e, t) => {
132
- x.current[e] = t;
142
+ function v({ selected: e, defaultSelected: n = null, onSelect: r, label: o = "Items", onBack: s, masterWidth: c = "280px", breakpoint: l = "md", emptyState: u, onNavigate: m, children: h, className: g, style: _, ...v }) {
143
+ let y = f(`(max-width: ${d[l]})`), [b, x] = i.useState(0), S = i.useRef([]), C = e !== void 0, [w, T] = i.useState(n), E = C ? e ?? null : w, D = i.useCallback((e) => {
144
+ C || T(e), r?.(e);
145
+ }, [C, r]), O = i.useCallback((e, t) => {
146
+ S.current[e] = t;
133
147
  }, []);
134
- return /* @__PURE__ */ a(f.Provider, {
148
+ return /* @__PURE__ */ a(p.Provider, {
135
149
  value: {
136
- selected: e,
137
- isMobile: g,
138
- onBack: n,
139
- emptyState: s,
140
- onNavigate: c,
141
- activeIndex: _,
142
- setActiveIndex: v,
143
- registerItemRef: S,
144
- itemCount: y,
145
- setItemCount: b
150
+ selected: E,
151
+ onSelect: D,
152
+ label: o,
153
+ isMobile: y,
154
+ onBack: s,
155
+ emptyState: u,
156
+ onNavigate: m,
157
+ activeIndex: b,
158
+ setActiveIndex: x,
159
+ registerItemRef: O
146
160
  },
147
161
  children: /* @__PURE__ */ a("div", {
148
- className: t("flex h-full", !g && "grid", p),
162
+ className: t("flex h-full", !y && "grid", g),
149
163
  style: {
150
- ...m,
151
- ...g ? {} : { gridTemplateColumns: `${r} 1fr` }
164
+ ..._,
165
+ ...y ? {} : { gridTemplateColumns: `${c} 1fr` }
152
166
  },
153
- ...h,
154
- children: l
167
+ ...v,
168
+ children: h
155
169
  })
156
170
  });
157
171
  }
158
- var _ = Object.assign(g, {
159
- List: p,
160
- Detail: m,
161
- ListItem: h
172
+ var y = Object.assign(v, {
173
+ List: h,
174
+ Detail: g,
175
+ ListItem: _
162
176
  });
163
177
  //#endregion
164
- export { _ as MasterDetail };
178
+ export { y as MasterDetail };