@rebasepro/app 0.0.1-canary.4829d6e

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 (268) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -0
  3. package/dist/auth/api.d.ts +66 -0
  4. package/dist/auth/index.d.ts +13 -0
  5. package/dist/auth/types.d.ts +127 -0
  6. package/dist/auth/useRebaseAuthController.d.ts +13 -0
  7. package/dist/components/AIIcon.d.ts +17 -0
  8. package/dist/components/AuthSimulationMenu.d.ts +0 -0
  9. package/dist/components/ConfirmationDialog.d.ts +9 -0
  10. package/dist/components/Debug/UIReferenceView.d.ts +13 -0
  11. package/dist/components/Debug/UIStyleGuide.d.ts +2 -0
  12. package/dist/components/Debug/collection-views/CardViewDemo.d.ts +2 -0
  13. package/dist/components/Debug/collection-views/CollectionTableDemo.d.ts +2 -0
  14. package/dist/components/Debug/collection-views/KanbanBoardDemo.d.ts +2 -0
  15. package/dist/components/Debug/collection-views/index.d.ts +3 -0
  16. package/dist/components/Debug/collection-views/sample_data.d.ts +23 -0
  17. package/dist/components/Debug/crm-dashboard/CalendarWidget.d.ts +22 -0
  18. package/dist/components/Debug/crm-dashboard/CrmDashboardDemo.d.ts +2 -0
  19. package/dist/components/Debug/crm-dashboard/DashboardMetrics.d.ts +15 -0
  20. package/dist/components/Debug/crm-dashboard/PipelineOverview.d.ts +34 -0
  21. package/dist/components/Debug/crm-dashboard/RecentActivity.d.ts +19 -0
  22. package/dist/components/Debug/crm-dashboard/TaskFilters.d.ts +30 -0
  23. package/dist/components/Debug/crm-dashboard/TaskTable.d.ts +50 -0
  24. package/dist/components/Debug/crm-dashboard/TasksView.d.ts +41 -0
  25. package/dist/components/ErrorTooltip.d.ts +3 -0
  26. package/dist/components/ErrorView.d.ts +21 -0
  27. package/dist/components/LanguageToggle.d.ts +2 -0
  28. package/dist/components/LoginView/LoginView.d.ts +113 -0
  29. package/dist/components/LoginView/index.d.ts +2 -0
  30. package/dist/components/NotFoundPage.d.ts +2 -0
  31. package/dist/components/RebaseAuth.d.ts +10 -0
  32. package/dist/components/RebaseLogo.d.ts +7 -0
  33. package/dist/components/SchemaDriftBanner.d.ts +27 -0
  34. package/dist/components/UnsavedChangesDialog.d.ts +9 -0
  35. package/dist/components/UserDisplay.d.ts +7 -0
  36. package/dist/components/UserSelectPopover.d.ts +63 -0
  37. package/dist/components/UserSettingsView.d.ts +2 -0
  38. package/dist/components/common/index.d.ts +6 -0
  39. package/dist/components/common/table_height.d.ts +5 -0
  40. package/dist/components/common/types.d.ts +66 -0
  41. package/dist/components/common/useColumnsIds.d.ts +9 -0
  42. package/dist/components/common/useDataTableController.d.ts +45 -0
  43. package/dist/components/common/useDebouncedData.d.ts +9 -0
  44. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  45. package/dist/components/index.d.ts +18 -0
  46. package/dist/contexts/AdminModeController.d.ts +4 -0
  47. package/dist/contexts/AnalyticsContext.d.ts +3 -0
  48. package/dist/contexts/AuthControllerContext.d.ts +3 -0
  49. package/dist/contexts/CollectionScopeContext.d.ts +50 -0
  50. package/dist/contexts/ComponentOverrideContext.d.ts +42 -0
  51. package/dist/contexts/CustomizationControllerContext.d.ts +3 -0
  52. package/dist/contexts/DataDriverContext.d.ts +3 -0
  53. package/dist/contexts/DataSourcesContext.d.ts +31 -0
  54. package/dist/contexts/DatabaseAdminContext.d.ts +3 -0
  55. package/dist/contexts/DialogsProvider.d.ts +4 -0
  56. package/dist/contexts/EffectiveRoleController.d.ts +4 -0
  57. package/dist/contexts/ModeController.d.ts +4 -0
  58. package/dist/contexts/RebaseClientInstanceContext.d.ts +6 -0
  59. package/dist/contexts/RebaseDataContext.d.ts +3 -0
  60. package/dist/contexts/SnackbarProvider.d.ts +2 -0
  61. package/dist/contexts/StorageSourceContext.d.ts +3 -0
  62. package/dist/contexts/StorageSourcesContext.d.ts +25 -0
  63. package/dist/contexts/UserConfigurationPersistenceContext.d.ts +3 -0
  64. package/dist/contexts/index.d.ts +17 -0
  65. package/dist/core/PluginLifecycleManager.d.ts +17 -0
  66. package/dist/core/PluginProviderStack.d.ts +21 -0
  67. package/dist/core/Rebase.d.ts +15 -0
  68. package/dist/core/RebaseProps.d.ts +291 -0
  69. package/dist/core/RebaseRouter.d.ts +4 -0
  70. package/dist/core/RebaseRoutes.d.ts +17 -0
  71. package/dist/core/index.d.ts +4 -0
  72. package/dist/hooks/ApiConfigContext.d.ts +24 -0
  73. package/dist/hooks/data/delete.d.ts +33 -0
  74. package/dist/hooks/data/save.d.ts +40 -0
  75. package/dist/hooks/data/useCollection.d.ts +62 -0
  76. package/dist/hooks/data/useData.d.ts +13 -0
  77. package/dist/hooks/data/useDataOrder.d.ts +12 -0
  78. package/dist/hooks/data/useFetch.d.ts +43 -0
  79. package/dist/hooks/data/useRelationSelector.d.ts +52 -0
  80. package/dist/hooks/index.d.ts +36 -0
  81. package/dist/hooks/useAdminModeController.d.ts +19 -0
  82. package/dist/hooks/useAnalyticsController.d.ts +5 -0
  83. package/dist/hooks/useAuthController.d.ts +11 -0
  84. package/dist/hooks/useAuthSubscription.d.ts +2 -0
  85. package/dist/hooks/useBackendStorageSource.d.ts +30 -0
  86. package/dist/hooks/useBridgeRegistration.d.ts +18 -0
  87. package/dist/hooks/useBrowserTitleAndIcon.d.ts +6 -0
  88. package/dist/hooks/useBuildAdminModeController.d.ts +6 -0
  89. package/dist/hooks/useBuildEffectiveRoleController.d.ts +8 -0
  90. package/dist/hooks/useBuildLocalConfigurationPersistence.d.ts +2 -0
  91. package/dist/hooks/useBuildModeController.d.ts +6 -0
  92. package/dist/hooks/useClipboard.d.ts +57 -0
  93. package/dist/hooks/useCollapsedGroups.d.ts +27 -0
  94. package/dist/hooks/useComponentOverride.d.ts +32 -0
  95. package/dist/hooks/useCustomizationController.d.ts +11 -0
  96. package/dist/hooks/useDialogsController.d.ts +11 -0
  97. package/dist/hooks/useEffectiveRoleController.d.ts +7 -0
  98. package/dist/hooks/useLargeLayout.d.ts +1 -0
  99. package/dist/hooks/useModeController.d.ts +19 -0
  100. package/dist/hooks/usePermissions.d.ts +12 -0
  101. package/dist/hooks/useRebaseClient.d.ts +5 -0
  102. package/dist/hooks/useRebaseContext.d.ts +11 -0
  103. package/dist/hooks/useRebaseRegistry.d.ts +34 -0
  104. package/dist/hooks/useResolvedComponent.d.ts +47 -0
  105. package/dist/hooks/useSlot.d.ts +18 -0
  106. package/dist/hooks/useSnackbarController.d.ts +20 -0
  107. package/dist/hooks/useStorageSource.d.ts +6 -0
  108. package/dist/hooks/useStudioBridge.d.ts +79 -0
  109. package/dist/hooks/useTranslation.d.ts +17 -0
  110. package/dist/hooks/useUnsavedChangesDialog.d.ts +12 -0
  111. package/dist/hooks/useUserConfigurationPersistence.d.ts +8 -0
  112. package/dist/i18n/RebaseI18nProvider.d.ts +33 -0
  113. package/dist/index.d.ts +16 -0
  114. package/dist/index.es.js +16843 -0
  115. package/dist/index.es.js.map +1 -0
  116. package/dist/index.umd.js +17021 -0
  117. package/dist/index.umd.js.map +1 -0
  118. package/dist/internal/common.d.ts +14 -0
  119. package/dist/internal/useRestoreScroll.d.ts +15 -0
  120. package/dist/locales/de.d.ts +2 -0
  121. package/dist/locales/en.d.ts +10 -0
  122. package/dist/locales/es.d.ts +10 -0
  123. package/dist/locales/fr.d.ts +2 -0
  124. package/dist/locales/hi.d.ts +2 -0
  125. package/dist/locales/it.d.ts +2 -0
  126. package/dist/locales/pt.d.ts +7 -0
  127. package/dist/util/constants.d.ts +1 -0
  128. package/dist/util/createFormexStub.d.ts +2 -0
  129. package/dist/util/entity_cache.d.ts +22 -0
  130. package/dist/util/enums.d.ts +5 -0
  131. package/dist/util/icon_list.d.ts +5 -0
  132. package/dist/util/icons.d.ts +20 -0
  133. package/dist/util/index.d.ts +8 -0
  134. package/dist/util/previews.d.ts +4 -0
  135. package/dist/util/useStorageUploadController.d.ts +44 -0
  136. package/dist/vitePlugin.d.ts +60 -0
  137. package/dist/vitePlugin.js +113 -0
  138. package/package.json +145 -0
  139. package/src/auth/api.ts +148 -0
  140. package/src/auth/index.ts +25 -0
  141. package/src/auth/types.ts +115 -0
  142. package/src/auth/useRebaseAuthController.ts +328 -0
  143. package/src/components/AIIcon.tsx +47 -0
  144. package/src/components/AuthSimulationMenu.tsx +0 -0
  145. package/src/components/ConfirmationDialog.tsx +48 -0
  146. package/src/components/Debug/UIReferenceView.tsx +958 -0
  147. package/src/components/Debug/UIStyleGuide.tsx +156 -0
  148. package/src/components/Debug/collection-views/CardViewDemo.tsx +85 -0
  149. package/src/components/Debug/collection-views/CollectionTableDemo.tsx +107 -0
  150. package/src/components/Debug/collection-views/KanbanBoardDemo.tsx +90 -0
  151. package/src/components/Debug/collection-views/index.ts +3 -0
  152. package/src/components/Debug/collection-views/sample_data.ts +42 -0
  153. package/src/components/Debug/crm-dashboard/CalendarWidget.tsx +389 -0
  154. package/src/components/Debug/crm-dashboard/CrmDashboardDemo.tsx +1102 -0
  155. package/src/components/Debug/crm-dashboard/DashboardMetrics.tsx +133 -0
  156. package/src/components/Debug/crm-dashboard/PipelineOverview.tsx +290 -0
  157. package/src/components/Debug/crm-dashboard/RecentActivity.tsx +215 -0
  158. package/src/components/Debug/crm-dashboard/TaskFilters.tsx +184 -0
  159. package/src/components/Debug/crm-dashboard/TaskTable.tsx +427 -0
  160. package/src/components/Debug/crm-dashboard/TasksView.tsx +234 -0
  161. package/src/components/ErrorTooltip.tsx +12 -0
  162. package/src/components/ErrorView.tsx +94 -0
  163. package/src/components/LanguageToggle.tsx +59 -0
  164. package/src/components/LoginView/LoginView.tsx +932 -0
  165. package/src/components/LoginView/index.ts +2 -0
  166. package/src/components/NotFoundPage.tsx +27 -0
  167. package/src/components/RebaseAuth.tsx +27 -0
  168. package/src/components/RebaseLogo.tsx +29 -0
  169. package/src/components/SchemaDriftBanner.tsx +102 -0
  170. package/src/components/UnsavedChangesDialog.tsx +46 -0
  171. package/src/components/UserDisplay.tsx +54 -0
  172. package/src/components/UserSelectPopover.tsx +399 -0
  173. package/src/components/UserSettingsView.tsx +318 -0
  174. package/src/components/common/index.ts +6 -0
  175. package/src/components/common/table_height.tsx +21 -0
  176. package/src/components/common/types.tsx +66 -0
  177. package/src/components/common/useColumnsIds.tsx +222 -0
  178. package/src/components/common/useDataTableController.tsx +514 -0
  179. package/src/components/common/useDebouncedData.ts +49 -0
  180. package/src/components/common/useScrollRestoration.tsx +68 -0
  181. package/src/components/index.tsx +26 -0
  182. package/src/contexts/AdminModeController.tsx +11 -0
  183. package/src/contexts/AnalyticsContext.tsx +4 -0
  184. package/src/contexts/AuthControllerContext.tsx +4 -0
  185. package/src/contexts/CollectionScopeContext.tsx +67 -0
  186. package/src/contexts/ComponentOverrideContext.tsx +81 -0
  187. package/src/contexts/CustomizationControllerContext.tsx +4 -0
  188. package/src/contexts/DataDriverContext.tsx +4 -0
  189. package/src/contexts/DataSourcesContext.tsx +36 -0
  190. package/src/contexts/DatabaseAdminContext.tsx +4 -0
  191. package/src/contexts/DialogsProvider.tsx +56 -0
  192. package/src/contexts/EffectiveRoleController.tsx +12 -0
  193. package/src/contexts/ModeController.tsx +11 -0
  194. package/src/contexts/RebaseClientInstanceContext.tsx +7 -0
  195. package/src/contexts/RebaseDataContext.tsx +4 -0
  196. package/src/contexts/SnackbarProvider.tsx +15 -0
  197. package/src/contexts/StorageSourceContext.tsx +4 -0
  198. package/src/contexts/StorageSourcesContext.tsx +30 -0
  199. package/src/contexts/UserConfigurationPersistenceContext.tsx +4 -0
  200. package/src/contexts/index.ts +17 -0
  201. package/src/core/PluginLifecycleManager.tsx +95 -0
  202. package/src/core/PluginProviderStack.tsx +40 -0
  203. package/src/core/Rebase.tsx +439 -0
  204. package/src/core/RebaseProps.tsx +320 -0
  205. package/src/core/RebaseRouter.tsx +17 -0
  206. package/src/core/RebaseRoutes.tsx +24 -0
  207. package/src/core/index.tsx +5 -0
  208. package/src/hooks/ApiConfigContext.tsx +41 -0
  209. package/src/hooks/data/delete.ts +55 -0
  210. package/src/hooks/data/save.ts +77 -0
  211. package/src/hooks/data/useCollection.tsx +176 -0
  212. package/src/hooks/data/useData.tsx +18 -0
  213. package/src/hooks/data/useDataOrder.ts +26 -0
  214. package/src/hooks/data/useFetch.tsx +140 -0
  215. package/src/hooks/data/useRelationSelector.tsx +234 -0
  216. package/src/hooks/index.tsx +45 -0
  217. package/src/hooks/useAdminModeController.tsx +23 -0
  218. package/src/hooks/useAnalyticsController.tsx +8 -0
  219. package/src/hooks/useAuthController.tsx +14 -0
  220. package/src/hooks/useAuthSubscription.ts +87 -0
  221. package/src/hooks/useBackendStorageSource.ts +288 -0
  222. package/src/hooks/useBridgeRegistration.tsx +32 -0
  223. package/src/hooks/useBrowserTitleAndIcon.tsx +23 -0
  224. package/src/hooks/useBuildAdminModeController.tsx +24 -0
  225. package/src/hooks/useBuildEffectiveRoleController.tsx +31 -0
  226. package/src/hooks/useBuildLocalConfigurationPersistence.tsx +75 -0
  227. package/src/hooks/useBuildModeController.tsx +71 -0
  228. package/src/hooks/useClipboard.tsx +158 -0
  229. package/src/hooks/useCollapsedGroups.ts +116 -0
  230. package/src/hooks/useComponentOverride.tsx +59 -0
  231. package/src/hooks/useCustomizationController.tsx +14 -0
  232. package/src/hooks/useDialogsController.tsx +15 -0
  233. package/src/hooks/useEffectiveRoleController.tsx +10 -0
  234. package/src/hooks/useLargeLayout.tsx +65 -0
  235. package/src/hooks/useModeController.tsx +23 -0
  236. package/src/hooks/usePermissions.ts +44 -0
  237. package/src/hooks/useRebaseClient.tsx +10 -0
  238. package/src/hooks/useRebaseContext.tsx +83 -0
  239. package/src/hooks/useRebaseRegistry.tsx +91 -0
  240. package/src/hooks/useResolvedComponent.tsx +159 -0
  241. package/src/hooks/useSlot.tsx +64 -0
  242. package/src/hooks/useSnackbarController.tsx +52 -0
  243. package/src/hooks/useStorageSource.tsx +11 -0
  244. package/src/hooks/useStudioBridge.tsx +209 -0
  245. package/src/hooks/useTranslation.ts +33 -0
  246. package/src/hooks/useUnsavedChangesDialog.tsx +64 -0
  247. package/src/hooks/useUserConfigurationPersistence.tsx +11 -0
  248. package/src/i18n/RebaseI18nProvider.tsx +160 -0
  249. package/src/index.ts +25 -0
  250. package/src/internal/common.tsx +16 -0
  251. package/src/internal/useRestoreScroll.tsx +69 -0
  252. package/src/locales/de.ts +902 -0
  253. package/src/locales/en.ts +980 -0
  254. package/src/locales/es.ts +922 -0
  255. package/src/locales/fr.ts +901 -0
  256. package/src/locales/hi.ts +901 -0
  257. package/src/locales/it.ts +901 -0
  258. package/src/locales/pt.ts +909 -0
  259. package/src/util/constants.ts +7 -0
  260. package/src/util/createFormexStub.tsx +66 -0
  261. package/src/util/entity_cache.ts +239 -0
  262. package/src/util/enums.ts +32 -0
  263. package/src/util/icon_list.ts +22 -0
  264. package/src/util/icons.tsx +149 -0
  265. package/src/util/index.ts +12 -0
  266. package/src/util/previews.ts +105 -0
  267. package/src/util/useStorageUploadController.tsx +350 -0
  268. package/src/vitePlugin.ts +196 -0
