@exxatdesignux/ui 0.2.16 → 0.2.18

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 (111) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +149 -4
  3. package/consumer-extras/cursor-skills/exxat-ds-skill/references/accessibility.md +142 -0
  4. package/consumer-extras/cursor-skills/exxat-ds-skill/references/coach-marks.md +169 -0
  5. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +382 -0
  6. package/consumer-extras/cursor-skills/exxat-kpi-flat-band/SKILL.md +38 -0
  7. package/consumer-extras/cursor-skills/exxat-mono-ids/SKILL.md +56 -0
  8. package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +19 -0
  9. package/consumer-extras/patterns/data-views-pattern.md +2 -0
  10. package/consumer-extras/patterns/kpi-flat-band-pattern.md +57 -0
  11. package/consumer-extras/patterns/shell-surface-elevation-pattern.md +52 -0
  12. package/package.json +3 -3
  13. package/src/components/ui/banner.tsx +2 -0
  14. package/src/components/ui/chart.tsx +57 -2
  15. package/src/components/ui/sidebar.tsx +3 -2
  16. package/src/globals.css +65 -14
  17. package/src/theme.css +3 -3
  18. package/template/.claude/skills/exxat-ds-skill/SKILL.md +1 -1
  19. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +1 -1
  20. package/template/.cursor/rules/exxat-mono-ids.mdc +30 -0
  21. package/template/AGENTS.md +27 -17
  22. package/template/app/(app)/data-list/page.tsx +2 -2
  23. package/template/app/(app)/error.tsx +22 -6
  24. package/template/app/(app)/layout.tsx +13 -6
  25. package/template/app/(app)/question-bank/layout.tsx +18 -5
  26. package/template/app/(app)/question-bank/new/page.tsx +58 -0
  27. package/template/app/global-error.tsx +63 -0
  28. package/template/app/globals.css +151 -14
  29. package/template/app/layout.tsx +43 -5
  30. package/template/components/app-sidebar.tsx +68 -33
  31. package/template/components/ask-leo-sidebar.tsx +0 -2
  32. package/template/components/brand-color-picker.tsx +344 -0
  33. package/template/components/compliance-list-view.tsx +33 -51
  34. package/template/components/compliance-table.tsx +4 -0
  35. package/template/components/data-table/index.tsx +99 -91
  36. package/template/components/data-table/pagination.tsx +0 -1
  37. package/template/components/data-table/types.ts +4 -1
  38. package/template/components/data-table/use-table-state.ts +276 -100
  39. package/template/components/data-views/data-row-list.tsx +183 -0
  40. package/template/components/data-views/index.ts +7 -3
  41. package/template/components/data-views/os-folder-glyph.tsx +8 -0
  42. package/template/components/dev-chunk-load-recovery.tsx +41 -0
  43. package/template/components/export-drawer.tsx +1 -1
  44. package/template/components/exxat-product-logo.tsx +168 -317
  45. package/template/components/invite-collaborators-drawer.tsx +5 -3
  46. package/template/components/key-metrics.tsx +122 -62
  47. package/template/components/new-placement-form.tsx +4 -2
  48. package/template/components/new-question-composer.tsx +2208 -0
  49. package/template/components/page-breadcrumb-trail.tsx +131 -0
  50. package/template/components/page-header.tsx +2 -1
  51. package/template/components/{data-views/placement-board-card.tsx → placement-board-card.tsx} +2 -2
  52. package/template/components/placement-detail.tsx +1 -1
  53. package/template/components/placements-board-view.tsx +1 -1
  54. package/template/components/{data-list-client.tsx → placements-client.tsx} +9 -7
  55. package/template/components/placements-list-view.tsx +19 -133
  56. package/template/components/{data-list-table-cells.test.tsx → placements-table-cells.test.tsx} +2 -2
  57. package/template/components/{data-list-table-cells.tsx → placements-table-cells.tsx} +1 -1
  58. package/template/components/placements-table-columns.tsx +2 -2
  59. package/template/components/{data-list-table.tsx → placements-table.tsx} +42 -66
  60. package/template/components/product-switcher.tsx +24 -7
  61. package/template/components/product-wordmark.tsx +282 -0
  62. package/template/components/question-bank-client.tsx +20 -2
  63. package/template/components/question-bank-hub-client.tsx +105 -115
  64. package/template/components/question-bank-list-view.tsx +30 -54
  65. package/template/components/question-bank-new-folder-sheet.tsx +1 -1
  66. package/template/components/question-bank-secondary-nav.tsx +0 -3
  67. package/template/components/question-bank-table.tsx +19 -6
  68. package/template/components/rotations-empty-state.tsx +3 -0
  69. package/template/components/secondary-panel.tsx +23 -3
  70. package/template/components/settings-appearance-card.tsx +584 -141
  71. package/template/components/sidebar-shell.tsx +2 -1
  72. package/template/components/site-header.tsx +36 -31
  73. package/template/components/sites-list-view.tsx +31 -36
  74. package/template/components/sites-table.tsx +4 -0
  75. package/template/components/table-properties/drawer-button.tsx +38 -20
  76. package/template/components/table-properties/drawer.tsx +17 -14
  77. package/template/components/team-client.tsx +1 -1
  78. package/template/components/team-list-view.tsx +34 -50
  79. package/template/components/team-table.tsx +8 -3
  80. package/template/components/templates/list-page.tsx +12 -9
  81. package/template/components/templates/nested-secondary-panel-shell.tsx +10 -4
  82. package/template/components/ui/dot-pattern.tsx +50 -26
  83. package/template/components/ui/leo-icon.tsx +23 -3
  84. package/template/contexts/product-context.tsx +70 -7
  85. package/template/contexts/system-banner-context.tsx +112 -4
  86. package/template/docs/data-views-pattern.md +2 -0
  87. package/template/docs/kpi-flat-band-pattern.md +57 -0
  88. package/template/docs/kpi-strip-max-four-pattern.md +1 -0
  89. package/template/docs/shell-surface-elevation-pattern.md +52 -0
  90. package/template/eslint.config.mjs +18 -0
  91. package/template/hooks/use-sidebar-reflow-zoom.ts +21 -11
  92. package/template/lib/chunk-load-error.ts +13 -0
  93. package/template/lib/conditional-rule-match.ts +87 -22
  94. package/template/lib/data-list-persistence.ts +57 -257
  95. package/template/lib/data-list-view.ts +6 -0
  96. package/template/lib/dev-log.test.ts +6 -5
  97. package/template/lib/exxat-palette.json +1462 -0
  98. package/template/lib/exxat-palette.ts +136 -0
  99. package/template/lib/list-page-table-properties.ts +1 -1
  100. package/template/lib/list-status-badges.ts +1 -1
  101. package/template/lib/mailto.ts +29 -0
  102. package/template/lib/placement-board-card-layout.ts +1 -1
  103. package/template/lib/product-brand.ts +268 -0
  104. package/template/lib/question-bank-authoring.ts +308 -0
  105. package/template/lib/question-bank-nav.ts +44 -0
  106. package/template/lib/raf-throttle.ts +45 -0
  107. package/template/lib/sidebar-state-cookie.ts +9 -0
  108. package/template/lib/table-state-lifecycle.ts +521 -0
  109. package/template/next.config.mjs +156 -0
  110. package/template/package.json +3 -3
  111. package/template/stores/app-store.ts +46 -1
