@exxatdesignux/ui 0.0.6 → 0.0.7

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 (264) hide show
  1. package/bin/init.mjs +29 -0
  2. package/package.json +7 -2
  3. package/template/.nvmrc +1 -0
  4. package/template/.prettierignore +7 -0
  5. package/template/.prettierrc +11 -0
  6. package/template/AGENTS.md +485 -0
  7. package/template/Logo/Exxat_Prism.svg +39 -0
  8. package/template/Logo/Exxat_one.svg +36 -0
  9. package/template/README.md +58 -0
  10. package/template/app/(app)/compliance/page.tsx +10 -0
  11. package/template/app/(app)/dashboard/loading.tsx +18 -0
  12. package/template/app/(app)/dashboard/page.tsx +36 -0
  13. package/template/app/(app)/data-list/[id]/page.tsx +28 -0
  14. package/template/app/(app)/data-list/new/page.tsx +31 -0
  15. package/template/app/(app)/data-list/page.tsx +10 -0
  16. package/template/app/(app)/error.tsx +43 -0
  17. package/template/app/(app)/help/page.tsx +34 -0
  18. package/template/app/(app)/layout.tsx +54 -0
  19. package/template/app/(app)/loading.tsx +18 -0
  20. package/template/app/(app)/question-bank/page.tsx +10 -0
  21. package/template/app/(app)/rotations/page.tsx +15 -0
  22. package/template/app/(app)/settings/page.tsx +17 -0
  23. package/template/app/(app)/sites/all/page.tsx +13 -0
  24. package/template/app/(app)/team/page.tsx +10 -0
  25. package/template/app/favicon.ico +0 -0
  26. package/template/app/globals.css +1811 -0
  27. package/template/app/layout.tsx +95 -0
  28. package/template/app/page.tsx +9 -0
  29. package/template/components/.gitkeep +0 -0
  30. package/template/components/app-sidebar-dynamic.tsx +15 -0
  31. package/template/components/app-sidebar.tsx +901 -0
  32. package/template/components/ask-leo-composer.tsx +216 -0
  33. package/template/components/ask-leo-sidebar.tsx +509 -0
  34. package/template/components/chart-area-interactive.tsx +293 -0
  35. package/template/components/charts-overview.tsx +2321 -0
  36. package/template/components/command-menu-01.tsx +133 -0
  37. package/template/components/command-menu-02.tsx +386 -0
  38. package/template/components/command-menu.tsx +182 -0
  39. package/template/components/compliance-board-view.tsx +134 -0
  40. package/template/components/compliance-client.tsx +92 -0
  41. package/template/components/compliance-list-view.tsx +59 -0
  42. package/template/components/compliance-page-header.tsx +89 -0
  43. package/template/components/compliance-table.tsx +525 -0
  44. package/template/components/dashboard-onboarding-gallery.tsx +13 -0
  45. package/template/components/dashboard-onboarding.tsx +21 -0
  46. package/template/components/dashboard-promo-banner.tsx +67 -0
  47. package/template/components/dashboard-quota-progress-card.tsx +369 -0
  48. package/template/components/dashboard-report-charts.tsx +69 -0
  49. package/template/components/dashboard-section-heading.tsx +68 -0
  50. package/template/components/dashboard-tabs.tsx +598 -0
  51. package/template/components/data-list-client.tsx +239 -0
  52. package/template/components/data-list-table-cells.test.tsx +22 -0
  53. package/template/components/data-list-table-cells.tsx +173 -0
  54. package/template/components/data-list-table.tsx +879 -0
  55. package/template/components/data-table/filter-date-calendar.tsx +38 -0
  56. package/template/components/data-table/filter-text-value-input.tsx +77 -0
  57. package/template/components/data-table/index.tsx +1612 -0
  58. package/template/components/data-table/pagination.tsx +256 -0
  59. package/template/components/data-table/types.ts +91 -0
  60. package/template/components/data-table/use-table-state.ts +566 -0
  61. package/template/components/data-view-dashboard-charts-compliance.tsx +960 -0
  62. package/template/components/data-view-dashboard-charts-team.tsx +968 -0
  63. package/template/components/data-view-dashboard-charts.tsx +1668 -0
  64. package/template/components/data-views/board-card-primitives.tsx +93 -0
  65. package/template/components/data-views/index.ts +41 -0
  66. package/template/components/data-views/list-page-board-card.tsx +192 -0
  67. package/template/components/data-views/list-page-board-template.tsx +122 -0
  68. package/template/components/data-views/placement-board-card.tsx +262 -0
  69. package/template/components/export-drawer.tsx +375 -0
  70. package/template/components/exxat-product-logo.tsx +453 -0
  71. package/template/components/form-layout-01.tsx +131 -0
  72. package/template/components/getting-started.tsx +625 -0
  73. package/template/components/key-metrics.tsx +920 -0
  74. package/template/components/leo-insight-indicator.tsx +364 -0
  75. package/template/components/leo-typing-dots.tsx +121 -0
  76. package/template/components/list-hub-status-badge.tsx +51 -0
  77. package/template/components/list-page-dashboard-charts.tsx +18 -0
  78. package/template/components/nav-documents.tsx +89 -0
  79. package/template/components/nav-main.tsx +58 -0
  80. package/template/components/nav-secondary.tsx +64 -0
  81. package/template/components/nav-user.tsx +190 -0
  82. package/template/components/new-placement-back-btn.tsx +28 -0
  83. package/template/components/new-placement-form.tsx +1066 -0
  84. package/template/components/onboarding/index.ts +4 -0
  85. package/template/components/onboarding/onboarding-01.tsx +7 -0
  86. package/template/components/onboarding/onboarding-02.tsx +7 -0
  87. package/template/components/onboarding/onboarding-03.tsx +7 -0
  88. package/template/components/onboarding/onboarding-04.tsx +7 -0
  89. package/template/components/page-header.tsx +57 -0
  90. package/template/components/placement-detail.tsx +438 -0
  91. package/template/components/placements-board-view.tsx +404 -0
  92. package/template/components/placements-list-view.tsx +285 -0
  93. package/template/components/placements-page-header.tsx +160 -0
  94. package/template/components/placements-table-columns.tsx +639 -0
  95. package/template/components/product-switcher.tsx +116 -0
  96. package/template/components/question-bank-board-view.tsx +205 -0
  97. package/template/components/question-bank-client.tsx +77 -0
  98. package/template/components/question-bank-list-view.tsx +59 -0
  99. package/template/components/question-bank-page-header.tsx +89 -0
  100. package/template/components/question-bank-table.tsx +586 -0
  101. package/template/components/rotations-empty-state.tsx +47 -0
  102. package/template/components/rotations-panel-activator.tsx +8 -0
  103. package/template/components/secondary-nav.tsx +394 -0
  104. package/template/components/secondary-panel.tsx +239 -0
  105. package/template/components/section-cards.tsx +106 -0
  106. package/template/components/settings-appearance-card.tsx +424 -0
  107. package/template/components/settings-client.tsx +537 -0
  108. package/template/components/settings-form-row.tsx +42 -0
  109. package/template/components/sidebar-auto-collapse.tsx +23 -0
  110. package/template/components/sidebar-auto-open.tsx +18 -0
  111. package/template/components/sidebar-shell.tsx +37 -0
  112. package/template/components/site-header.tsx +93 -0
  113. package/template/components/sites-all-client.tsx +154 -0
  114. package/template/components/sites-board-view.tsx +67 -0
  115. package/template/components/sites-list-view.tsx +47 -0
  116. package/template/components/sites-table.tsx +312 -0
  117. package/template/components/system-banner-slot.tsx +66 -0
  118. package/template/components/table-properties/column-row.tsx +90 -0
  119. package/template/components/table-properties/draggable-list.ts +49 -0
  120. package/template/components/table-properties/drawer-button.tsx +231 -0
  121. package/template/components/table-properties/drawer.tsx +1102 -0
  122. package/template/components/table-properties/filter-card.tsx +251 -0
  123. package/template/components/table-properties/index.ts +22 -0
  124. package/template/components/table-properties/sort-card.tsx +59 -0
  125. package/template/components/table-properties/types.ts +124 -0
  126. package/template/components/task-list-panel.tsx +98 -0
  127. package/template/components/task-priority-badge.tsx +28 -0
  128. package/template/components/team-board-view.tsx +114 -0
  129. package/template/components/team-client.tsx +93 -0
  130. package/template/components/team-list-view.tsx +62 -0
  131. package/template/components/team-page-header.tsx +92 -0
  132. package/template/components/team-table.tsx +525 -0
  133. package/template/components/templates/list-page.tsx +576 -0
  134. package/template/components/templates/primary-page-template.tsx +56 -0
  135. package/template/components/theme-color-sync.tsx +32 -0
  136. package/template/components/theme-provider.tsx +71 -0
  137. package/template/components/tinted-icon-disc.tsx +53 -0
  138. package/template/components/ui/ai-thinking-surface.tsx +121 -0
  139. package/template/components/ui/avatar.tsx +1 -0
  140. package/template/components/ui/badge.tsx +1 -0
  141. package/template/components/ui/banner.tsx +1 -0
  142. package/template/components/ui/breadcrumb.tsx +1 -0
  143. package/template/components/ui/button.tsx +1 -0
  144. package/template/components/ui/calendar.tsx +1 -0
  145. package/template/components/ui/card.tsx +1 -0
  146. package/template/components/ui/chart.tsx +1 -0
  147. package/template/components/ui/checkbox.tsx +1 -0
  148. package/template/components/ui/coach-mark.tsx +1 -0
  149. package/template/components/ui/collapsible.tsx +1 -0
  150. package/template/components/ui/command.tsx +1 -0
  151. package/template/components/ui/date-picker-field.tsx +1 -0
  152. package/template/components/ui/dialog.tsx +1 -0
  153. package/template/components/ui/dot-pattern.tsx +159 -0
  154. package/template/components/ui/drag-handle-grip.tsx +1 -0
  155. package/template/components/ui/drawer.tsx +1 -0
  156. package/template/components/ui/dropdown-menu.tsx +1 -0
  157. package/template/components/ui/field.tsx +1 -0
  158. package/template/components/ui/form.tsx +1 -0
  159. package/template/components/ui/input-group.tsx +1 -0
  160. package/template/components/ui/input-mask.tsx +1 -0
  161. package/template/components/ui/input.tsx +1 -0
  162. package/template/components/ui/kbd.tsx +1 -0
  163. package/template/components/ui/label.tsx +1 -0
  164. package/template/components/ui/leo-icon.tsx +726 -0
  165. package/template/components/ui/payment-card-fields.tsx +1 -0
  166. package/template/components/ui/popover.tsx +1 -0
  167. package/template/components/ui/radio-group.tsx +1 -0
  168. package/template/components/ui/select.tsx +1 -0
  169. package/template/components/ui/selection-tile-grid.tsx +1 -0
  170. package/template/components/ui/separator.tsx +1 -0
  171. package/template/components/ui/sheet.tsx +1 -0
  172. package/template/components/ui/sidebar.tsx +1 -0
  173. package/template/components/ui/skeleton.tsx +1 -0
  174. package/template/components/ui/sonner.tsx +1 -0
  175. package/template/components/ui/status-badge.tsx +1 -0
  176. package/template/components/ui/table.tsx +1 -0
  177. package/template/components/ui/tabs.tsx +1 -0
  178. package/template/components/ui/textarea.tsx +1 -0
  179. package/template/components/ui/tip.tsx +1 -0
  180. package/template/components/ui/toggle-group.tsx +1 -0
  181. package/template/components/ui/toggle-switch.tsx +1 -0
  182. package/template/components/ui/toggle.tsx +1 -0
  183. package/template/components/ui/tooltip.tsx +1 -0
  184. package/template/components/ui/view-segmented-control.tsx +1 -0
  185. package/template/components.json +27 -0
  186. package/template/contexts/chart-variant-context.tsx +35 -0
  187. package/template/contexts/command-menu-context.tsx +28 -0
  188. package/template/contexts/dashboard-view-context.tsx +35 -0
  189. package/template/contexts/product-context.tsx +38 -0
  190. package/template/contexts/system-banner-context.tsx +127 -0
  191. package/template/docs/command-menu-pattern.md +45 -0
  192. package/template/docs/data-views-pattern.md +160 -0
  193. package/template/ecosystem.config.cjs +20 -0
  194. package/template/eslint.config.mjs +18 -0
  195. package/template/fontawesome-subset.manifest.json +190 -0
  196. package/template/hooks/.gitkeep +0 -0
  197. package/template/hooks/use-app-theme.ts +1 -0
  198. package/template/hooks/use-coach-mark.ts +1 -0
  199. package/template/hooks/use-mobile.ts +1 -0
  200. package/template/hooks/use-mod-key-label.ts +1 -0
  201. package/template/lib/.gitkeep +0 -0
  202. package/template/lib/ask-leo-route-context.ts +133 -0
  203. package/template/lib/chart-keyboard-selection.test.ts +20 -0
  204. package/template/lib/chart-keyboard-selection.ts +17 -0
  205. package/template/lib/chart-line-dash.ts +16 -0
  206. package/template/lib/coach-mark-registry.ts +68 -0
  207. package/template/lib/command-menu-config.ts +127 -0
  208. package/template/lib/command-menu-search-data.ts +44 -0
  209. package/template/lib/conditional-rule-match.ts +32 -0
  210. package/template/lib/dashboard-customize-coach-mark.ts +18 -0
  211. package/template/lib/dashboard-layout-merge.ts +63 -0
  212. package/template/lib/data-list-display-options.ts +35 -0
  213. package/template/lib/data-list-persistence.ts +280 -0
  214. package/template/lib/data-list-view-surface.ts +58 -0
  215. package/template/lib/data-list-view.ts +29 -0
  216. package/template/lib/data-view-dashboard-storage.ts +101 -0
  217. package/template/lib/date-filter.ts +8 -0
  218. package/template/lib/dev-log.test.ts +28 -0
  219. package/template/lib/dev-log.ts +8 -0
  220. package/template/lib/editable-target.ts +10 -0
  221. package/template/lib/floating-sheet-panel.ts +72 -0
  222. package/template/lib/initials-from-name.ts +7 -0
  223. package/template/lib/list-page-table-properties.ts +52 -0
  224. package/template/lib/list-status-badges.ts +168 -0
  225. package/template/lib/logo-dev.ts +12 -0
  226. package/template/lib/mock/compliance-kpi.ts +61 -0
  227. package/template/lib/mock/compliance.ts +146 -0
  228. package/template/lib/mock/dashboard.ts +105 -0
  229. package/template/lib/mock/navigation.tsx +231 -0
  230. package/template/lib/mock/placements-kpi.ts +134 -0
  231. package/template/lib/mock/placements.ts +183 -0
  232. package/template/lib/mock/question-bank-kpi.ts +61 -0
  233. package/template/lib/mock/question-bank.ts +142 -0
  234. package/template/lib/mock/sites-directory.ts +16 -0
  235. package/template/lib/mock/sites-kpi.ts +25 -0
  236. package/template/lib/mock/team-kpi.ts +60 -0
  237. package/template/lib/mock/team.ts +118 -0
  238. package/template/lib/motion-ui.ts +17 -0
  239. package/template/lib/placement-board-card-layout.ts +79 -0
  240. package/template/lib/placement-lifecycle.ts +5 -0
  241. package/template/lib/row-height.ts +10 -0
  242. package/template/lib/stock-portrait.ts +11 -0
  243. package/template/lib/utils.test.ts +13 -0
  244. package/template/lib/utils.ts +1 -0
  245. package/template/next.config.mjs +15 -0
  246. package/template/package.json +83 -0
  247. package/template/postcss.config.mjs +8 -0
  248. package/template/public/.gitkeep +0 -0
  249. package/template/public/Illustration/Rotation.svg +74 -0
  250. package/template/public/avatars/user.svg +11 -0
  251. package/template/public/favicon/favicon.ico +0 -0
  252. package/template/public/favicon.ico +0 -0
  253. package/template/public/logos/exxat-one.svg +36 -0
  254. package/template/public/logos/exxat-prism.svg +39 -0
  255. package/template/public/mock-schools/emory.svg +4 -0
  256. package/template/public/mock-schools/rush.svg +4 -0
  257. package/template/scripts/fontawesome-subset-audit.mjs +190 -0
  258. package/template/scripts/pm2-startup-macos.sh +13 -0
  259. package/template/skills-lock.json +10 -0
  260. package/template/stores/app-store.ts +33 -0
  261. package/template/tests/setup.ts +1 -0
  262. package/template/tsconfig.json +35 -0
  263. package/template/types/react-payment-inputs.d.ts +19 -0
  264. package/template/vitest.config.ts +18 -0