@@ -0,0 +1,958 @@
1
+
2
+ /**
3
+ * UIReferenceView — hidden debug route at /debug/ui
4
+ *
5
+ * This file is a STATIC reference of the real UI patterns used across the app.
6
+ * All markup / styles are copied verbatim from source files.
7
+ * DO NOT add invented styles. Only copy from actual source files.
8
+ *
9
+ * Sources:
10
+ * DefaultDrawer.tsx, DefaultAppBar.tsx, DrawerNavigationItem.tsx,
11
+ * DrawerNavigationGroup.tsx, UsersView.tsx, RolesView.tsx
12
+ */
13
+ import React, { useState } from "react";
14
+ import {
15
+ Alert,
16
+ AlertCircleIcon,
17
+ Avatar,
18
+ AppWindow,
19
+ BooleanSwitch,
20
+ Button,
21
+ Checkbox,
22
+ ChevronDownIcon,
23
+ ChevronsLeftIcon,
24
+ ChevronsRightIcon,
25
+ Chip,
26
+ CircleUserIcon,
27
+ CircularProgress,
28
+ cls,
29
+ ColumnsIcon,
30
+ defaultBorderMixin,
31
+ FileIcon,
32
+ FileTextIcon,
33
+ FilterChip,
34
+ FilterIcon,
35
+ FolderIcon,
36
+ IconButton,
37
+ iconSize,
38
+ KanbanIcon,
39
+ LayoutGridIcon,
40
+ ListIcon,
41
+ LoadingButton,
42
+ LogOutIcon,
43
+ Menu,
44
+ MenuItem,
45
+ MoonIcon,
46
+ MultiSelect,
47
+ MultiSelectItem,
48
+ PanelLeftIcon,
49
+ PencilIcon,
50
+ PlusIcon,
51
+ SearchBar,
52
+ Select,
53
+ SelectItem,
54
+ Separator,
55
+ SettingsIcon,
56
+ Skeleton,
57
+ SunIcon,
58
+ SunMoonIcon,
59
+ Tab,
60
+ Table,
61
+ TableBody,
62
+ TableCell,
63
+ TableHeader,
64
+ TableRow,
65
+ Tabs,
66
+ TagIcon,
67
+ TextField,
68
+ Tooltip,
69
+ Trash2Icon,
70
+ TypeIcon,
71
+ Typography,
72
+ UserIcon
73
+ } from "@rebasepro/ui";
74
+ import { RebaseLogo } from "../RebaseLogo";
75
+ import { CrmDashboardDemo } from "./crm-dashboard/CrmDashboardDemo";
76
+ import { CollectionTableDemo, CardViewDemo, KanbanBoardDemo } from "./collection-views";
77
+
78
+ const SECTIONS = [
79
+ { id: "drawer", label: "Drawer", icon: PanelLeftIcon },
80
+ { id: "appbar", label: "App Bar", icon: AppWindow },
81
+ { id: "tabs", label: "Tabs", icon: ListIcon },
82
+ { id: "editor-sidebar", label: "Editor Sidebar", icon: ColumnsIcon },
83
+ { id: "empty-states", label: "Empty States", icon: FileIcon },
84
+ { id: "typography", label: "Typography", icon: TypeIcon },
85
+ { id: "buttons", label: "Buttons", icon: PlusIcon },
86
+ { id: "inputs", label: "Form Inputs", icon: FileTextIcon },
87
+ { id: "chips-alerts", label: "Chips & Alerts", icon: AlertCircleIcon },
88
+ { id: "users", label: "Users View", icon: UserIcon },
89
+ { id: "user-dialog", label: "User Dialog", icon: CircleUserIcon },
90
+ { id: "crm-dashboard", label: "CRM Dashboard", icon: LayoutGridIcon },
91
+ { id: "collection-table", label: "Collection Table", icon: ListIcon },
92
+ { id: "card-view", label: "Card View", icon: LayoutGridIcon },
93
+ { id: "kanban-board", label: "Kanban Board", icon: KanbanIcon }
94
+ ];
95
+
96
+ export function UIReferenceView() {
97
+ const [activeSection, setActiveSection] = useState("drawer");
98
+ const scrollContainerRef = React.useRef<HTMLDivElement>(null);
99
+
100
+ const scrollTo = (id: string) => {
101
+ const el = document.getElementById(id);
102
+ const container = scrollContainerRef.current;
103
+ if (el && container) {
104
+ const offsetTop = el.offsetTop - container.offsetTop;
105
+ container.scrollTo({ top: offsetTop, behavior: "smooth" });
106
+ }
107
+ setActiveSection(id);
108
+ };
109
+
110
+ return (
111
+ <div className="flex w-full">
112
+
113
+ {/* ── Sidebar nav (same structure as DefaultDrawer) ─────────────── */}
114
+ <div className={cls("flex flex-col sticky top-0 h-screen grow-0 shrink-0 w-[200px] border-r", defaultBorderMixin)}>
115
+ {/* DrawerLogo */}
116
+ <div className="flex flex-row items-center shrink-0 pt-4 pb-2 px-2">
117
+ <div className="shrink-0 flex items-center justify-center w-[56px] h-[40px]">
118
+ <RebaseLogo width="28px" height="28px"/>
119
+ </div>
120
+ <Typography variant="subtitle1" noWrap className="truncate">UI Ref</Typography>
121
+ </div>
122
+
123
+ {/* Nav entries */}
124
+ <div className="mt-3 flex-grow overflow-scroll no-scrollbar">
125
+ <div className="my-2 mx-2 flex flex-col">
126
+ {/* Group header — from DrawerNavigationGroup */}
127
+ <div className={cls("pl-4 pr-2 py-1 flex flex-row items-center transition-colors cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-700/50 rounded-t-lg bg-surface-50 dark:bg-surface-950/30")}>
128
+ <ChevronDownIcon size={iconSize.smallest} className="text-surface-500 dark:text-surface-400 transition-transform duration-200 mr-1"/>
129
+ <Typography variant="caption" color="secondary" className="font-medium flex-grow line-clamp-1">
130
+ SECTIONS
131
+ </Typography>
132
+ </div>
133
+ {/* Nav items — from DrawerNavigationItem */}
134
+ <div className="overflow-hidden bg-surface-50 dark:bg-surface-950/30 rounded-b-lg">
135
+ {SECTIONS.map(s => {
136
+ const IconComponent = s.icon;
137
+ return (
138
+ <div key={s.id}>
139
+ <div
140
+ onClick={() => scrollTo(s.id)}
141
+ className={cls(
142
+ "rounded-lg truncate group/nav",
143
+ "hover:bg-primary/5 dark:hover:bg-primary/5 text-text-primary dark:text-surface-200 hover:text-surface-900 dark:hover:text-white",
144
+ "flex flex-row items-center",
145
+ "pr-4 h-10",
146
+ "font-medium text-xs cursor-pointer",
147
+ activeSection === s.id ? "bg-primary/8 dark:bg-primary/10 text-primary dark:text-primary" : ""
148
+ )}
149
+ >
150
+ <div className={cls("shrink-0 flex items-center justify-center w-[56px] h-[40px] text-surface-500 dark:text-text-secondary-dark transition-colors duration-150 group-hover/nav:text-primary", activeSection === s.id && "text-primary dark:text-primary")}>
151
+ <IconComponent size={iconSize.small}/>
152
+ </div>
153
+ <div className="text-text-primary dark:text-surface-200 opacity-100 font-inherit truncate space-x-2">
154
+ {s.label.toUpperCase()}
155
+ </div>
156
+ </div>
157
+ </div>
158
+ );
159
+ })}
160
+ </div>
161
+ </div>
162
+ </div>
163
+
164
+ {/* DrawerToggle — from DefaultDrawer */}
165
+ <div className={cls("shrink-0 mt-auto border-t px-2 py-2", defaultBorderMixin)}>
166
+ <div className={cls(
167
+ "flex flex-row items-center rounded-lg cursor-pointer",
168
+ "hover:bg-surface-accent-100 dark:hover:bg-surface-800",
169
+ "transition-colors duration-150",
170
+ "py-2"
171
+ )}>
172
+ <div className="shrink-0 flex items-center justify-center w-[56px] h-[24px] text-surface-500 dark:text-surface-400">
173
+ <ChevronsLeftIcon size={iconSize.small}/>
174
+ </div>
175
+ <Typography variant="body2" className="text-surface-500 dark:text-surface-400 select-none whitespace-nowrap">
176
+ Collapse
177
+ </Typography>
178
+ </div>
179
+ </div>
180
+ </div>
181
+
182
+ {/* ── Main content area ───────────────────────────────────────────── */}
183
+ <div ref={scrollContainerRef} className="flex-1">
184
+
185
+ {/* ═══════════════════════════════════════════════
186
+ SECTION: Drawer
187
+ ═══════════════════════════════════════════════ */}
188
+ <SectionBlock id="drawer" title="Drawer — DefaultDrawer.tsx">
189
+ <Typography variant="body2" color="secondary" className="mb-4">
190
+ The drawer wraps <code className="font-mono text-xs">DrawerLogo</code>, scrollable <code className="font-mono text-xs">DrawerNavigationGroup</code>s,
191
+ and <code className="font-mono text-xs">DrawerToggle</code>. Two visual states: collapsed (icon only, 72px) and expanded (280px).
192
+ </Typography>
193
+ <div className="flex gap-6 flex-wrap">
194
+
195
+ {/* Collapsed — exact markup from DefaultDrawer + DrawerNavigationItem */}
196
+ <div>
197
+ <Typography variant="caption" color="secondary" className="block mb-1">Collapsed (72px)</Typography>
198
+ <div className={cls("flex flex-col h-72 relative w-[72px] border rounded-lg overflow-hidden bg-white dark:bg-surface-900", defaultBorderMixin)}>
199
+ <div className="flex flex-row items-center shrink-0 pt-4 pb-2 px-2">
200
+ <div className="shrink-0 flex items-center justify-center w-[56px] h-[40px]">
201
+ <RebaseLogo width="28px" height="28px"/>
202
+ </div>
203
+ </div>
204
+ <div className="mt-3 flex-grow overflow-hidden">
205
+ <div className="my-2 mx-2 flex flex-col">
206
+ <div className="overflow-hidden rounded-lg bg-surface-50 dark:bg-surface-950/30">
207
+ {[<FolderIcon key="folder" size={iconSize.small}/>, <UserIcon key="user" size={iconSize.small}/>, <TagIcon key="tag" size={iconSize.small}/>].map((icon, i) => (
208
+ <div key={i} className="rounded-lg truncate hover:bg-primary/5 dark:hover:bg-primary/5 flex flex-row items-center h-10">
209
+ <div className="shrink-0 flex items-center justify-center w-[56px] h-[40px] text-text-secondary dark:text-text-secondary-dark">
210
+ {icon}
211
+ </div>
212
+ </div>
213
+ ))}
214
+ </div>
215
+ </div>
216
+ </div>
217
+ <div className={cls("shrink-0 mt-auto border-t px-2 py-2", defaultBorderMixin)}>
218
+ <div className="flex flex-row items-center rounded-lg cursor-pointer hover:bg-surface-accent-100 dark:hover:bg-surface-800 transition-colors duration-150 py-2">
219
+ <div className="shrink-0 flex items-center justify-center w-[56px] h-[24px] text-surface-500 dark:text-surface-400">
220
+ <ChevronsRightIcon size={iconSize.small}/>
221
+ </div>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </div>
226
+
227
+ {/* Expanded — exact markup from DefaultDrawer + DrawerNavigationGroup + DrawerNavigationItem */}
228
+ <div>
229
+ <Typography variant="caption" color="secondary" className="block mb-1">Expanded (280px)</Typography>
230
+ <div className={cls("flex flex-col h-72 relative w-[280px] border rounded-lg overflow-hidden bg-white dark:bg-surface-900", defaultBorderMixin)}>
231
+ {/* DrawerLogo */}
232
+ <div className="flex flex-row items-center shrink-0 pt-4 pb-2 px-2">
233
+ <div className="shrink-0 flex items-center justify-center w-[56px] h-[40px]">
234
+ <RebaseLogo width="28px" height="28px"/>
235
+ </div>
236
+ <div className="flex flex-row items-center overflow-hidden transition-all duration-200 ease-in-out opacity-100 w-full ml-1">
237
+ <Typography variant="subtitle1" noWrap className="truncate">Rebase</Typography>
238
+ </div>
239
+ </div>
240
+ {/* DrawerNavigationGroup */}
241
+ <div className="mt-3 flex-grow overflow-hidden">
242
+ <div className="my-2 mx-2 flex flex-col">
243
+ <div className="pl-4 pr-2 py-1 flex flex-row items-center transition-colors cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-700/50 rounded-t-lg bg-surface-50 dark:bg-surface-950/30">
244
+ <ChevronDownIcon size={iconSize.smallest} className="text-surface-500 dark:text-surface-400 mr-1"/>
245
+ <Typography variant="caption" color="secondary" className="font-medium flex-grow line-clamp-1">CONTENT</Typography>
246
+ </div>
247
+ <div className="overflow-hidden bg-surface-50 dark:bg-surface-950/30 rounded-b-lg">
248
+ {[
249
+ { label: "Posts",
250
+ icon: <FolderIcon size={iconSize.small}/>,
251
+ active: true },
252
+ { label: "Authors",
253
+ icon: <UserIcon size={iconSize.small}/>,
254
+ active: false },
255
+ { label: "Tags",
256
+ icon: <TagIcon size={iconSize.small}/>,
257
+ active: false }
258
+ ].map(({ label, icon, active }) => (
259
+ <div key={label} className={cls(
260
+ "rounded-lg truncate hover:bg-primary/5 dark:hover:bg-primary/5 text-text-primary dark:text-surface-200 hover:text-surface-900 dark:hover:text-white flex flex-row items-center pr-4 h-10 font-medium text-xs cursor-pointer",
261
+ active ? "bg-primary/8 dark:bg-primary/10 text-primary dark:text-primary" : ""
262
+ )}>
263
+ <div className={cls("shrink-0 flex items-center justify-center w-[56px] h-[40px] transition-colors duration-150", active ? "text-primary dark:text-primary" : "text-surface-500 dark:text-text-secondary-dark")}>
264
+ {icon}
265
+ </div>
266
+ <div className="text-text-primary dark:text-surface-200 font-inherit truncate">
267
+ {label.toUpperCase()}
268
+ </div>
269
+ </div>
270
+ ))}
271
+ </div>
272
+ </div>
273
+ </div>
274
+ {/* DrawerToggle */}
275
+ <div className={cls("shrink-0 mt-auto border-t px-2 py-2", defaultBorderMixin)}>
276
+ <div className="flex flex-row items-center rounded-lg cursor-pointer hover:bg-surface-accent-100 dark:hover:bg-surface-800 transition-colors duration-150 py-2">
277
+ <div className="shrink-0 flex items-center justify-center w-[56px] h-[24px] text-surface-500 dark:text-surface-400">
278
+ <ChevronsLeftIcon size={iconSize.small}/>
279
+ </div>
280
+ <div className="overflow-hidden transition-all duration-200 ease-in-out opacity-100 w-auto">
281
+ <Typography variant="body2" className="text-surface-500 dark:text-surface-400 select-none whitespace-nowrap">
282
+ Collapse
283
+ </Typography>
284
+ </div>
285
+ </div>
286
+ </div>
287
+ </div>
288
+ </div>
289
+ </div>
290
+ </SectionBlock>
291
+
292
+ {/* ═══════════════════════════════════════════════
293
+ SECTION: AppBar
294
+ ═══════════════════════════════════════════════ */}
295
+ <SectionBlock id="appbar" title="App Bar — DefaultAppBar.tsx">
296
+ <Typography variant="body2" color="secondary" className="mb-4">
297
+ Fixed at top (<code className="font-mono text-xs">h-16 absolute top-0</code>). Contains breadcrumbs (caption + body2), Content/Studio pill toggle,
298
+ theme menu, and user avatar menu via <code className="font-mono text-xs">Menu</code>.
299
+ </Typography>
300
+ {/* Exact classes from DefaultAppBar line 121-130 */}
301
+ <div className={cls("w-full h-16 flex flex-row gap-2 px-4 items-center border rounded-lg relative", defaultBorderMixin)}>
302
+ {/* Breadcrumbs — from DefaultAppBar line 157-188 */}
303
+ <div className="mr-8 hidden lg:block">
304
+ <div className="flex flex-row gap-2 items-center">
305
+ <Typography variant="caption" color="secondary">/</Typography>
306
+ <div className="flex flex-row items-center gap-2 whitespace-nowrap">
307
+ <Typography variant="body2">Posts</Typography>
308
+ <span className="text-xs text-surface-accent-500 dark:text-surface-accent-400 bg-surface-100 dark:bg-surface-700 px-1 py-0 rounded">42</span>
309
+ </div>
310
+ <Typography variant="caption" color="secondary">/</Typography>
311
+ <div className="flex flex-row items-center gap-2 whitespace-nowrap">
312
+ <Typography variant="body2">My Post</Typography>
313
+ </div>
314
+ </div>
315
+ </div>
316
+ <div className="grow"/>
317
+ {/* Content/Studio toggle — from DefaultAppBar line 204-225 */}
318
+ <div className={cls("mr-2 hidden sm:flex bg-surface-100 dark:bg-surface-950 rounded-lg p-0.5 border", defaultBorderMixin)}>
319
+ <button className={cls("px-3 py-1 text-xs font-semibold rounded-md transition-all", "bg-white dark:bg-surface-900 shadow-sm text-primary dark:text-primary-400")}>
320
+ Content
321
+ </button>
322
+ <button className={cls("px-3 py-1 text-xs font-semibold rounded-md transition-all", "text-surface-500 hover:text-surface-900 dark:hover:text-white")}>
323
+ Studio
324
+ </button>
325
+ </div>
326
+ {/* Theme menu — from DefaultAppBar line 227-241 */}
327
+ <Menu trigger={
328
+ <IconButton color="inherit">
329
+ <MoonIcon/>
330
+ </IconButton>
331
+ }>
332
+ <MenuItem><MoonIcon size={iconSize.smallest}/> Dark</MenuItem>
333
+ <MenuItem><SunIcon size={iconSize.smallest}/> Light</MenuItem>
334
+ <MenuItem><SunMoonIcon size={iconSize.smallest}/> System</MenuItem>
335
+ </Menu>
336
+ {/* Avatar menu — from DefaultAppBar line 243-270 */}
337
+ <Menu trigger={<Avatar>A</Avatar>}>
338
+ <div className="px-4 py-2 mb-2">
339
+ <Typography variant="body1" color="secondary">Alice Johnson</Typography>
340
+ <Typography variant="body2" color="secondary">alice@example.com</Typography>
341
+ </div>
342
+ <MenuItem><SettingsIcon/> Account Settings</MenuItem>
343
+ <MenuItem><LogOutIcon/> Log Out</MenuItem>
344
+ </Menu>
345
+ </div>
346
+ </SectionBlock>
347
+
348
+ {/* ═══════════════════════════════════════════════
349
+ SECTION: Tabs
350
+ ═══════════════════════════════════════════════ */}
351
+ <SectionBlock id="tabs" title="Tabs — Tabs.tsx">
352
+ <Typography variant="body2" color="secondary" className="mb-4">
353
+ All editor components use <code className="font-mono text-xs">variant=&quot;boxy&quot;</code> tabs for sidebar navigation.
354
+ The boxy variant provides a segmented, flat tab bar that integrates tightly with editor chrome.
355
+ </Typography>
356
+
357
+ <div className="flex flex-col gap-6">
358
+ {/* Default variant */}
359
+ <div>
360
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">variant=&quot;default&quot;</Typography>
361
+ <Tabs value="tab1" onValueChange={() => {}}>
362
+ <Tab value="tab1">Schema</Tab>
363
+ <Tab value="tab2">Snippets</Tab>
364
+ <Tab value="tab3">History</Tab>
365
+ </Tabs>
366
+ </div>
367
+
368
+ {/* Boxy variant — exact pattern from SQLEditorSidebar, JSEditorSidebar, RLSEditor */}
369
+ <div>
370
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">variant=&quot;boxy&quot; (Editor Standard)</Typography>
371
+ <div className={cls("border rounded-lg overflow-hidden w-[320px]", defaultBorderMixin)}>
372
+ <Tabs value="schema" onValueChange={() => {}} variant="boxy" className="border-b border-surface-200 dark:border-surface-950">
373
+ <Tab value="schema">Schema</Tab>
374
+ <Tab value="snippets">Snippets</Tab>
375
+ <Tab value="history">History</Tab>
376
+ </Tabs>
377
+ {/* Section header pattern — used in all editor sidebars */}
378
+ <div className={cls("p-3 border-b flex justify-between items-center bg-surface-50 dark:bg-surface-900", defaultBorderMixin)}>
379
+ <Typography variant="caption" className="font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark">TABLES</Typography>
380
+ <IconButton size="small">
381
+ <SettingsIcon size={iconSize.smallest}/>
382
+ </IconButton>
383
+ </div>
384
+ <div className="p-2 h-24">
385
+ <Typography variant="caption" className="text-text-disabled dark:text-text-disabled-dark italic p-2">Tab content area…</Typography>
386
+ </div>
387
+ </div>
388
+ </div>
389
+
390
+ {/* Toolbar tabs — from SQLEditor/JSEditor main toolbar */}
391
+ <div>
392
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">Toolbar Tabs (boxy, inline with controls)</Typography>
393
+ <div className={cls("border rounded-lg overflow-hidden flex items-center justify-between pr-2 bg-white dark:bg-surface-950", defaultBorderMixin)}>
394
+ <div className="flex items-center">
395
+ <Tabs value="query1" onValueChange={() => {}} variant="boxy" className="w-[unset] flex-shrink-0">
396
+ <Tab value="query1" className="flex items-center gap-1.5">
397
+ <svg className="w-3.5 h-3.5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"/></svg>
398
+ Query 1
399
+ </Tab>
400
+ <Tab value="query2" className="flex items-center gap-1.5">
401
+ <svg className="w-3.5 h-3.5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"/></svg>
402
+ Query 2
403
+ </Tab>
404
+ </Tabs>
405
+ <IconButton size="small" className="ml-2 flex-shrink-0">
406
+ <PlusIcon/>
407
+ </IconButton>
408
+ </div>
409
+ <div className="flex items-center gap-1.5">
410
+ <Button variant="text" size="small">Explain</Button>
411
+ <div className="h-4 w-px bg-surface-200 dark:bg-surface-950"/>
412
+ <Button size="small" color="primary">Run</Button>
413
+ </div>
414
+ </div>
415
+ </div>
416
+ </div>
417
+ </SectionBlock>
418
+
419
+ {/* ═══════════════════════════════════════════════
420
+ SECTION: Editor Sidebar
421
+ ═══════════════════════════════════════════════ */}
422
+ <SectionBlock id="editor-sidebar" title="Editor Sidebar — Harmonized Pattern">
423
+ <Typography variant="body2" color="secondary" className="mb-4">
424
+ All studio editor components (SQL, JS, RLS, Collection) share the same underlying sidebar foundation:
425
+ <code className="font-mono text-xs">Tabs variant=&quot;boxy&quot;</code> at top (optional) → section header with uppercase label → scrollable list.
426
+ While SQL/JS/RLS use dense tree entries, the Collection Schema Editor uses larger items (<code className="font-mono text-xs">px-3 py-2</code>, <code className="font-mono text-xs">text-sm</code>) suitable for primary navigation.
427
+ </Typography>
428
+
429
+ <div className="flex gap-6 flex-wrap">
430
+ {/* SQL Editor Sidebar replica */}
431
+ <div>
432
+ <Typography variant="caption" color="secondary" className="block mb-1">SQL Editor Sidebar</Typography>
433
+ <div className={cls("flex flex-col h-72 w-[240px] border rounded-lg overflow-hidden", defaultBorderMixin)}>
434
+ <Tabs value="schema" onValueChange={() => {}} variant="boxy" className="border-b border-surface-200 dark:border-surface-950">
435
+ <Tab value="schema">Schema</Tab>
436
+ <Tab value="snippets">Snippets</Tab>
437
+ <Tab value="history">History</Tab>
438
+ </Tabs>
439
+ <div className={cls("p-3 border-b flex justify-between items-center bg-surface-50 dark:bg-surface-900", defaultBorderMixin)}>
440
+ <Typography variant="caption" className="font-bold uppercase tracking-wider text-text-secondary dark:text-text-secondary-dark">TABLES</Typography>
441
+ <IconButton size="small">
442
+ <SettingsIcon size={iconSize.smallest}/>
443
+ </IconButton>
444
+ </div>
445
+ <div className="flex-grow overflow-y-auto no-scrollbar p-1">
446
+ {/* Schema tree items — from SchemaBrowser */}
447
+ <div className="mb-2">
448
+ <div className="flex items-center p-1 cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-900 rounded transition-colors">
449
+ <svg className="w-3 h-3 mr-1 rotate-90" fill="currentColor" viewBox="0 0 20 20"><path d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>
450
+ <Typography variant="body2" className="text-text-primary dark:text-text-primary-dark font-medium text-xs">public</Typography>
451
+ </div>
452
+ <div className="ml-3 mt-1 space-y-1">
453
+ {["users", "posts", "comments"].map(t => (
454
+ <div key={t} className="flex items-center p-1 cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-900 rounded transition-colors group">
455
+ <svg className="w-3.5 h-3.5 mr-1 shrink-0 text-text-disabled dark:text-text-disabled-dark" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
456
+ <Typography variant="body2" className="text-text-secondary dark:text-text-secondary-dark text-xs truncate">{t}</Typography>
457
+ </div>
458
+ ))}
459
+ </div>
460
+ </div>
461
+ </div>
462
+ </div>
463
+ </div>
464
+
465
+ {/* RLS Editor Sidebar replica */}
466
+ <div>
467
+ <Typography variant="caption" color="secondary" className="block mb-1">RLS Editor Sidebar</Typography>
468
+ <div className={cls("flex flex-col h-72 w-[240px] border rounded-lg overflow-hidden", defaultBorderMixin)}>
469
+ <Tabs value="tables" onValueChange={() => {}} variant="boxy" className="border-b border-surface-200 dark:border-surface-950">
470
+ <Tab value="tables">Tables</Tab>
471
+ <Tab value="info">Info</Tab>
472
+ </Tabs>
473
+ <div className={cls("p-3 border-b flex justify-between items-center bg-surface-50 dark:bg-surface-900", defaultBorderMixin)}>
474
+ <Typography variant="caption" className="font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark">RLS</Typography>
475
+ <IconButton size="small">
476
+ <SettingsIcon size={iconSize.smallest}/>
477
+ </IconButton>
478
+ </div>
479
+ <div className="flex-grow overflow-y-auto no-scrollbar p-1">
480
+ <div className="mb-2">
481
+ <div className="flex items-center p-1 cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-900 rounded transition-colors">
482
+ <svg className="w-3 h-3 mr-1 rotate-90" fill="currentColor" viewBox="0 0 20 20"><path d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>
483
+ <Typography variant="body2" className="text-text-primary dark:text-text-primary-dark font-medium text-xs">public</Typography>
484
+ </div>
485
+ <div className="ml-3 mt-1 space-y-0.5">
486
+ {[{ name: "users",
487
+ enabled: true }, { name: "posts",
488
+ enabled: true }, { name: "sessions",
489
+ enabled: false }].map(t => (
490
+ <div key={t.name} className={cls("flex items-center p-1 cursor-pointer rounded transition-colors", t.name === "users" ? "bg-primary/10 text-primary dark:bg-primary/20" : "hover:bg-surface-100 dark:hover:bg-surface-900 text-text-secondary")}>
491
+ <svg className="w-3.5 h-3.5 mr-1 shrink-0 text-text-disabled" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
492
+ <Typography variant="body2" className="text-xs truncate flex-1">{t.name}</Typography>
493
+ <div className={cls("w-1.5 h-1.5 rounded-full shrink-0", t.enabled ? "bg-green-500" : "bg-orange-400 opacity-50")}/>
494
+ </div>
495
+ ))}
496
+ </div>
497
+ </div>
498
+ </div>
499
+ </div>
500
+ </div>
501
+
502
+ {/* Collection Editor Sidebar replica */}
503
+ <div>
504
+ <Typography variant="caption" color="secondary" className="block mb-1">Collection Editor Sidebar</Typography>
505
+ <div className={cls("flex flex-col h-72 w-[240px] border rounded-lg overflow-hidden bg-white dark:bg-surface-950", defaultBorderMixin)}>
506
+ <div className={cls("p-3 border-b flex justify-between items-center bg-surface-50 dark:bg-surface-900", defaultBorderMixin)}>
507
+ <Typography variant="caption" className="font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark">COLLECTIONS</Typography>
508
+ <IconButton size="small">
509
+ <PlusIcon size={iconSize.smallest}/>
510
+ </IconButton>
511
+ </div>
512
+ <div className="flex-grow overflow-y-auto no-scrollbar p-2 space-y-0.5">
513
+ {[{ name: "Authors" }, { name: "Posts",
514
+ selected: true }, { name: "Tags" }].map(c => (
515
+ <div key={c.name} className={cls("flex items-center gap-3 px-3 py-2 cursor-pointer rounded-md text-sm transition-colors", c.selected ? "bg-primary/10 text-primary dark:bg-primary/20 dark:text-primary-light" : "hover:bg-surface-100 dark:hover:bg-surface-900 text-text-secondary dark:text-text-secondary-dark")}>
516
+ <FolderIcon size={iconSize.small} className={cls(c.selected ? "text-primary dark:text-primary-light" : "text-text-secondary dark:text-text-secondary-dark")}/>
517
+ <span className="truncate flex-1">{c.name}</span>
518
+ </div>
519
+ ))}
520
+ </div>
521
+ </div>
522
+ </div>
523
+ </div>
524
+ </SectionBlock>
525
+
526
+ {/* ═══════════════════════════════════════════════
527
+ SECTION: Empty States
528
+ ═══════════════════════════════════════════════ */}
529
+ <SectionBlock id="empty-states" title="Empty States — Canonical Pattern">
530
+ <Typography variant="body2" color="secondary" className="mb-4">
531
+ All empty / placeholder states share the same layout: a centered <code className="font-mono text-xs">flex-col</code> container
532
+ with <code className="font-mono text-xs">Typography variant=&quot;label&quot;</code> for the message and a <code className="font-mono text-xs">Button</code> with <code className="font-mono text-xs">AddIcon</code> for the primary action.
533
+ Sources: <code className="font-mono text-xs">CollectionPropertiesEditorForm</code>, <code className="font-mono text-xs">CollectionsStudioView</code>, <code className="font-mono text-xs">CollectionStudioView</code>.
534
+ </Typography>
535
+
536
+ <div className="flex gap-6 flex-wrap">
537
+ {/* Property editor empty state */}
538
+ <div>
539
+ <Typography variant="caption" color="secondary" className="block mb-1">Property Editor (no selection)</Typography>
540
+ <div className={cls("flex flex-col items-center justify-center h-48 w-[320px] border rounded-lg", defaultBorderMixin)}>
541
+ <div className="flex flex-col items-center justify-center h-full gap-4">
542
+ <Typography variant="label">
543
+ Select a property to edit it
544
+ </Typography>
545
+ <Button>
546
+ <PlusIcon/>
547
+ Add new property
548
+ </Button>
549
+ </div>
550
+ </div>
551
+ </div>
552
+
553
+ {/* Property editor empty collection state */}
554
+ <div>
555
+ <Typography variant="caption" color="secondary" className="block mb-1">Property Editor (empty collection)</Typography>
556
+ <div className={cls("flex flex-col items-center justify-center h-48 w-[320px] border rounded-lg", defaultBorderMixin)}>
557
+ <div className="flex flex-col items-center justify-center h-full gap-4">
558
+ <Typography variant="label">
559
+ Now you can add your first property
560
+ </Typography>
561
+ <Button>
562
+ <PlusIcon/>
563
+ Add new property
564
+ </Button>
565
+ </div>
566
+ </div>
567
+ </div>
568
+
569
+ {/* Collection list empty state */}
570
+ <div>
571
+ <Typography variant="caption" color="secondary" className="block mb-1">Collection ListIcon (no selection)</Typography>
572
+ <div className={cls("flex flex-col items-center justify-center h-48 w-[320px] border rounded-lg", defaultBorderMixin)}>
573
+ <div className="flex flex-col items-center justify-center h-full gap-4">
574
+ <Typography variant="label">
575
+ Select a collection or create a new one to start editing
576
+ </Typography>
577
+ <Button>
578
+ <PlusIcon/>
579
+ Add new collection
580
+ </Button>
581
+ </div>
582
+ </div>
583
+ </div>
584
+ </div>
585
+ </SectionBlock>
586
+
587
+ {/* ═══════════════════════════════════════════════
588
+ SECTION: Typography
589
+ ═══════════════════════════════════════════════ */}
590
+ <SectionBlock id="typography" title="Typography">
591
+ <Typography variant="body2" color="secondary" className="mb-4">
592
+ All variants from <code className="font-mono text-xs">Typography</code>. Colors: primary (default), secondary, disabled, error.
593
+ </Typography>
594
+ <div className="flex flex-col gap-3">
595
+ {(["h1", "h2", "h3", "h4", "h5", "h6", "subtitle1", "subtitle2", "body1", "body2", "caption", "label", "button"] as const).map(v => (
596
+ <div key={v} className={cls("flex items-baseline gap-4 border-b pb-3 last:border-0", defaultBorderMixin)}>
597
+ <span className="w-24 shrink-0 text-xs text-surface-400 font-mono">{v}</span>
598
+ <Typography variant={v}>The quick brown fox jumps over the lazy dog</Typography>
599
+ </div>
600
+ ))}
601
+ </div>
602
+ <div className="flex gap-4 flex-wrap mt-4">
603
+ {(["primary", "secondary", "disabled", "error"] as const).map(c => (
604
+ <Typography key={c} color={c}>color=&quot;{c}&quot;</Typography>
605
+ ))}
606
+ </div>
607
+ </SectionBlock>
608
+
609
+ {/* ═══════════════════════════════════════════════
610
+ SECTION: Buttons
611
+ ═══════════════════════════════════════════════ */}
612
+ <SectionBlock id="buttons" title="Buttons">
613
+ <div className="flex flex-col gap-6">
614
+ {(["filled", "text"] as const).map(variant => (
615
+ <div key={variant}>
616
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">variant=&quot;{variant}&quot;</Typography>
617
+ <div className="flex flex-wrap gap-3 items-center">
618
+ {(["primary", "secondary", "text", "error", "neutral"] as const).map(color => (
619
+ <Button key={color} variant={variant} color={color}>{color.charAt(0).toUpperCase() + color.slice(1)}</Button>
620
+ ))}
621
+ <Button variant={variant} disabled>Disabled</Button>
622
+ </div>
623
+ </div>
624
+ ))}
625
+ <div>
626
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">sizes</Typography>
627
+ <div className="flex flex-wrap items-end gap-3">
628
+ {(["small", "medium", "large", "xl", "2xl"] as const).map(s => (
629
+ <Button key={s} size={s}>{s.charAt(0).toUpperCase() + s.slice(1)}</Button>
630
+ ))}
631
+ </div>
632
+ </div>
633
+ <div>
634
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">IconButton — sizes</Typography>
635
+ <div className="flex flex-wrap gap-3 items-center">
636
+ {([
637
+ { s: "smallest" as const, icon: <PencilIcon size={14}/> },
638
+ { s: "small" as const, icon: <PencilIcon size={16}/> },
639
+ { s: "medium" as const, icon: <PencilIcon size={20}/> },
640
+ { s: "large" as const, icon: <PencilIcon size={24}/> }
641
+ ]).map(({ s, icon }) => (
642
+ <div key={s} className="flex flex-col items-center gap-1">
643
+ <IconButton size={s}>{icon}</IconButton>
644
+ <Typography variant="caption" color="secondary">{s.charAt(0).toUpperCase() + s.slice(1)}</Typography>
645
+ </div>
646
+ ))}
647
+ <div className="flex flex-col items-center gap-1">
648
+ <IconButton disabled><Trash2Icon size={20}/></IconButton>
649
+ <Typography variant="caption" color="secondary">Disabled</Typography>
650
+ </div>
651
+ <div className="flex flex-col items-center gap-1">
652
+ <IconButton variant="filled"><PlusIcon size={20}/></IconButton>
653
+ <Typography variant="caption" color="secondary">Filled</Typography>
654
+ </div>
655
+ <div className="flex flex-col items-center gap-1">
656
+ <IconButton shape="square"><SettingsIcon size={20}/></IconButton>
657
+ <Typography variant="caption" color="secondary">Square</Typography>
658
+ </div>
659
+ </div>
660
+ </div>
661
+ <div>
662
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">LoadingButton</Typography>
663
+ <div className="flex flex-wrap gap-3">
664
+ <LoadingButton loading={true}>Saving…</LoadingButton>
665
+ <LoadingButton loading={false}>Idle</LoadingButton>
666
+ </div>
667
+ </div>
668
+ </div>
669
+ </SectionBlock>
670
+
671
+ {/* ═══════════════════════════════════════════════
672
+ SECTION: Form Inputs
673
+ ═══════════════════════════════════════════════ */}
674
+ <SectionBlock id="inputs" title="Form Inputs">
675
+ <div className="grid grid-cols-12 gap-4">
676
+ <div className="col-span-12 sm:col-span-6">
677
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">TextField</Typography>
678
+ <div className="flex flex-col gap-3">
679
+ <TextField label="Default" placeholder="Type something…"/>
680
+ <TextField label="With value" value="Filled value" onChange={() => {}}/>
681
+ <TextField label="Error state" error value="Bad value" onChange={() => {}}/>
682
+ <TextField label="Disabled" disabled value="Read only" onChange={() => {}}/>
683
+ </div>
684
+ </div>
685
+ <div className="col-span-12 sm:col-span-6 flex flex-col gap-4">
686
+ <div>
687
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">Select</Typography>
688
+ <Select label="Status" value="published" onValueChange={() => {}}>
689
+ <SelectItem value="draft">Draft</SelectItem>
690
+ <SelectItem value="published">Published</SelectItem>
691
+ <SelectItem value="archived">Archived</SelectItem>
692
+ </Select>
693
+ </div>
694
+ <div>
695
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">MultiSelect</Typography>
696
+ <MultiSelect label="Roles" value={["admin", "editor"]} onValueChange={() => {}}>
697
+ <MultiSelectItem value="admin">Admin</MultiSelectItem>
698
+ <MultiSelectItem value="editor">Editor</MultiSelectItem>
699
+ <MultiSelectItem value="viewer">Viewer</MultiSelectItem>
700
+ </MultiSelect>
701
+ </div>
702
+ </div>
703
+ <div className="col-span-12 sm:col-span-6 flex flex-col gap-3">
704
+ <Typography variant="caption" color="secondary" className="block font-mono">Checkbox</Typography>
705
+ <label className="flex items-center gap-2 cursor-pointer"><Checkbox checked={true} onCheckedChange={() => {}}/><span>Checked</span></label>
706
+ <label className="flex items-center gap-2 cursor-pointer"><Checkbox checked={false} onCheckedChange={() => {}}/><span>Unchecked</span></label>
707
+ <label className="flex items-center gap-2"><Checkbox checked={true} disabled/><span>Disabled</span></label>
708
+ </div>
709
+ <div className="col-span-12 sm:col-span-6 flex flex-col gap-3">
710
+ <Typography variant="caption" color="secondary" className="block font-mono">BooleanSwitch</Typography>
711
+ <div className="flex items-center gap-2"><BooleanSwitch value={true} onValueChange={() => {}}/><span>On</span></div>
712
+ <div className="flex items-center gap-2"><BooleanSwitch value={false} onValueChange={() => {}}/><span>Off</span></div>
713
+ </div>
714
+ <div className="col-span-12">
715
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">SearchBar</Typography>
716
+ <SearchBar placeholder="Search entities…"/>
717
+ </div>
718
+ <div className="col-span-12">
719
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">Skeleton</Typography>
720
+ <div className="flex gap-4 items-center flex-wrap">
721
+ <Skeleton className="w-10 h-10 rounded-full"/>
722
+ <Skeleton className="w-48 h-4 rounded"/>
723
+ <Skeleton className="w-32 h-8 rounded-md"/>
724
+ </div>
725
+ </div>
726
+ </div>
727
+ </SectionBlock>
728
+
729
+ {/* ═══════════════════════════════════════════════
730
+ SECTION: Chips & Alerts
731
+ ═══════════════════════════════════════════════ */}
732
+ <SectionBlock id="chips-alerts" title="Chips & Alerts">
733
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">Chip — colorScheme</Typography>
734
+ <div className="flex flex-wrap gap-2 mb-4">
735
+ {(["blue", "teal", "red", "green", "yellow", "orange", "purple", "pink", "cyan", "indigo", "violet", "fuchsia", "rose", "emerald", "gray"] as const).map(s => (
736
+ <Chip key={s} colorScheme={s}>{s}</Chip>
737
+ ))}
738
+ </div>
739
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">Chip — sizes</Typography>
740
+ <div className="flex flex-wrap gap-2 items-center mb-4">
741
+ {(["smallest", "small", "medium", "large"] as const).map(sz => (
742
+ <Chip key={sz} colorScheme="blue" size={sz}>{sz}</Chip>
743
+ ))}
744
+ </div>
745
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">Chip — outlined, error, clickable, icon</Typography>
746
+ <div className="flex flex-wrap gap-2 items-center mb-4">
747
+ <Chip colorScheme="red" outlined>Outlined Red</Chip>
748
+ <Chip colorScheme="blue" outlined>Outlined Blue</Chip>
749
+ <Chip error>Error</Chip>
750
+ <Chip error outlined>Error Outlined</Chip>
751
+ <Chip onClick={() => {}}>Clickable</Chip>
752
+ <Chip icon={<TagIcon size={12}/>} colorScheme="teal">With Icon</Chip>
753
+ <Chip>Default (no scheme)</Chip>
754
+ <Chip outlined>Default Outlined</Chip>
755
+ </div>
756
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">FilterChip</Typography>
757
+ <div className="flex flex-wrap gap-2 items-center mb-6">
758
+ <FilterChip active>Active</FilterChip>
759
+ <FilterChip>Inactive</FilterChip>
760
+ <FilterChip icon={<FilterIcon size={12}/>} active>With Icon</FilterChip>
761
+ <FilterChip size="small">Small</FilterChip>
762
+ <FilterChip disabled>Disabled</FilterChip>
763
+ </div>
764
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">Alert — color variants</Typography>
765
+ <div className="flex flex-col gap-2">
766
+ <Alert color="info">Info — informational message</Alert>
767
+ <Alert color="success">Success — operation completed</Alert>
768
+ <Alert color="warning">Warning — attention required</Alert>
769
+ <Alert color="error">Error — something went wrong</Alert>
770
+ </div>
771
+ <div className="mt-4">
772
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">Separator</Typography>
773
+ <div>Above</div>
774
+ <Separator orientation="horizontal"/>
775
+ <div>Below</div>
776
+ </div>
777
+ <div className="mt-4">
778
+ <Typography variant="caption" color="secondary" className="block mb-2 font-mono">CircularProgress</Typography>
779
+ <div className="flex gap-6 items-center">
780
+ {(["small", "medium", "large"] as const).map(s => (
781
+ <div key={s} className="flex flex-col items-center gap-1">
782
+ <CircularProgress size={s}/>
783
+ <Typography variant="caption" color="secondary">{s}</Typography>
784
+ </div>
785
+ ))}
786
+ </div>
787
+ </div>
788
+ </SectionBlock>
789
+
790
+ {/* ═══════════════════════════════════════════════
791
+ SECTION: Users View
792
+ ═══════════════════════════════════════════════ */}
793
+ <SectionBlock id="users" title="Users View — UsersView.tsx">
794
+ <Typography variant="body2" color="secondary" className="mb-4">
795
+ Layout from <code className="font-mono text-xs">UsersView</code>: <code className="font-mono text-xs">Container maxWidth=&quot;6xl&quot;</code>, header row, and table with <code className="font-mono text-xs">RoleChip</code>s.
796
+ </Typography>
797
+ {/* Bootstrap warning — from UsersView line 105-119 */}
798
+ <div className="bg-yellow-100 dark:bg-yellow-900 border border-yellow-400 dark:border-yellow-700 rounded p-4 flex items-center justify-between mb-4">
799
+ <div>
800
+ <Typography variant="label" className="text-yellow-800 dark:text-yellow-200">
801
+ No admin users exist. You can make yourself an admin.
802
+ </Typography>
803
+ </div>
804
+ <Button>Make me admin</Button>
805
+ </div>
806
+ {/* Header — from UsersView line 121-128 */}
807
+ <div className="flex items-center mt-12">
808
+ <Typography gutterBottom variant="h4" className="grow" component="h4">Users</Typography>
809
+ <Button startIcon={<PlusIcon/>}>Add user</Button>
810
+ </div>
811
+ {/* Table — from UsersView line 130-182 */}
812
+ <div className="overflow-auto">
813
+ <Table className="w-full">
814
+ <TableHeader>
815
+ <TableCell header className="truncate w-16"></TableCell>
816
+ <TableCell header>Email</TableCell>
817
+ <TableCell header>Name</TableCell>
818
+ <TableCell header>Roles</TableCell>
819
+ </TableHeader>
820
+ <TableBody>
821
+ {[
822
+ { uid: "1",
823
+ email: "alice@example.com",
824
+ displayName: "Alice Johnson",
825
+ roles: [{ id: "admin",
826
+ name: "Admin",
827
+ isAdmin: true }] },
828
+ { uid: "2",
829
+ email: "bob@example.com",
830
+ displayName: "Bob Smith",
831
+ roles: [{ id: "editor",
832
+ name: "Editor",
833
+ isAdmin: false }] },
834
+ { uid: "3",
835
+ email: "carol@example.com",
836
+ displayName: "Carol White",
837
+ roles: [] }
838
+ ].map(user => (
839
+ <TableRow key={user.uid}>
840
+ <TableCell style={{ width: "64px" }}>
841
+ <Tooltip asChild title="Delete this user">
842
+ <IconButton size="small"><Trash2Icon/></IconButton>
843
+ </Tooltip>
844
+ </TableCell>
845
+ <TableCell>{user.email}</TableCell>
846
+ <TableCell className="font-medium">{user.displayName}</TableCell>
847
+ <TableCell>
848
+ <div className="flex flex-wrap gap-2">
849
+ {user.roles.map(role => (
850
+ <Chip key={role.id} colorScheme={role.isAdmin ? "purpleDark" : "blueDark"} size="small">
851
+ {role.name}
852
+ </Chip>
853
+ ))}
854
+ </div>
855
+ </TableCell>
856
+ </TableRow>
857
+ ))}
858
+ </TableBody>
859
+ </Table>
860
+ </div>
861
+ </SectionBlock>
862
+
863
+ {/* ═══════════════════════════════════════════════
864
+ SECTION: User Dialog
865
+ ═══════════════════════════════════════════════ */}
866
+ <SectionBlock id="user-dialog" title="User Dialog — UserDetailsForm">
867
+ <Typography variant="body2" color="secondary" className="mb-4">
868
+ Exact structure of <code className="font-mono text-xs">UserDetailsForm</code>: <code className="font-mono text-xs">grid grid-cols-12 gap-4</code>, <code className="font-mono text-xs">MultiSelect</code> for roles, <code className="font-mono text-xs">LoadingButton</code> to submit.
869
+ </Typography>
870
+ <div className={`rounded-lg border w-full max-w-xl ${defaultBorderMixin}`}>
871
+ <div className="px-6 pt-6 pb-2">
872
+ <Typography variant="h4">User</Typography>
873
+ </div>
874
+ <div className="px-6 py-4">
875
+ <div className="grid grid-cols-12 gap-4">
876
+ <div className="col-span-12">
877
+ <TextField name="displayName" required value="Alice Johnson" onChange={() => {}} label="Name"/>
878
+ </div>
879
+ <div className="col-span-12">
880
+ <TextField required name="email" value="alice@example.com" onChange={() => {}} label="Email" disabled/>
881
+ </div>
882
+ <div className="col-span-12">
883
+ <MultiSelect className="w-full" label="Roles" value={["admin"]} onValueChange={() => {}}>
884
+ <MultiSelectItem value="admin">Admin</MultiSelectItem>
885
+ <MultiSelectItem value="editor">Editor</MultiSelectItem>
886
+ <MultiSelectItem value="viewer">Viewer</MultiSelectItem>
887
+ </MultiSelect>
888
+ </div>
889
+ </div>
890
+ </div>
891
+ <div className="flex items-center justify-end gap-2 px-6 pb-6">
892
+ <Button variant="text">Cancel</Button>
893
+ <LoadingButton variant="filled" loading={false}>Update</LoadingButton>
894
+ </div>
895
+ </div>
896
+ </SectionBlock>
897
+
898
+ {/* ═══════════════════════════════════════════════
899
+ SECTION: CRM Dashboard
900
+ ═══════════════════════════════════════════════ */}
901
+ <SectionBlock id="crm-dashboard" title="CRM Dashboard — CrmDashboardDemo">
902
+ <Typography variant="body2" color="secondary" className="mb-4">
903
+ A real-world showcase of a complex dashboard home page incorporating Rebase design language.
904
+ </Typography>
905
+ <div className="w-full">
906
+ <CrmDashboardDemo />
907
+ </div>
908
+ </SectionBlock>
909
+
910
+ {/* ═══════════════════════════════════════════════
911
+ SECTION: Collection Table
912
+ ═══════════════════════════════════════════════ */}
913
+ <SectionBlock id="collection-table" title="Collection Table">
914
+ <Typography variant="body2" color="secondary" className="mb-4">
915
+ Sample data collection rendered as a sortable, searchable, filterable table with row selection.
916
+ Uses <code className="font-mono text-xs">Table</code>, <code className="font-mono text-xs">Chip</code>,{" "}
917
+ <code className="font-mono text-xs">SearchBar</code>, <code className="font-mono text-xs">Select</code>,{" "}
918
+ <code className="font-mono text-xs">Checkbox</code>.
919
+ </Typography>
920
+ <div className="w-full"><CollectionTableDemo /></div>
921
+ </SectionBlock>
922
+
923
+ {/* ═══════════════════════════════════════════════
924
+ SECTION: Card View
925
+ ═══════════════════════════════════════════════ */}
926
+ <SectionBlock id="card-view" title="Card View">
927
+ <Typography variant="body2" color="secondary" className="mb-4">
928
+ Grid of entity cards with thumbnail area, progress bar, status/priority chips, and assignee.
929
+ Uses <code className="font-mono text-xs">Card</code>, <code className="font-mono text-xs">Chip</code>,{" "}
930
+ <code className="font-mono text-xs">ToggleButtonGroup</code>, <code className="font-mono text-xs">SearchBar</code>.
931
+ </Typography>
932
+ <div className="w-full"><CardViewDemo /></div>
933
+ </SectionBlock>
934
+
935
+ {/* ═══════════════════════════════════════════════
936
+ SECTION: Kanban Board
937
+ ═══════════════════════════════════════════════ */}
938
+ <SectionBlock id="kanban-board" title="Kanban Board">
939
+ <Typography variant="body2" color="secondary" className="mb-4">
940
+ Drag-and-drop kanban board with four status columns.
941
+ Uses <code className="font-mono text-xs">KanbanView</code>, <code className="font-mono text-xs">BoardItem</code>,{" "}
942
+ <code className="font-mono text-xs">BoardItemViewProps</code>.
943
+ </Typography>
944
+ <div className="w-full"><KanbanBoardDemo /></div>
945
+ </SectionBlock>
946
+ </div>
947
+ </div>
948
+ );
949
+ }
950
+
951
+ function SectionBlock({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {
952
+ return (
953
+ <section id={id} className={cls("px-6 py-8 border-b scroll-mt-0 max-w-5xl", defaultBorderMixin)}>
954
+ <Typography variant="h5" className="mb-1">{title}</Typography>
955
+ <div className="mt-4">{children}</div>
956
+ </section>
957
+ );
958
+ }