@diwauhris/ui 1.0.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 (272) hide show
  1. package/README.md +75 -0
  2. package/lib/assets/ui.css +154 -0
  3. package/lib/index.cjs +183 -0
  4. package/lib/index.mjs +65 -0
  5. package/lib/index10.cjs +33 -0
  6. package/lib/index10.cjs.map +1 -0
  7. package/lib/index10.mjs +33 -0
  8. package/lib/index10.mjs.map +1 -0
  9. package/lib/index11.cjs +16 -0
  10. package/lib/index11.cjs.map +1 -0
  11. package/lib/index11.mjs +16 -0
  12. package/lib/index11.mjs.map +1 -0
  13. package/lib/index12.cjs +16 -0
  14. package/lib/index12.cjs.map +1 -0
  15. package/lib/index12.mjs +15 -0
  16. package/lib/index12.mjs.map +1 -0
  17. package/lib/index13.cjs +57 -0
  18. package/lib/index13.cjs.map +1 -0
  19. package/lib/index13.mjs +57 -0
  20. package/lib/index13.mjs.map +1 -0
  21. package/lib/index14.cjs +10 -0
  22. package/lib/index14.cjs.map +1 -0
  23. package/lib/index14.mjs +10 -0
  24. package/lib/index14.mjs.map +1 -0
  25. package/lib/index15.cjs +30 -0
  26. package/lib/index15.cjs.map +1 -0
  27. package/lib/index15.mjs +30 -0
  28. package/lib/index15.mjs.map +1 -0
  29. package/lib/index16.cjs +28 -0
  30. package/lib/index16.cjs.map +1 -0
  31. package/lib/index16.mjs +26 -0
  32. package/lib/index16.mjs.map +1 -0
  33. package/lib/index17.cjs +43 -0
  34. package/lib/index17.cjs.map +1 -0
  35. package/lib/index17.mjs +43 -0
  36. package/lib/index17.mjs.map +1 -0
  37. package/lib/index18.cjs +59 -0
  38. package/lib/index18.cjs.map +1 -0
  39. package/lib/index18.mjs +59 -0
  40. package/lib/index18.mjs.map +1 -0
  41. package/lib/index19.cjs +67 -0
  42. package/lib/index19.cjs.map +1 -0
  43. package/lib/index19.mjs +67 -0
  44. package/lib/index19.mjs.map +1 -0
  45. package/lib/index2.cjs +33 -0
  46. package/lib/index2.mjs +13 -0
  47. package/lib/index20.cjs +79 -0
  48. package/lib/index20.cjs.map +1 -0
  49. package/lib/index20.mjs +79 -0
  50. package/lib/index20.mjs.map +1 -0
  51. package/lib/index21.cjs +105 -0
  52. package/lib/index21.cjs.map +1 -0
  53. package/lib/index21.mjs +104 -0
  54. package/lib/index21.mjs.map +1 -0
  55. package/lib/index22.cjs +50 -0
  56. package/lib/index22.cjs.map +1 -0
  57. package/lib/index22.mjs +50 -0
  58. package/lib/index22.mjs.map +1 -0
  59. package/lib/index23.cjs +143 -0
  60. package/lib/index23.cjs.map +1 -0
  61. package/lib/index23.mjs +143 -0
  62. package/lib/index23.mjs.map +1 -0
  63. package/lib/index25.cjs +177 -0
  64. package/lib/index25.cjs.map +1 -0
  65. package/lib/index25.mjs +175 -0
  66. package/lib/index25.mjs.map +1 -0
  67. package/lib/index26.cjs +108 -0
  68. package/lib/index26.cjs.map +1 -0
  69. package/lib/index26.mjs +108 -0
  70. package/lib/index26.mjs.map +1 -0
  71. package/lib/index27.cjs +120 -0
  72. package/lib/index27.cjs.map +1 -0
  73. package/lib/index27.mjs +120 -0
  74. package/lib/index27.mjs.map +1 -0
  75. package/lib/index28.cjs +54 -0
  76. package/lib/index28.cjs.map +1 -0
  77. package/lib/index28.mjs +54 -0
  78. package/lib/index28.mjs.map +1 -0
  79. package/lib/index29.cjs +100 -0
  80. package/lib/index29.cjs.map +1 -0
  81. package/lib/index29.mjs +100 -0
  82. package/lib/index29.mjs.map +1 -0
  83. package/lib/index3.cjs +38 -0
  84. package/lib/index3.cjs.map +1 -0
  85. package/lib/index3.mjs +38 -0
  86. package/lib/index3.mjs.map +1 -0
  87. package/lib/index30.cjs +27 -0
  88. package/lib/index30.cjs.map +1 -0
  89. package/lib/index30.mjs +27 -0
  90. package/lib/index30.mjs.map +1 -0
  91. package/lib/index31.cjs +72 -0
  92. package/lib/index31.cjs.map +1 -0
  93. package/lib/index31.mjs +72 -0
  94. package/lib/index31.mjs.map +1 -0
  95. package/lib/index32.cjs +19 -0
  96. package/lib/index32.cjs.map +1 -0
  97. package/lib/index32.mjs +19 -0
  98. package/lib/index32.mjs.map +1 -0
  99. package/lib/index33.cjs +25 -0
  100. package/lib/index33.cjs.map +1 -0
  101. package/lib/index33.mjs +25 -0
  102. package/lib/index33.mjs.map +1 -0
  103. package/lib/index34.cjs +55 -0
  104. package/lib/index34.cjs.map +1 -0
  105. package/lib/index34.mjs +51 -0
  106. package/lib/index34.mjs.map +1 -0
  107. package/lib/index35.cjs +25 -0
  108. package/lib/index35.cjs.map +1 -0
  109. package/lib/index35.mjs +25 -0
  110. package/lib/index35.mjs.map +1 -0
  111. package/lib/index36.cjs +54 -0
  112. package/lib/index36.cjs.map +1 -0
  113. package/lib/index36.mjs +49 -0
  114. package/lib/index36.mjs.map +1 -0
  115. package/lib/index37.cjs +130 -0
  116. package/lib/index37.cjs.map +1 -0
  117. package/lib/index37.mjs +128 -0
  118. package/lib/index37.mjs.map +1 -0
  119. package/lib/index38.cjs +106 -0
  120. package/lib/index38.cjs.map +1 -0
  121. package/lib/index38.mjs +102 -0
  122. package/lib/index38.mjs.map +1 -0
  123. package/lib/index39.cjs +137 -0
  124. package/lib/index39.cjs.map +1 -0
  125. package/lib/index39.mjs +137 -0
  126. package/lib/index39.mjs.map +1 -0
  127. package/lib/index4.cjs +24 -0
  128. package/lib/index4.cjs.map +1 -0
  129. package/lib/index4.mjs +24 -0
  130. package/lib/index4.mjs.map +1 -0
  131. package/lib/index40.cjs +130 -0
  132. package/lib/index40.cjs.map +1 -0
  133. package/lib/index40.mjs +126 -0
  134. package/lib/index40.mjs.map +1 -0
  135. package/lib/index41.cjs +60 -0
  136. package/lib/index41.cjs.map +1 -0
  137. package/lib/index41.mjs +58 -0
  138. package/lib/index41.mjs.map +1 -0
  139. package/lib/index42.cjs +105 -0
  140. package/lib/index42.cjs.map +1 -0
  141. package/lib/index42.mjs +105 -0
  142. package/lib/index42.mjs.map +1 -0
  143. package/lib/index43.cjs +47 -0
  144. package/lib/index43.cjs.map +1 -0
  145. package/lib/index43.mjs +42 -0
  146. package/lib/index43.mjs.map +1 -0
  147. package/lib/index44.cjs +40 -0
  148. package/lib/index44.cjs.map +1 -0
  149. package/lib/index44.mjs +35 -0
  150. package/lib/index44.mjs.map +1 -0
  151. package/lib/index45.cjs +91 -0
  152. package/lib/index45.cjs.map +1 -0
  153. package/lib/index45.mjs +91 -0
  154. package/lib/index45.mjs.map +1 -0
  155. package/lib/index46.cjs +180 -0
  156. package/lib/index46.cjs.map +1 -0
  157. package/lib/index46.mjs +180 -0
  158. package/lib/index46.mjs.map +1 -0
  159. package/lib/index47.cjs +61 -0
  160. package/lib/index47.cjs.map +1 -0
  161. package/lib/index47.mjs +61 -0
  162. package/lib/index47.mjs.map +1 -0
  163. package/lib/index48.cjs +165 -0
  164. package/lib/index48.cjs.map +1 -0
  165. package/lib/index48.mjs +161 -0
  166. package/lib/index48.mjs.map +1 -0
  167. package/lib/index49.cjs +83 -0
  168. package/lib/index49.cjs.map +1 -0
  169. package/lib/index49.mjs +83 -0
  170. package/lib/index49.mjs.map +1 -0
  171. package/lib/index5.cjs +39 -0
  172. package/lib/index5.cjs.map +1 -0
  173. package/lib/index5.mjs +39 -0
  174. package/lib/index5.mjs.map +1 -0
  175. package/lib/index50.cjs +100 -0
  176. package/lib/index50.cjs.map +1 -0
  177. package/lib/index50.mjs +100 -0
  178. package/lib/index50.mjs.map +1 -0
  179. package/lib/index51.cjs +116 -0
  180. package/lib/index51.cjs.map +1 -0
  181. package/lib/index51.mjs +113 -0
  182. package/lib/index51.mjs.map +1 -0
  183. package/lib/index52.cjs +93 -0
  184. package/lib/index52.cjs.map +1 -0
  185. package/lib/index52.mjs +93 -0
  186. package/lib/index52.mjs.map +1 -0
  187. package/lib/index53.cjs +120 -0
  188. package/lib/index53.cjs.map +1 -0
  189. package/lib/index53.mjs +120 -0
  190. package/lib/index53.mjs.map +1 -0
  191. package/lib/index54.cjs +53 -0
  192. package/lib/index54.cjs.map +1 -0
  193. package/lib/index54.mjs +50 -0
  194. package/lib/index54.mjs.map +1 -0
  195. package/lib/index55.cjs +130 -0
  196. package/lib/index55.cjs.map +1 -0
  197. package/lib/index55.mjs +127 -0
  198. package/lib/index55.mjs.map +1 -0
  199. package/lib/index56.cjs +36 -0
  200. package/lib/index56.cjs.map +1 -0
  201. package/lib/index56.mjs +35 -0
  202. package/lib/index56.mjs.map +1 -0
  203. package/lib/index57.cjs +47 -0
  204. package/lib/index57.cjs.map +1 -0
  205. package/lib/index57.mjs +47 -0
  206. package/lib/index57.mjs.map +1 -0
  207. package/lib/index58.cjs +97 -0
  208. package/lib/index58.cjs.map +1 -0
  209. package/lib/index58.mjs +97 -0
  210. package/lib/index58.mjs.map +1 -0
  211. package/lib/index59.cjs +120 -0
  212. package/lib/index59.cjs.map +1 -0
  213. package/lib/index59.mjs +116 -0
  214. package/lib/index59.mjs.map +1 -0
  215. package/lib/index6.cjs +29 -0
  216. package/lib/index6.cjs.map +1 -0
  217. package/lib/index6.mjs +29 -0
  218. package/lib/index6.mjs.map +1 -0
  219. package/lib/index60.cjs +34 -0
  220. package/lib/index60.cjs.map +1 -0
  221. package/lib/index60.mjs +34 -0
  222. package/lib/index60.mjs.map +1 -0
  223. package/lib/index61.cjs +62 -0
  224. package/lib/index61.cjs.map +1 -0
  225. package/lib/index61.mjs +62 -0
  226. package/lib/index61.mjs.map +1 -0
  227. package/lib/index62.cjs +213 -0
  228. package/lib/index62.cjs.map +1 -0
  229. package/lib/index62.mjs +213 -0
  230. package/lib/index62.mjs.map +1 -0
  231. package/lib/index63.cjs +42 -0
  232. package/lib/index63.cjs.map +1 -0
  233. package/lib/index63.mjs +42 -0
  234. package/lib/index63.mjs.map +1 -0
  235. package/lib/index64.cjs +86 -0
  236. package/lib/index64.cjs.map +1 -0
  237. package/lib/index64.mjs +86 -0
  238. package/lib/index64.mjs.map +1 -0
  239. package/lib/index65.cjs +156 -0
  240. package/lib/index65.cjs.map +1 -0
  241. package/lib/index65.mjs +156 -0
  242. package/lib/index65.mjs.map +1 -0
  243. package/lib/index66.cjs +107 -0
  244. package/lib/index66.cjs.map +1 -0
  245. package/lib/index66.mjs +106 -0
  246. package/lib/index66.mjs.map +1 -0
  247. package/lib/index67.cjs +52 -0
  248. package/lib/index67.cjs.map +1 -0
  249. package/lib/index67.mjs +52 -0
  250. package/lib/index67.mjs.map +1 -0
  251. package/lib/index68.cjs +125 -0
  252. package/lib/index68.cjs.map +1 -0
  253. package/lib/index68.mjs +115 -0
  254. package/lib/index68.mjs.map +1 -0
  255. package/lib/index69.cjs +34 -0
  256. package/lib/index69.cjs.map +1 -0
  257. package/lib/index69.mjs +29 -0
  258. package/lib/index69.mjs.map +1 -0
  259. package/lib/index7.cjs +17 -0
  260. package/lib/index7.cjs.map +1 -0
  261. package/lib/index7.mjs +17 -0
  262. package/lib/index7.mjs.map +1 -0
  263. package/lib/index8.cjs +86 -0
  264. package/lib/index8.cjs.map +1 -0
  265. package/lib/index8.mjs +86 -0
  266. package/lib/index8.mjs.map +1 -0
  267. package/lib/index9.cjs +29 -0
  268. package/lib/index9.cjs.map +1 -0
  269. package/lib/index9.mjs +29 -0
  270. package/lib/index9.mjs.map +1 -0
  271. package/lib/types/index.d.ts +1 -0
  272. package/package.json +68 -0