@@ -0,0 +1,71 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { ThemeProvider as NextThemesProvider, useTheme } from "next-themes"
5
+
6
+ function ThemeProvider({
7
+ children,
8
+ ...props
9
+ }: React.ComponentProps<typeof NextThemesProvider>) {
10
+ return (
11
+ <NextThemesProvider
12
+ attribute="class"
13
+ defaultTheme="system"
14
+ enableSystem
15
+ disableTransitionOnChange
16
+ {...props}
17
+ >
18
+ <ThemeHotkey />
19
+ {children}
20
+ </NextThemesProvider>
21
+ )
22
+ }
23
+
24
+ function isTypingTarget(target: EventTarget | null) {
25
+ if (!(target instanceof HTMLElement)) {
26
+ return false
27
+ }
28
+
29
+ return (
30
+ target.isContentEditable ||
31
+ target.tagName === "INPUT" ||
32
+ target.tagName === "TEXTAREA" ||
33
+ target.tagName === "SELECT"
34
+ )
35
+ }
36
+
37
+ function ThemeHotkey() {
38
+ const { resolvedTheme, setTheme } = useTheme()
39
+
40
+ React.useEffect(() => {
41
+ function onKeyDown(event: KeyboardEvent) {
42
+ if (event.defaultPrevented || event.repeat) {
43
+ return
44
+ }
45
+
46
+ if (event.metaKey || event.ctrlKey || event.altKey) {
47
+ return
48
+ }
49
+
50
+ if (event.key.toLowerCase() !== "d") {
51
+ return
52
+ }
53
+
54
+ if (isTypingTarget(event.target)) {
55
+ return
56
+ }
57
+
58
+ setTheme(resolvedTheme === "dark" ? "light" : "dark")
59
+ }
60
+
61
+ window.addEventListener("keydown", onKeyDown)
62
+
63
+ return () => {
64
+ window.removeEventListener("keydown", onKeyDown)
65
+ }
66
+ }, [resolvedTheme, setTheme])
67
+
68
+ return null
69
+ }
70
+
71
+ export { ThemeProvider }
@@ -0,0 +1,53 @@
1
+ "use client"
2
+
3
+ /**
4
+ * Dashboard / feed — decorative icon on a tinted disc. Colors come from `app/globals.css`
5
+ * `--icon-disc-*` tokens (WCAG 1.4.11-friendly pairings). Prefer this over ad-hoc `oklch(from …)`.
6
+ */
7
+
8
+ import * as React from "react"
9
+ import { cn } from "@/lib/utils"
10
+
11
+ export type TintedIconDiscTone = "chart-2" | "chart-4" | "brand" | "destructive"
12
+
13
+ const TONE_CLASS: Record<TintedIconDiscTone, string> = {
14
+ "chart-2":
15
+ "bg-[var(--icon-disc-chart-2-bg)] text-[var(--icon-disc-chart-2-fg)]",
16
+ "chart-4":
17
+ "bg-[var(--icon-disc-chart-4-bg)] text-[var(--icon-disc-chart-4-fg)]",
18
+ brand: "bg-[var(--icon-disc-brand-bg)] text-[var(--icon-disc-brand-fg)]",
19
+ destructive:
20
+ "bg-[var(--icon-disc-danger-bg)] text-[var(--icon-disc-danger-fg)]",
21
+ }
22
+
23
+ export interface TintedIconDiscProps {
24
+ /** Font Awesome icon class suffix, e.g. `fa-arrow-trend-up` (paired with `fa-light`). */
25
+ icon: string
26
+ tone: TintedIconDiscTone
27
+ size?: "sm" | "md" | "lg"
28
+ className?: string
29
+ }
30
+
31
+ export function TintedIconDisc({
32
+ icon,
33
+ tone,
34
+ size = "md",
35
+ className,
36
+ }: TintedIconDiscProps) {
37
+ const sizeClass =
38
+ size === "sm" ? "h-6 w-6 text-xs" : size === "lg" ? "h-12 w-12 text-xl" : "h-7 w-7 text-xs"
39
+
40
+ return (
41
+ <span
42
+ className={cn(
43
+ "inline-flex shrink-0 items-center justify-center rounded-full hc:border hc:border-foreground forced-colors:border forced-colors:border-[CanvasText] forced-colors:bg-[Canvas] forced-colors:text-[CanvasText]",
44
+ sizeClass,
45
+ TONE_CLASS[tone],
46
+ className,
47
+ )}
48
+ aria-hidden="true"
49
+ >
50
+ <i className={cn("fa-light", icon)} />
51
+ </span>
52
+ )
53
+ }
@@ -0,0 +1,121 @@
1
+ "use client"
2
+
3
+ /**
4
+ * AiThinkingOverlay / AiThinkingSurface — ambient "AI is thinking" indicator.
5
+ *
6
+ * Drops a soft, drifting dot cloud onto any surface to signal the assistant
7
+ * is working. Intentionally decorative — pair with a visible text/sr-only
8
+ * status so screen readers still hear "Leo is thinking" / "Generating…".
9
+ *
10
+ * Two ways to use:
11
+ *
12
+ * 1) **Overlay** — drop inside an existing `relative` container:
13
+ *
14
+ * <div className="relative rounded-xl border p-6">
15
+ * <AiThinkingOverlay active={isPending} />
16
+ * <YourContent />
17
+ * </div>
18
+ *
19
+ * 2) **Surface** — wraps children and handles positioning for you:
20
+ *
21
+ * <AiThinkingSurface active={isPending} className="rounded-xl border p-6">
22
+ * <YourContent />
23
+ * </AiThinkingSurface>
24
+ *
25
+ * Accessibility: the overlay is `aria-hidden` and `pointer-events-none`;
26
+ * always render a live status element next to it, e.g.
27
+ * <span role="status" aria-live="polite" className="sr-only">Generating…</span>
28
+ */
29
+
30
+ import * as React from "react"
31
+ import { cn } from "@/lib/utils"
32
+ import { DotPattern } from "@/components/ui/dot-pattern"
33
+
34
+ export interface AiThinkingOverlayProps extends React.HTMLAttributes<HTMLDivElement> {
35
+ /** When false (default), nothing renders. Flip to true while the AI is working. */
36
+ active?: boolean
37
+ /** Number of drifting soft clouds. Keep small (1–2) for most surfaces. */
38
+ cloudCount?: number
39
+ /** Radius of each cloud in px — scale up for large surfaces. */
40
+ cloudRadius?: number
41
+ /** Grid tile size (both width and height of the repeating dot tile). */
42
+ gridSize?: number
43
+ /** Per-dot radius. */
44
+ dotRadius?: number
45
+ /** Tailwind utility for the dot fill (e.g. `"fill-foreground/35"`). */
46
+ fillClassName?: string
47
+ }
48
+
49
+ /**
50
+ * Absolute overlay. The parent must be `position: relative` and should usually
51
+ * clip overflow (e.g. `rounded-xl overflow-hidden`) so the drifting clouds
52
+ * don't paint outside the surface.
53
+ */
54
+ export function AiThinkingOverlay({
55
+ active = false,
56
+ cloudCount = 2,
57
+ cloudRadius = 260,
58
+ gridSize = 14,
59
+ dotRadius = 0.8,
60
+ fillClassName = "fill-foreground/35 dark:fill-foreground/45",
61
+ className,
62
+ ...props
63
+ }: AiThinkingOverlayProps) {
64
+ if (!active) return null
65
+ return (
66
+ <div
67
+ aria-hidden
68
+ className={cn("pointer-events-none absolute inset-0 z-0 overflow-hidden", className)}
69
+ {...props}
70
+ >
71
+ <DotPattern
72
+ glow
73
+ glowCount={cloudCount}
74
+ glowRadius={cloudRadius}
75
+ width={gridSize}
76
+ height={gridSize}
77
+ cr={dotRadius}
78
+ className={cn("absolute inset-0 h-full w-full", fillClassName)}
79
+ />
80
+ </div>
81
+ )
82
+ }
83
+
84
+ export interface AiThinkingSurfaceProps
85
+ extends React.HTMLAttributes<HTMLDivElement>,
86
+ Pick<AiThinkingOverlayProps, "active" | "cloudCount" | "cloudRadius" | "gridSize" | "dotRadius" | "fillClassName"> {
87
+ /** Optional className applied to the content wrapper (above the overlay). */
88
+ contentClassName?: string
89
+ }
90
+
91
+ /**
92
+ * Wrapper that adds `relative overflow-hidden`, renders the overlay, and
93
+ * stacks children above it. Use when you'd otherwise have to manually wire
94
+ * positioning around `<AiThinkingOverlay>`.
95
+ */
96
+ export function AiThinkingSurface({
97
+ active,
98
+ cloudCount,
99
+ cloudRadius,
100
+ gridSize,
101
+ dotRadius,
102
+ fillClassName,
103
+ className,
104
+ contentClassName,
105
+ children,
106
+ ...props
107
+ }: AiThinkingSurfaceProps) {
108
+ return (
109
+ <div className={cn("relative overflow-hidden", className)} {...props}>
110
+ <AiThinkingOverlay
111
+ active={active}
112
+ cloudCount={cloudCount}
113
+ cloudRadius={cloudRadius}
114
+ gridSize={gridSize}
115
+ dotRadius={dotRadius}
116
+ fillClassName={fillClassName}
117
+ />
118
+ <div className={cn("relative z-[1]", contentClassName)}>{children}</div>
119
+ </div>
120
+ )
121
+ }
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/avatar"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/badge"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/banner"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/breadcrumb"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/button"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/calendar"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/card"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/chart"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/checkbox"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/coach-mark"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/collapsible"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/command"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/date-picker-field"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/dialog"
@@ -0,0 +1,159 @@
1
+ "use client"
2
+
3
+ /**
4
+ * DotPattern — dot grid revealed by a soft drifting "cloud" mask.
5
+ *
6
+ * Inspiration: Google/Apple AI loading states — a diffuse dot field that
7
+ * softly fades in, drifts diagonally across the surface, then fades out.
8
+ * No bright glow cores, no particles — just one or two large soft halos
9
+ * sliding across the grid so the dots appear as an ambient cloud.
10
+ */
11
+
12
+ import * as React from "react"
13
+ import { motion } from "motion/react"
14
+ import { cn } from "@/lib/utils"
15
+
16
+ interface DotPatternProps extends React.SVGProps<SVGSVGElement> {
17
+ width?: number
18
+ height?: number
19
+ x?: number
20
+ y?: number
21
+ cx?: number
22
+ cy?: number
23
+ cr?: number
24
+ className?: string
25
+ glow?: boolean
26
+ /** Number of drifting soft clouds (keep small: 1–2). */
27
+ glowCount?: number
28
+ /** Cloud radius — large values produce a wide, diffuse reveal. */
29
+ glowRadius?: number
30
+ }
31
+
32
+ type Cloud = {
33
+ key: number
34
+ xs: string[]
35
+ ys: string[]
36
+ duration: number
37
+ delay: number
38
+ }
39
+
40
+ function rand(min: number, max: number) {
41
+ return min + Math.random() * (max - min)
42
+ }
43
+
44
+ export function DotPattern({
45
+ width = 14,
46
+ height = 14,
47
+ x = 0,
48
+ y = 0,
49
+ cx = 1,
50
+ cy = 1,
51
+ cr = 0.8,
52
+ className,
53
+ glow = false,
54
+ glowCount = 2,
55
+ glowRadius = 240,
56
+ ...props
57
+ }: DotPatternProps) {
58
+ const id = React.useId()
59
+ const maskId = `${id}-mask`
60
+ const gradId = `${id}-grad`
61
+
62
+ const clouds = React.useMemo<Cloud[]>(
63
+ () =>
64
+ Array.from({ length: glowCount }).map((_, i) => {
65
+ // Drift diagonally: bottom-right → top-left. Start/end partly off-canvas
66
+ // so the cloud enters and exits softly without a visible edge.
67
+ const startX = rand(85, 120)
68
+ const endX = rand(-20, 15)
69
+ const midX = (startX + endX) / 2 + rand(-6, 6)
70
+
71
+ const startY = rand(85, 115)
72
+ const endY = rand(-15, 10)
73
+ const midY = (startY + endY) / 2 + rand(-4, 4)
74
+
75
+ const duration = rand(8, 12)
76
+ // Offset clouds by half a cycle so one is arriving as the other leaves.
77
+ const delay = -(i / glowCount) * duration
78
+
79
+ return {
80
+ key: i,
81
+ xs: [`${startX}%`, `${midX}%`, `${endX}%`],
82
+ ys: [`${startY}%`, `${midY}%`, `${endY}%`],
83
+ duration,
84
+ delay,
85
+ }
86
+ }),
87
+ [glowCount],
88
+ )
89
+
90
+ return (
91
+ <svg
92
+ aria-hidden="true"
93
+ className={cn(
94
+ "pointer-events-none absolute inset-0 h-full w-full fill-neutral-400/80",
95
+ className,
96
+ )}
97
+ {...props}
98
+ >
99
+ <defs>
100
+ <pattern
101
+ id={id}
102
+ width={width}
103
+ height={height}
104
+ patternUnits="userSpaceOnUse"
105
+ patternContentUnits="userSpaceOnUse"
106
+ x={x}
107
+ y={y}
108
+ >
109
+ <circle cx={cx} cy={cy} r={cr} />
110
+ </pattern>
111
+
112
+ {glow ? (
113
+ <>
114
+ {/* Very soft falloff — no visible ring edge, dots dissolve gradually. */}
115
+ <radialGradient id={gradId}>
116
+ <stop offset="0%" stopColor="white" stopOpacity="0.9" />
117
+ <stop offset="40%" stopColor="white" stopOpacity="0.55" />
118
+ <stop offset="75%" stopColor="white" stopOpacity="0.18" />
119
+ <stop offset="100%" stopColor="white" stopOpacity="0" />
120
+ </radialGradient>
121
+
122
+ <mask id={maskId}>
123
+ {clouds.map((c) => (
124
+ <motion.circle
125
+ key={`cloud-${c.key}`}
126
+ r={glowRadius}
127
+ fill={`url(#${gradId})`}
128
+ initial={{ cx: c.xs[0], cy: c.ys[0], opacity: 0 }}
129
+ animate={{
130
+ cx: c.xs,
131
+ cy: c.ys,
132
+ // Long hold with soft fade at both ends.
133
+ opacity: [0, 1, 1, 0],
134
+ }}
135
+ transition={{
136
+ duration: c.duration,
137
+ delay: c.delay,
138
+ repeat: Infinity,
139
+ ease: "linear",
140
+ times: [0, 0.3, 0.7, 1],
141
+ }}
142
+ />
143
+ ))}
144
+ </mask>
145
+ </>
146
+ ) : null}
147
+ </defs>
148
+
149
+ {/* Dot grid — only visible inside the drifting soft clouds when glow is on. */}
150
+ <rect
151
+ width="100%"
152
+ height="100%"
153
+ strokeWidth={0}
154
+ fill={`url(#${id})`}
155
+ mask={glow ? `url(#${maskId})` : undefined}
156
+ />
157
+ </svg>
158
+ )
159
+ }
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/drag-handle-grip"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/drawer"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/dropdown-menu"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/field"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/form"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/input-group"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/input-mask"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/input"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/kbd"
@@ -0,0 +1 @@
1
+ export * from "../../../../packages/ui/src/components/ui/label"