@@ -91,12 +91,20 @@ export function OsFolderGlyph({
91
91
  aria-label={!decorative ? label : undefined}
92
92
  aria-hidden={decorative ? true : undefined}
93
93
  >
94
+ {/* Static SVG — `next/image` can't optimize SVGs without
95
+ `dangerouslyAllowSVG`, so we stay on plain <img> but add the same
96
+ loading/decoding hints `next/image` would. Folder grids render many
97
+ of these at once; lazy-loading lets the browser skip off-screen
98
+ glyphs until they scroll near the viewport. */}
99
+ {/* eslint-disable-next-line @next/next/no-img-element -- SVG; next/image can't optimize without dangerouslyAllowSVG */}
94
100
  <img
95
101
  src={OS_FOLDER_GLYPH_SRC}
96
102
  alt=""
97
103
  width={240}
98
104
  height={240}
99
105
  draggable={false}
106
+ loading="lazy"
107
+ decoding="async"
100
108
  className={cn(
101
109
  "h-full w-full object-contain",
102
110
  "transition-[filter] duration-200",
@@ -0,0 +1,41 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+
5
+ import { isChunkLoadError } from "@/lib/chunk-load-error"
6
+
7
+ const RELOAD_FLAG = "exxat-ds:chunk-reload-attempted"
8
+
9
+ /**
10
+ * Dev-only: auto-reload once when Turbopack serves a stale chunk hash so users
11
+ * are not stuck on a blank shell before the route error boundary mounts.
12
+ */
13
+ export function DevChunkLoadRecovery() {
14
+ React.useEffect(() => {
15
+ if (process.env.NODE_ENV !== "development") return
16
+
17
+ function maybeReload(error: unknown) {
18
+ if (!isChunkLoadError(error)) return
19
+ if (typeof window === "undefined") return
20
+ if (window.sessionStorage.getItem(RELOAD_FLAG) === "1") return
21
+ window.sessionStorage.setItem(RELOAD_FLAG, "1")
22
+ window.location.reload()
23
+ }
24
+
25
+ const onError = (event: ErrorEvent) => {
26
+ maybeReload(event.error ?? event.message)
27
+ }
28
+ const onRejection = (event: PromiseRejectionEvent) => {
29
+ maybeReload(event.reason)
30
+ }
31
+
32
+ window.addEventListener("error", onError)
33
+ window.addEventListener("unhandledrejection", onRejection)
34
+ return () => {
35
+ window.removeEventListener("error", onError)
36
+ window.removeEventListener("unhandledrejection", onRejection)
37
+ }
38
+ }, [])
39
+
40
+ return null
41
+ }
@@ -145,7 +145,7 @@ export function ExportDrawer({
145
145
  side="right"
146
146
  showCloseButton={false}
147
147
  showOverlay={false}
148
- className="z-[60] w-80 sm:max-w-80 p-0 gap-0 flex flex-col border border-border shadow-xl rounded-xl overflow-hidden"
148
+ className="z-[80] w-80 sm:max-w-80 p-0 gap-0 flex flex-col border border-border shadow-xl rounded-xl overflow-hidden"
149
149
  style={{ top: "0.5rem", bottom: "0.5rem", right: "0.5rem", height: "calc(100vh - 1rem)" }}
150
150
  >
151
151
  {/* Header */}