@@ -0,0 +1,86 @@
1
+ let react_jsx_runtime = require("react/jsx-runtime");
2
+ let lucide_react = require("lucide-react");
3
+ //#region src/ui-library/gallery/permission-matrix/PermissionMatrix.tsx
4
+ /**
5
+ * PermissionMatrix — Design System Component
6
+ *
7
+ * A grid showing which roles have which permissions, using checkboxes
8
+ * or check icons. Purely presentational. No RBAC logic.
9
+ *
10
+ * Based on the "Effective Permission Matrix" pattern in RoleDetailPage.tsx
11
+ * but domain-free.
12
+ *
13
+ * Accessibility:
14
+ * - <table> with <caption>
15
+ * - Column headers: role names
16
+ * - Row headers: permission names
17
+ * - Cell has aria-label: "Permission X for Role Y: granted/denied"
18
+ */
19
+ function PermissionMatrix({ roles, permissions, caption = "Permission matrix", className = "" }) {
20
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
21
+ className: `w-full overflow-x-auto rounded-xl border border-slate-200 ${className}`,
22
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
23
+ className: "w-full text-sm border-collapse",
24
+ children: [
25
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("caption", {
26
+ className: "sr-only",
27
+ children: caption
28
+ }),
29
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
30
+ className: "border-b border-slate-100 bg-slate-50",
31
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
32
+ scope: "col",
33
+ className: "px-5 py-3 text-left text-[11px] font-bold uppercase tracking-widest text-slate-500",
34
+ children: "Permission"
35
+ }), roles.map((role) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
36
+ scope: "col",
37
+ className: "px-4 py-3 text-center text-[11px] font-bold uppercase tracking-widest text-slate-500",
38
+ children: role
39
+ }, role))]
40
+ }) }),
41
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", {
42
+ className: "divide-y divide-slate-100 bg-white",
43
+ children: permissions.map((perm) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
44
+ className: "hover:bg-slate-50/60",
45
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
46
+ scope: "row",
47
+ className: "px-5 py-3 text-left text-xs font-semibold text-slate-700",
48
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
49
+ className: "flex items-center gap-2",
50
+ children: [perm.group && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
51
+ className: "text-[9px] font-bold uppercase tracking-wider text-slate-400 bg-slate-100 px-1.5 py-0.5 rounded",
52
+ children: perm.group
53
+ }), perm.label]
54
+ })
55
+ }), perm.cells.map((cell, ci) => {
56
+ const roleLabel = roles[ci] ?? "";
57
+ const cellLabel = `${perm.label} for ${roleLabel}: ${cell.granted ? "granted" : "denied"}${cell.inherited ? " (inherited)" : ""}`;
58
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
59
+ className: "px-4 py-3 text-center",
60
+ "aria-label": cellLabel,
61
+ children: cell.granted ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
62
+ className: `inline-flex items-center justify-center h-5 w-5 rounded-full mx-auto ${cell.inherited ? "bg-brand-blue/15 text-brand-blue/60" : "bg-brand-blue text-white"}`,
63
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, {
64
+ size: 11,
65
+ strokeWidth: 2.5,
66
+ "aria-hidden": "true"
67
+ })
68
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
69
+ className: "inline-flex items-center justify-center h-5 w-5 rounded-full mx-auto bg-slate-100 text-slate-300",
70
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Minus, {
71
+ size: 11,
72
+ "aria-hidden": "true"
73
+ })
74
+ })
75
+ }, ci);
76
+ })]
77
+ }, perm.label))
78
+ })
79
+ ]
80
+ })
81
+ });
82
+ }
83
+ //#endregion
84
+ exports.PermissionMatrix = PermissionMatrix;
85
+
86
+ //# sourceMappingURL=index64.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index64.cjs","names":[],"sources":["../src/ui-library/gallery/permission-matrix/PermissionMatrix.tsx"],"sourcesContent":["/**\n * PermissionMatrix — Design System Component\n *\n * A grid showing which roles have which permissions, using checkboxes\n * or check icons. Purely presentational. No RBAC logic.\n *\n * Based on the \"Effective Permission Matrix\" pattern in RoleDetailPage.tsx\n * but domain-free.\n *\n * Accessibility:\n * - <table> with <caption>\n * - Column headers: role names\n * - Row headers: permission names\n * - Cell has aria-label: \"Permission X for Role Y: granted/denied\"\n */\n\nimport { Check, Minus } from 'lucide-react';\n\nexport interface PermissionMatrixCell {\n granted: boolean;\n /** If true, the cell is read-only and visually subdued */\n inherited?: boolean;\n}\n\nexport interface PermissionMatrixProps {\n /** Column headers (roles) */\n roles: string[];\n /** Row definitions */\n permissions: Array<{\n label: string;\n group?: string;\n cells: PermissionMatrixCell[];\n }>;\n caption?: string;\n className?: string;\n}\n\nexport function PermissionMatrix({\n roles,\n permissions,\n caption = 'Permission matrix',\n className = '',\n}: PermissionMatrixProps) {\n return (\n <div className={`w-full overflow-x-auto rounded-xl border border-slate-200 ${className}`}>\n <table className=\"w-full text-sm border-collapse\">\n <caption className=\"sr-only\">{caption}</caption>\n <thead>\n <tr className=\"border-b border-slate-100 bg-slate-50\">\n <th scope=\"col\" className=\"px-5 py-3 text-left text-[11px] font-bold uppercase tracking-widest text-slate-500\">\n Permission\n </th>\n {roles.map((role) => (\n <th\n key={role}\n scope=\"col\"\n className=\"px-4 py-3 text-center text-[11px] font-bold uppercase tracking-widest text-slate-500\"\n >\n {role}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-slate-100 bg-white\">\n {permissions.map((perm) => (\n <tr key={perm.label} className=\"hover:bg-slate-50/60\">\n <th\n scope=\"row\"\n className=\"px-5 py-3 text-left text-xs font-semibold text-slate-700\"\n >\n <div className=\"flex items-center gap-2\">\n {perm.group && (\n <span className=\"text-[9px] font-bold uppercase tracking-wider text-slate-400 bg-slate-100 px-1.5 py-0.5 rounded\">\n {perm.group}\n </span>\n )}\n {perm.label}\n </div>\n </th>\n {perm.cells.map((cell, ci) => {\n const roleLabel = roles[ci] ?? '';\n const cellLabel = `${perm.label} for ${roleLabel}: ${cell.granted ? 'granted' : 'denied'}${cell.inherited ? ' (inherited)' : ''}`;\n return (\n <td\n key={ci}\n className=\"px-4 py-3 text-center\"\n aria-label={cellLabel}\n >\n {cell.granted ? (\n <span className={`inline-flex items-center justify-center h-5 w-5 rounded-full mx-auto ${cell.inherited ? 'bg-brand-blue/15 text-brand-blue/60' : 'bg-brand-blue text-white'}`}>\n <Check size={11} strokeWidth={2.5} aria-hidden=\"true\" />\n </span>\n ) : (\n <span className=\"inline-flex items-center justify-center h-5 w-5 rounded-full mx-auto bg-slate-100 text-slate-300\">\n <Minus size={11} aria-hidden=\"true\" />\n </span>\n )}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqCA,SAAgB,iBAAiB,EAC/B,OACA,aACA,UAAU,qBACV,YAAY,MACY;CACxB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAW,6DAA6D;EAC3E,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;GAAO,WAAU;GAAjB,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;KAAS,WAAU;KAAW,UAAA;IAAiB,CAAA;IAC/C,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;KAAI,WAAU;KAAd,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,OAAM;MAAM,WAAU;MAAqF,UAAA;KAE3G,CAAA,GACH,MAAM,KAAK,SACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAEE,OAAM;MACN,WAAU;MAET,UAAA;KACC,GALG,IAKH,CACL,CACC;IACC,CAAA,EAAA,CAAA;IACP,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;KAAO,WAAU;KACd,UAAA,YAAY,KAAK,SAChB,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;MAAqB,WAAU;MAA/B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;OACE,OAAM;OACN,WAAU;OAEV,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAU;QAAf,UAAA,CACG,KAAK,SACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAU;SACb,UAAA,KAAK;QACF,CAAA,GAEP,KAAK,KACH;;MACH,CAAA,GACH,KAAK,MAAM,KAAK,MAAM,OAAO;OAC5B,MAAM,YAAY,MAAM,OAAO;OAC/B,MAAM,YAAY,GAAG,KAAK,MAAM,OAAO,UAAU,IAAI,KAAK,UAAU,YAAY,WAAW,KAAK,YAAY,iBAAiB;OAC7H,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAEE,WAAU;QACV,cAAY;QAEX,UAAA,KAAK,UACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAW,wEAAwE,KAAK,YAAY,wCAAwC;SAChJ,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAA,OAAD;UAAO,MAAM;UAAI,aAAa;UAAK,eAAY;SAAQ,CAAA;QACnD,CAAA,IAEN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAU;SACd,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAA,OAAD;UAAO,MAAM;UAAI,eAAY;SAAQ,CAAA;QACjC,CAAA;OAEN,GAbG,EAaH;MAER,CAAC,CACC;KAnCK,GAAA,KAAK,KAmCV,CACL;IACI,CAAA;GACF;;CACJ,CAAA;AAET"}
@@ -0,0 +1,86 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Check, Minus } from "lucide-react";
3
+ //#region src/ui-library/gallery/permission-matrix/PermissionMatrix.tsx
4
+ /**
5
+ * PermissionMatrix — Design System Component
6
+ *
7
+ * A grid showing which roles have which permissions, using checkboxes
8
+ * or check icons. Purely presentational. No RBAC logic.
9
+ *
10
+ * Based on the "Effective Permission Matrix" pattern in RoleDetailPage.tsx
11
+ * but domain-free.
12
+ *
13
+ * Accessibility:
14
+ * - <table> with <caption>
15
+ * - Column headers: role names
16
+ * - Row headers: permission names
17
+ * - Cell has aria-label: "Permission X for Role Y: granted/denied"
18
+ */
19
+ function PermissionMatrix({ roles, permissions, caption = "Permission matrix", className = "" }) {
20
+ return /* @__PURE__ */ jsx("div", {
21
+ className: `w-full overflow-x-auto rounded-xl border border-slate-200 ${className}`,
22
+ children: /* @__PURE__ */ jsxs("table", {
23
+ className: "w-full text-sm border-collapse",
24
+ children: [
25
+ /* @__PURE__ */ jsx("caption", {
26
+ className: "sr-only",
27
+ children: caption
28
+ }),
29
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", {
30
+ className: "border-b border-slate-100 bg-slate-50",
31
+ children: [/* @__PURE__ */ jsx("th", {
32
+ scope: "col",
33
+ className: "px-5 py-3 text-left text-[11px] font-bold uppercase tracking-widest text-slate-500",
34
+ children: "Permission"
35
+ }), roles.map((role) => /* @__PURE__ */ jsx("th", {
36
+ scope: "col",
37
+ className: "px-4 py-3 text-center text-[11px] font-bold uppercase tracking-widest text-slate-500",
38
+ children: role
39
+ }, role))]
40
+ }) }),
41
+ /* @__PURE__ */ jsx("tbody", {
42
+ className: "divide-y divide-slate-100 bg-white",
43
+ children: permissions.map((perm) => /* @__PURE__ */ jsxs("tr", {
44
+ className: "hover:bg-slate-50/60",
45
+ children: [/* @__PURE__ */ jsx("th", {
46
+ scope: "row",
47
+ className: "px-5 py-3 text-left text-xs font-semibold text-slate-700",
48
+ children: /* @__PURE__ */ jsxs("div", {
49
+ className: "flex items-center gap-2",
50
+ children: [perm.group && /* @__PURE__ */ jsx("span", {
51
+ className: "text-[9px] font-bold uppercase tracking-wider text-slate-400 bg-slate-100 px-1.5 py-0.5 rounded",
52
+ children: perm.group
53
+ }), perm.label]
54
+ })
55
+ }), perm.cells.map((cell, ci) => {
56
+ const roleLabel = roles[ci] ?? "";
57
+ const cellLabel = `${perm.label} for ${roleLabel}: ${cell.granted ? "granted" : "denied"}${cell.inherited ? " (inherited)" : ""}`;
58
+ return /* @__PURE__ */ jsx("td", {
59
+ className: "px-4 py-3 text-center",
60
+ "aria-label": cellLabel,
61
+ children: cell.granted ? /* @__PURE__ */ jsx("span", {
62
+ className: `inline-flex items-center justify-center h-5 w-5 rounded-full mx-auto ${cell.inherited ? "bg-brand-blue/15 text-brand-blue/60" : "bg-brand-blue text-white"}`,
63
+ children: /* @__PURE__ */ jsx(Check, {
64
+ size: 11,
65
+ strokeWidth: 2.5,
66
+ "aria-hidden": "true"
67
+ })
68
+ }) : /* @__PURE__ */ jsx("span", {
69
+ className: "inline-flex items-center justify-center h-5 w-5 rounded-full mx-auto bg-slate-100 text-slate-300",
70
+ children: /* @__PURE__ */ jsx(Minus, {
71
+ size: 11,
72
+ "aria-hidden": "true"
73
+ })
74
+ })
75
+ }, ci);
76
+ })]
77
+ }, perm.label))
78
+ })
79
+ ]
80
+ })
81
+ });
82
+ }
83
+ //#endregion
84
+ export { PermissionMatrix };
85
+
86
+ //# sourceMappingURL=index64.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index64.mjs","names":[],"sources":["../src/ui-library/gallery/permission-matrix/PermissionMatrix.tsx"],"sourcesContent":["/**\n * PermissionMatrix — Design System Component\n *\n * A grid showing which roles have which permissions, using checkboxes\n * or check icons. Purely presentational. No RBAC logic.\n *\n * Based on the \"Effective Permission Matrix\" pattern in RoleDetailPage.tsx\n * but domain-free.\n *\n * Accessibility:\n * - <table> with <caption>\n * - Column headers: role names\n * - Row headers: permission names\n * - Cell has aria-label: \"Permission X for Role Y: granted/denied\"\n */\n\nimport { Check, Minus } from 'lucide-react';\n\nexport interface PermissionMatrixCell {\n granted: boolean;\n /** If true, the cell is read-only and visually subdued */\n inherited?: boolean;\n}\n\nexport interface PermissionMatrixProps {\n /** Column headers (roles) */\n roles: string[];\n /** Row definitions */\n permissions: Array<{\n label: string;\n group?: string;\n cells: PermissionMatrixCell[];\n }>;\n caption?: string;\n className?: string;\n}\n\nexport function PermissionMatrix({\n roles,\n permissions,\n caption = 'Permission matrix',\n className = '',\n}: PermissionMatrixProps) {\n return (\n <div className={`w-full overflow-x-auto rounded-xl border border-slate-200 ${className}`}>\n <table className=\"w-full text-sm border-collapse\">\n <caption className=\"sr-only\">{caption}</caption>\n <thead>\n <tr className=\"border-b border-slate-100 bg-slate-50\">\n <th scope=\"col\" className=\"px-5 py-3 text-left text-[11px] font-bold uppercase tracking-widest text-slate-500\">\n Permission\n </th>\n {roles.map((role) => (\n <th\n key={role}\n scope=\"col\"\n className=\"px-4 py-3 text-center text-[11px] font-bold uppercase tracking-widest text-slate-500\"\n >\n {role}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-slate-100 bg-white\">\n {permissions.map((perm) => (\n <tr key={perm.label} className=\"hover:bg-slate-50/60\">\n <th\n scope=\"row\"\n className=\"px-5 py-3 text-left text-xs font-semibold text-slate-700\"\n >\n <div className=\"flex items-center gap-2\">\n {perm.group && (\n <span className=\"text-[9px] font-bold uppercase tracking-wider text-slate-400 bg-slate-100 px-1.5 py-0.5 rounded\">\n {perm.group}\n </span>\n )}\n {perm.label}\n </div>\n </th>\n {perm.cells.map((cell, ci) => {\n const roleLabel = roles[ci] ?? '';\n const cellLabel = `${perm.label} for ${roleLabel}: ${cell.granted ? 'granted' : 'denied'}${cell.inherited ? ' (inherited)' : ''}`;\n return (\n <td\n key={ci}\n className=\"px-4 py-3 text-center\"\n aria-label={cellLabel}\n >\n {cell.granted ? (\n <span className={`inline-flex items-center justify-center h-5 w-5 rounded-full mx-auto ${cell.inherited ? 'bg-brand-blue/15 text-brand-blue/60' : 'bg-brand-blue text-white'}`}>\n <Check size={11} strokeWidth={2.5} aria-hidden=\"true\" />\n </span>\n ) : (\n <span className=\"inline-flex items-center justify-center h-5 w-5 rounded-full mx-auto bg-slate-100 text-slate-300\">\n <Minus size={11} aria-hidden=\"true\" />\n </span>\n )}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqCA,SAAgB,iBAAiB,EAC/B,OACA,aACA,UAAU,qBACV,YAAY,MACY;CACxB,OACE,oBAAC,OAAD;EAAK,WAAW,6DAA6D;EAC3E,UAAA,qBAAC,SAAD;GAAO,WAAU;GAAjB,UAAA;IACE,oBAAC,WAAD;KAAS,WAAU;KAAW,UAAA;IAAiB,CAAA;IAC/C,oBAAC,SAAD,EAAA,UACE,qBAAC,MAAD;KAAI,WAAU;KAAd,UAAA,CACE,oBAAC,MAAD;MAAI,OAAM;MAAM,WAAU;MAAqF,UAAA;KAE3G,CAAA,GACH,MAAM,KAAK,SACV,oBAAC,MAAD;MAEE,OAAM;MACN,WAAU;MAET,UAAA;KACC,GALG,IAKH,CACL,CACC;IACC,CAAA,EAAA,CAAA;IACP,oBAAC,SAAD;KAAO,WAAU;KACd,UAAA,YAAY,KAAK,SAChB,qBAAC,MAAD;MAAqB,WAAU;MAA/B,UAAA,CACE,oBAAC,MAAD;OACE,OAAM;OACN,WAAU;OAEV,UAAA,qBAAC,OAAD;QAAK,WAAU;QAAf,UAAA,CACG,KAAK,SACJ,oBAAC,QAAD;SAAM,WAAU;SACb,UAAA,KAAK;QACF,CAAA,GAEP,KAAK,KACH;;MACH,CAAA,GACH,KAAK,MAAM,KAAK,MAAM,OAAO;OAC5B,MAAM,YAAY,MAAM,OAAO;OAC/B,MAAM,YAAY,GAAG,KAAK,MAAM,OAAO,UAAU,IAAI,KAAK,UAAU,YAAY,WAAW,KAAK,YAAY,iBAAiB;OAC7H,OACE,oBAAC,MAAD;QAEE,WAAU;QACV,cAAY;QAEX,UAAA,KAAK,UACJ,oBAAC,QAAD;SAAM,WAAW,wEAAwE,KAAK,YAAY,wCAAwC;SAChJ,UAAA,oBAAC,OAAD;UAAO,MAAM;UAAI,aAAa;UAAK,eAAY;SAAQ,CAAA;QACnD,CAAA,IAEN,oBAAC,QAAD;SAAM,WAAU;SACd,UAAA,oBAAC,OAAD;UAAO,MAAM;UAAI,eAAY;SAAQ,CAAA;QACjC,CAAA;OAEN,GAbG,EAaH;MAER,CAAC,CACC;KAnCK,GAAA,KAAK,KAmCV,CACL;IACI,CAAA;GACF;;CACJ,CAAA;AAET"}
@@ -0,0 +1,156 @@
1
+ let react_jsx_runtime = require("react/jsx-runtime");
2
+ let react = require("react");
3
+ let lucide_react = require("lucide-react");
4
+ //#region src/ui-library/gallery/calendar/Calendar.tsx
5
+ /**
6
+ * Calendar — Design System Component
7
+ *
8
+ * A standalone month-view calendar grid for date selection and display.
9
+ * Controlled or uncontrolled. No time support.
10
+ *
11
+ * Accessibility:
12
+ * - role="grid" for the calendar table
13
+ * - role="gridcell" for each day cell
14
+ * - aria-label on each cell: "Day Month Year, [Today|Selected]"
15
+ * - aria-selected on selected day
16
+ * - aria-current="date" on today
17
+ * - Keyboard: ArrowKeys navigate days, Enter/Space select
18
+ * - Previous/Next month buttons have aria-label
19
+ */
20
+ var MONTHS = [
21
+ "January",
22
+ "February",
23
+ "March",
24
+ "April",
25
+ "May",
26
+ "June",
27
+ "July",
28
+ "August",
29
+ "September",
30
+ "October",
31
+ "November",
32
+ "December"
33
+ ];
34
+ var DAYS = [
35
+ "Su",
36
+ "Mo",
37
+ "Tu",
38
+ "We",
39
+ "Th",
40
+ "Fr",
41
+ "Sa"
42
+ ];
43
+ function isSameDay(a, b) {
44
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
45
+ }
46
+ function Calendar({ value, defaultValue, onChange, minDate, maxDate, className = "" }) {
47
+ const today = /* @__PURE__ */ new Date();
48
+ today.setHours(0, 0, 0, 0);
49
+ const [internal, setInternal] = (0, react.useState)(defaultValue ?? null);
50
+ const selected = value !== void 0 ? value : internal;
51
+ const [viewYear, setViewYear] = (0, react.useState)((selected ?? today).getFullYear());
52
+ const [viewMonth, setViewMonth] = (0, react.useState)((selected ?? today).getMonth());
53
+ const firstDay = new Date(viewYear, viewMonth, 1).getDay();
54
+ const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
55
+ const prevMonth = () => {
56
+ if (viewMonth === 0) {
57
+ setViewMonth(11);
58
+ setViewYear((y) => y - 1);
59
+ } else setViewMonth((m) => m - 1);
60
+ };
61
+ const nextMonth = () => {
62
+ if (viewMonth === 11) {
63
+ setViewMonth(0);
64
+ setViewYear((y) => y + 1);
65
+ } else setViewMonth((m) => m + 1);
66
+ };
67
+ const handleSelect = (day) => {
68
+ const date = new Date(viewYear, viewMonth, day);
69
+ if (minDate && date < minDate) return;
70
+ if (maxDate && date > maxDate) return;
71
+ if (!value) setInternal(date);
72
+ onChange?.(date);
73
+ };
74
+ const cells = [...Array(firstDay).fill(null), ...Array.from({ length: daysInMonth }, (_, i) => i + 1)];
75
+ while (cells.length % 7 !== 0) cells.push(null);
76
+ const weeks = [];
77
+ for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));
78
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
79
+ className: `inline-block select-none rounded-2xl border border-slate-200 bg-white p-4 shadow-sm ${className}`,
80
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
81
+ className: "mb-3 flex items-center justify-between",
82
+ children: [
83
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
84
+ type: "button",
85
+ onClick: prevMonth,
86
+ "aria-label": "Previous month",
87
+ className: "rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30",
88
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronLeft, {
89
+ size: 16,
90
+ "aria-hidden": "true"
91
+ })
92
+ }),
93
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
94
+ className: "text-sm font-bold text-slate-800",
95
+ children: [
96
+ MONTHS[viewMonth],
97
+ " ",
98
+ viewYear
99
+ ]
100
+ }),
101
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
102
+ type: "button",
103
+ onClick: nextMonth,
104
+ "aria-label": "Next month",
105
+ className: "rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30",
106
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRight, {
107
+ size: 16,
108
+ "aria-hidden": "true"
109
+ })
110
+ })
111
+ ]
112
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
113
+ role: "grid",
114
+ "aria-label": `${MONTHS[viewMonth]} ${viewYear}`,
115
+ className: "w-full border-collapse",
116
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: DAYS.map((d) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
117
+ scope: "col",
118
+ className: "pb-2 text-center text-[10px] font-bold uppercase tracking-widest text-slate-400",
119
+ children: d
120
+ }, d)) }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: weeks.map((week, wi) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: week.map((day, di) => {
121
+ if (!day) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
122
+ role: "gridcell",
123
+ "aria-label": "Empty"
124
+ }, di);
125
+ const date = new Date(viewYear, viewMonth, day);
126
+ const isToday = isSameDay(date, today);
127
+ const isSelected = !!selected && isSameDay(date, selected);
128
+ const isDisabled = (minDate ? date < minDate : false) || (maxDate ? date > maxDate : false);
129
+ const label = `${day} ${MONTHS[viewMonth]} ${viewYear}${isToday ? ", Today" : ""}${isSelected ? ", Selected" : ""}`;
130
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
131
+ role: "gridcell",
132
+ "aria-label": label,
133
+ "aria-selected": isSelected,
134
+ className: "p-0.5",
135
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
136
+ type: "button",
137
+ onClick: () => handleSelect(day),
138
+ disabled: isDisabled,
139
+ "aria-current": isToday ? "date" : void 0,
140
+ className: [
141
+ "flex h-8 w-8 items-center justify-center rounded-full text-sm font-semibold transition",
142
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30",
143
+ "disabled:cursor-not-allowed disabled:opacity-30",
144
+ isSelected ? "bg-brand-blue text-white shadow-md" : isToday ? "border border-brand-blue/60 text-brand-blue hover:bg-blue-50" : "text-slate-700 hover:bg-slate-100"
145
+ ].join(" "),
146
+ children: day
147
+ })
148
+ }, di);
149
+ }) }, wi)) })]
150
+ })]
151
+ });
152
+ }
153
+ //#endregion
154
+ exports.Calendar = Calendar;
155
+
156
+ //# sourceMappingURL=index65.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index65.cjs","names":[],"sources":["../src/ui-library/gallery/calendar/Calendar.tsx"],"sourcesContent":["/**\n * Calendar — Design System Component\n *\n * A standalone month-view calendar grid for date selection and display.\n * Controlled or uncontrolled. No time support.\n *\n * Accessibility:\n * - role=\"grid\" for the calendar table\n * - role=\"gridcell\" for each day cell\n * - aria-label on each cell: \"Day Month Year, [Today|Selected]\"\n * - aria-selected on selected day\n * - aria-current=\"date\" on today\n * - Keyboard: ArrowKeys navigate days, Enter/Space select\n * - Previous/Next month buttons have aria-label\n */\n\nimport { useState } from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\n\nexport interface CalendarProps {\n /** Selected date (controlled). */\n value?: Date | null;\n /** Default selected date (uncontrolled). */\n defaultValue?: Date | null;\n /** Called when a date is selected. */\n onChange?: (date: Date) => void;\n /** Minimum selectable date. */\n minDate?: Date;\n /** Maximum selectable date. */\n maxDate?: Date;\n /** Additional class on the root element. */\n className?: string;\n}\n\nconst MONTHS = [\n 'January','February','March','April','May','June',\n 'July','August','September','October','November','December',\n];\nconst DAYS = ['Su','Mo','Tu','We','Th','Fr','Sa'];\n\nfunction isSameDay(a: Date, b: Date) {\n return a.getFullYear() === b.getFullYear()\n && a.getMonth() === b.getMonth()\n && a.getDate() === b.getDate();\n}\n\nexport function Calendar({\n value,\n defaultValue,\n onChange,\n minDate,\n maxDate,\n className = '',\n}: CalendarProps) {\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n\n const [internal, setInternal] = useState<Date | null>(defaultValue ?? null);\n const selected = value !== undefined ? value : internal;\n\n const [viewYear, setViewYear] = useState(\n (selected ?? today).getFullYear(),\n );\n const [viewMonth, setViewMonth] = useState(\n (selected ?? today).getMonth(),\n );\n\n const firstDay = new Date(viewYear, viewMonth, 1).getDay();\n const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();\n\n const prevMonth = () => {\n if (viewMonth === 0) { setViewMonth(11); setViewYear(y => y - 1); }\n else setViewMonth(m => m - 1);\n };\n const nextMonth = () => {\n if (viewMonth === 11) { setViewMonth(0); setViewYear(y => y + 1); }\n else setViewMonth(m => m + 1);\n };\n\n const handleSelect = (day: number) => {\n const date = new Date(viewYear, viewMonth, day);\n if (minDate && date < minDate) return;\n if (maxDate && date > maxDate) return;\n if (!value) setInternal(date);\n onChange?.(date);\n };\n\n // Build calendar grid\n const cells: Array<number | null> = [\n ...Array(firstDay).fill(null),\n ...Array.from({ length: daysInMonth }, (_, i) => i + 1),\n ];\n // Pad to complete last row\n while (cells.length % 7 !== 0) cells.push(null);\n const weeks = [];\n for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));\n\n return (\n <div className={`inline-block select-none rounded-2xl border border-slate-200 bg-white p-4 shadow-sm ${className}`}>\n {/* Header */}\n <div className=\"mb-3 flex items-center justify-between\">\n <button\n type=\"button\"\n onClick={prevMonth}\n aria-label=\"Previous month\"\n className=\"rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30\"\n >\n <ChevronLeft size={16} aria-hidden=\"true\" />\n </button>\n <span className=\"text-sm font-bold text-slate-800\">\n {MONTHS[viewMonth]} {viewYear}\n </span>\n <button\n type=\"button\"\n onClick={nextMonth}\n aria-label=\"Next month\"\n className=\"rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30\"\n >\n <ChevronRight size={16} aria-hidden=\"true\" />\n </button>\n </div>\n\n {/* Grid */}\n <table\n role=\"grid\"\n aria-label={`${MONTHS[viewMonth]} ${viewYear}`}\n className=\"w-full border-collapse\"\n >\n <thead>\n <tr>\n {DAYS.map((d) => (\n <th key={d} scope=\"col\" className=\"pb-2 text-center text-[10px] font-bold uppercase tracking-widest text-slate-400\">\n {d}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {weeks.map((week, wi) => (\n <tr key={wi}>\n {week.map((day, di) => {\n if (!day) return <td key={di} role=\"gridcell\" aria-label=\"Empty\" />;\n const date = new Date(viewYear, viewMonth, day);\n const isToday = isSameDay(date, today);\n const isSelected = !!selected && isSameDay(date, selected);\n const isDisabled = (minDate ? date < minDate : false) || (maxDate ? date > maxDate : false);\n const label = `${day} ${MONTHS[viewMonth]} ${viewYear}${isToday ? ', Today' : ''}${isSelected ? ', Selected' : ''}`;\n\n return (\n <td key={di} role=\"gridcell\" aria-label={label} aria-selected={isSelected} className=\"p-0.5\">\n <button\n type=\"button\"\n onClick={() => handleSelect(day)}\n disabled={isDisabled}\n aria-current={isToday ? 'date' : undefined}\n className={[\n 'flex h-8 w-8 items-center justify-center rounded-full text-sm font-semibold transition',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30',\n 'disabled:cursor-not-allowed disabled:opacity-30',\n isSelected\n ? 'bg-brand-blue text-white shadow-md'\n : isToday\n ? 'border border-brand-blue/60 text-brand-blue hover:bg-blue-50'\n : 'text-slate-700 hover:bg-slate-100',\n ].join(' ')}\n >\n {day}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { ChevronLeft, ChevronRight } from "lucide-react";
4
+ //#region src/ui-library/gallery/calendar/Calendar.tsx
5
+ /**
6
+ * Calendar — Design System Component
7
+ *
8
+ * A standalone month-view calendar grid for date selection and display.
9
+ * Controlled or uncontrolled. No time support.
10
+ *
11
+ * Accessibility:
12
+ * - role="grid" for the calendar table
13
+ * - role="gridcell" for each day cell
14
+ * - aria-label on each cell: "Day Month Year, [Today|Selected]"
15
+ * - aria-selected on selected day
16
+ * - aria-current="date" on today
17
+ * - Keyboard: ArrowKeys navigate days, Enter/Space select
18
+ * - Previous/Next month buttons have aria-label
19
+ */
20
+ var MONTHS = [
21
+ "January",
22
+ "February",
23
+ "March",
24
+ "April",
25
+ "May",
26
+ "June",
27
+ "July",
28
+ "August",
29
+ "September",
30
+ "October",
31
+ "November",
32
+ "December"
33
+ ];
34
+ var DAYS = [
35
+ "Su",
36
+ "Mo",
37
+ "Tu",
38
+ "We",
39
+ "Th",
40
+ "Fr",
41
+ "Sa"
42
+ ];
43
+ function isSameDay(a, b) {
44
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
45
+ }
46
+ function Calendar({ value, defaultValue, onChange, minDate, maxDate, className = "" }) {
47
+ const today = /* @__PURE__ */ new Date();
48
+ today.setHours(0, 0, 0, 0);
49
+ const [internal, setInternal] = useState(defaultValue ?? null);
50
+ const selected = value !== void 0 ? value : internal;
51
+ const [viewYear, setViewYear] = useState((selected ?? today).getFullYear());
52
+ const [viewMonth, setViewMonth] = useState((selected ?? today).getMonth());
53
+ const firstDay = new Date(viewYear, viewMonth, 1).getDay();
54
+ const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
55
+ const prevMonth = () => {
56
+ if (viewMonth === 0) {
57
+ setViewMonth(11);
58
+ setViewYear((y) => y - 1);
59
+ } else setViewMonth((m) => m - 1);
60
+ };
61
+ const nextMonth = () => {
62
+ if (viewMonth === 11) {
63
+ setViewMonth(0);
64
+ setViewYear((y) => y + 1);
65
+ } else setViewMonth((m) => m + 1);
66
+ };
67
+ const handleSelect = (day) => {
68
+ const date = new Date(viewYear, viewMonth, day);
69
+ if (minDate && date < minDate) return;
70
+ if (maxDate && date > maxDate) return;
71
+ if (!value) setInternal(date);
72
+ onChange?.(date);
73
+ };
74
+ const cells = [...Array(firstDay).fill(null), ...Array.from({ length: daysInMonth }, (_, i) => i + 1)];
75
+ while (cells.length % 7 !== 0) cells.push(null);
76
+ const weeks = [];
77
+ for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));
78
+ return /* @__PURE__ */ jsxs("div", {
79
+ className: `inline-block select-none rounded-2xl border border-slate-200 bg-white p-4 shadow-sm ${className}`,
80
+ children: [/* @__PURE__ */ jsxs("div", {
81
+ className: "mb-3 flex items-center justify-between",
82
+ children: [
83
+ /* @__PURE__ */ jsx("button", {
84
+ type: "button",
85
+ onClick: prevMonth,
86
+ "aria-label": "Previous month",
87
+ className: "rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30",
88
+ children: /* @__PURE__ */ jsx(ChevronLeft, {
89
+ size: 16,
90
+ "aria-hidden": "true"
91
+ })
92
+ }),
93
+ /* @__PURE__ */ jsxs("span", {
94
+ className: "text-sm font-bold text-slate-800",
95
+ children: [
96
+ MONTHS[viewMonth],
97
+ " ",
98
+ viewYear
99
+ ]
100
+ }),
101
+ /* @__PURE__ */ jsx("button", {
102
+ type: "button",
103
+ onClick: nextMonth,
104
+ "aria-label": "Next month",
105
+ className: "rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30",
106
+ children: /* @__PURE__ */ jsx(ChevronRight, {
107
+ size: 16,
108
+ "aria-hidden": "true"
109
+ })
110
+ })
111
+ ]
112
+ }), /* @__PURE__ */ jsxs("table", {
113
+ role: "grid",
114
+ "aria-label": `${MONTHS[viewMonth]} ${viewYear}`,
115
+ className: "w-full border-collapse",
116
+ children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: DAYS.map((d) => /* @__PURE__ */ jsx("th", {
117
+ scope: "col",
118
+ className: "pb-2 text-center text-[10px] font-bold uppercase tracking-widest text-slate-400",
119
+ children: d
120
+ }, d)) }) }), /* @__PURE__ */ jsx("tbody", { children: weeks.map((week, wi) => /* @__PURE__ */ jsx("tr", { children: week.map((day, di) => {
121
+ if (!day) return /* @__PURE__ */ jsx("td", {
122
+ role: "gridcell",
123
+ "aria-label": "Empty"
124
+ }, di);
125
+ const date = new Date(viewYear, viewMonth, day);
126
+ const isToday = isSameDay(date, today);
127
+ const isSelected = !!selected && isSameDay(date, selected);
128
+ const isDisabled = (minDate ? date < minDate : false) || (maxDate ? date > maxDate : false);
129
+ const label = `${day} ${MONTHS[viewMonth]} ${viewYear}${isToday ? ", Today" : ""}${isSelected ? ", Selected" : ""}`;
130
+ return /* @__PURE__ */ jsx("td", {
131
+ role: "gridcell",
132
+ "aria-label": label,
133
+ "aria-selected": isSelected,
134
+ className: "p-0.5",
135
+ children: /* @__PURE__ */ jsx("button", {
136
+ type: "button",
137
+ onClick: () => handleSelect(day),
138
+ disabled: isDisabled,
139
+ "aria-current": isToday ? "date" : void 0,
140
+ className: [
141
+ "flex h-8 w-8 items-center justify-center rounded-full text-sm font-semibold transition",
142
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30",
143
+ "disabled:cursor-not-allowed disabled:opacity-30",
144
+ isSelected ? "bg-brand-blue text-white shadow-md" : isToday ? "border border-brand-blue/60 text-brand-blue hover:bg-blue-50" : "text-slate-700 hover:bg-slate-100"
145
+ ].join(" "),
146
+ children: day
147
+ })
148
+ }, di);
149
+ }) }, wi)) })]
150
+ })]
151
+ });
152
+ }
153
+ //#endregion
154
+ export { Calendar };
155
+
156
+ //# sourceMappingURL=index65.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index65.mjs","names":[],"sources":["../src/ui-library/gallery/calendar/Calendar.tsx"],"sourcesContent":["/**\n * Calendar — Design System Component\n *\n * A standalone month-view calendar grid for date selection and display.\n * Controlled or uncontrolled. No time support.\n *\n * Accessibility:\n * - role=\"grid\" for the calendar table\n * - role=\"gridcell\" for each day cell\n * - aria-label on each cell: \"Day Month Year, [Today|Selected]\"\n * - aria-selected on selected day\n * - aria-current=\"date\" on today\n * - Keyboard: ArrowKeys navigate days, Enter/Space select\n * - Previous/Next month buttons have aria-label\n */\n\nimport { useState } from 'react';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\n\nexport interface CalendarProps {\n /** Selected date (controlled). */\n value?: Date | null;\n /** Default selected date (uncontrolled). */\n defaultValue?: Date | null;\n /** Called when a date is selected. */\n onChange?: (date: Date) => void;\n /** Minimum selectable date. */\n minDate?: Date;\n /** Maximum selectable date. */\n maxDate?: Date;\n /** Additional class on the root element. */\n className?: string;\n}\n\nconst MONTHS = [\n 'January','February','March','April','May','June',\n 'July','August','September','October','November','December',\n];\nconst DAYS = ['Su','Mo','Tu','We','Th','Fr','Sa'];\n\nfunction isSameDay(a: Date, b: Date) {\n return a.getFullYear() === b.getFullYear()\n && a.getMonth() === b.getMonth()\n && a.getDate() === b.getDate();\n}\n\nexport function Calendar({\n value,\n defaultValue,\n onChange,\n minDate,\n maxDate,\n className = '',\n}: CalendarProps) {\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n\n const [internal, setInternal] = useState<Date | null>(defaultValue ?? null);\n const selected = value !== undefined ? value : internal;\n\n const [viewYear, setViewYear] = useState(\n (selected ?? today).getFullYear(),\n );\n const [viewMonth, setViewMonth] = useState(\n (selected ?? today).getMonth(),\n );\n\n const firstDay = new Date(viewYear, viewMonth, 1).getDay();\n const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();\n\n const prevMonth = () => {\n if (viewMonth === 0) { setViewMonth(11); setViewYear(y => y - 1); }\n else setViewMonth(m => m - 1);\n };\n const nextMonth = () => {\n if (viewMonth === 11) { setViewMonth(0); setViewYear(y => y + 1); }\n else setViewMonth(m => m + 1);\n };\n\n const handleSelect = (day: number) => {\n const date = new Date(viewYear, viewMonth, day);\n if (minDate && date < minDate) return;\n if (maxDate && date > maxDate) return;\n if (!value) setInternal(date);\n onChange?.(date);\n };\n\n // Build calendar grid\n const cells: Array<number | null> = [\n ...Array(firstDay).fill(null),\n ...Array.from({ length: daysInMonth }, (_, i) => i + 1),\n ];\n // Pad to complete last row\n while (cells.length % 7 !== 0) cells.push(null);\n const weeks = [];\n for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));\n\n return (\n <div className={`inline-block select-none rounded-2xl border border-slate-200 bg-white p-4 shadow-sm ${className}`}>\n {/* Header */}\n <div className=\"mb-3 flex items-center justify-between\">\n <button\n type=\"button\"\n onClick={prevMonth}\n aria-label=\"Previous month\"\n className=\"rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30\"\n >\n <ChevronLeft size={16} aria-hidden=\"true\" />\n </button>\n <span className=\"text-sm font-bold text-slate-800\">\n {MONTHS[viewMonth]} {viewYear}\n </span>\n <button\n type=\"button\"\n onClick={nextMonth}\n aria-label=\"Next month\"\n className=\"rounded-lg p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30\"\n >\n <ChevronRight size={16} aria-hidden=\"true\" />\n </button>\n </div>\n\n {/* Grid */}\n <table\n role=\"grid\"\n aria-label={`${MONTHS[viewMonth]} ${viewYear}`}\n className=\"w-full border-collapse\"\n >\n <thead>\n <tr>\n {DAYS.map((d) => (\n <th key={d} scope=\"col\" className=\"pb-2 text-center text-[10px] font-bold uppercase tracking-widest text-slate-400\">\n {d}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {weeks.map((week, wi) => (\n <tr key={wi}>\n {week.map((day, di) => {\n if (!day) return <td key={di} role=\"gridcell\" aria-label=\"Empty\" />;\n const date = new Date(viewYear, viewMonth, day);\n const isToday = isSameDay(date, today);\n const isSelected = !!selected && isSameDay(date, selected);\n const isDisabled = (minDate ? date < minDate : false) || (maxDate ? date > maxDate : false);\n const label = `${day} ${MONTHS[viewMonth]} ${viewYear}${isToday ? ', Today' : ''}${isSelected ? ', Selected' : ''}`;\n\n return (\n <td key={di} role=\"gridcell\" aria-label={label} aria-selected={isSelected} className=\"p-0.5\">\n <button\n type=\"button\"\n onClick={() => handleSelect(day)}\n disabled={isDisabled}\n aria-current={isToday ? 'date' : undefined}\n className={[\n 'flex h-8 w-8 items-center justify-center rounded-full text-sm font-semibold transition',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-blue/30',\n 'disabled:cursor-not-allowed disabled:opacity-30',\n isSelected\n ? 'bg-brand-blue text-white shadow-md'\n : isToday\n ? 'border border-brand-blue/60 text-brand-blue hover:bg-blue-50'\n : 'text-slate-700 hover:bg-slate-100',\n ].join(' ')}\n >\n {day}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n"],"mappings":"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"}