@devxcrew/react-ui 0.0.0-stage → 0.1.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 (326) hide show
  1. package/README.md +85 -2
  2. package/package.json +105 -4
  3. package/src/blocks/agent-chat-workspace/agent-chat-workspace.tsx +162 -0
  4. package/src/blocks/agent-chat-workspace/index.ts +2 -0
  5. package/src/blocks/agent-provider-settings/agent-provider-settings.tsx +183 -0
  6. package/src/blocks/agent-provider-settings/index.ts +2 -0
  7. package/src/blocks/agent-task-workspace/agent-task-workspace.tsx +48 -0
  8. package/src/blocks/agent-task-workspace/index.ts +2 -0
  9. package/src/blocks/analysis-context/analysis-context.tsx +6 -0
  10. package/src/blocks/analysis-context/index.ts +1 -0
  11. package/src/blocks/app-header/app-header.tsx +159 -0
  12. package/src/blocks/app-header/index.ts +2 -0
  13. package/src/blocks/archived-chat-workspace/archived-chat-workspace.tsx +29 -0
  14. package/src/blocks/archived-chat-workspace/index.ts +2 -0
  15. package/src/blocks/auth/README.md +32 -0
  16. package/src/blocks/auth/admin-login-page.tsx +15 -0
  17. package/src/blocks/auth/admin-password-forgot-page.tsx +5 -0
  18. package/src/blocks/auth/auth-page-layout.tsx +90 -0
  19. package/src/blocks/auth/client-login-page.tsx +20 -0
  20. package/src/blocks/auth/client-password-forgot-page.tsx +5 -0
  21. package/src/blocks/auth/identity-management-desk.tsx +530 -0
  22. package/src/blocks/auth/index.ts +12 -0
  23. package/src/blocks/auth/login-page.tsx +206 -0
  24. package/src/blocks/auth/password-forgot-page.tsx +60 -0
  25. package/src/blocks/auth/portal-pages.tsx +32 -0
  26. package/src/blocks/auth/privileged-desk.tsx +55 -0
  27. package/src/blocks/auth/register-page.tsx +117 -0
  28. package/src/blocks/auth/session-boundary.tsx +296 -0
  29. package/src/blocks/auth/super-admin-login-page.tsx +15 -0
  30. package/src/blocks/auth/super-admin-password-forgot-page.tsx +5 -0
  31. package/src/blocks/blog/blog-card.tsx +156 -0
  32. package/src/blocks/blog/blog-reader.tsx +175 -0
  33. package/src/blocks/blog/blog-types.ts +47 -0
  34. package/src/blocks/blog/index.ts +3 -0
  35. package/src/blocks/chat-composer/chat-composer.tsx +140 -0
  36. package/src/blocks/chat-composer/index.ts +1 -0
  37. package/src/blocks/chat-history/chat-history.tsx +59 -0
  38. package/src/blocks/chat-history/index.ts +1 -0
  39. package/src/blocks/chat-response-progress/chat-response-progress.tsx +34 -0
  40. package/src/blocks/chat-response-progress/index.ts +2 -0
  41. package/src/blocks/chat-runtime-controls/chat-runtime-controls.tsx +56 -0
  42. package/src/blocks/chat-runtime-controls/index.ts +2 -0
  43. package/src/blocks/chat-runtime-trace/chat-runtime-trace.tsx +71 -0
  44. package/src/blocks/chat-runtime-trace/index.ts +2 -0
  45. package/src/blocks/codex-connection-settings/codex-connection-settings.tsx +42 -0
  46. package/src/blocks/codex-connection-settings/index.ts +1 -0
  47. package/src/blocks/dropzone/dropzone-file-item.tsx +113 -0
  48. package/src/blocks/dropzone/dropzone-types.ts +32 -0
  49. package/src/blocks/dropzone/dropzone.tsx +216 -0
  50. package/src/blocks/dropzone/index.ts +3 -0
  51. package/src/blocks/ecommerce/cart/cart-drawer.tsx +228 -0
  52. package/src/blocks/ecommerce/cart/cart-types.ts +27 -0
  53. package/src/blocks/ecommerce/cart/index.ts +2 -0
  54. package/src/blocks/ecommerce/categories/categories-types.ts +23 -0
  55. package/src/blocks/ecommerce/categories/category-showcase.tsx +125 -0
  56. package/src/blocks/ecommerce/categories/index.ts +2 -0
  57. package/src/blocks/ecommerce/checkout/checkout-types.ts +48 -0
  58. package/src/blocks/ecommerce/checkout/checkout-wizard.tsx +468 -0
  59. package/src/blocks/ecommerce/checkout/index.ts +2 -0
  60. package/src/blocks/ecommerce/comparison/comparison-types.ts +28 -0
  61. package/src/blocks/ecommerce/comparison/index.ts +2 -0
  62. package/src/blocks/ecommerce/comparison/product-comparison.tsx +174 -0
  63. package/src/blocks/ecommerce/coupon-wallet/coupon-wallet-types.ts +21 -0
  64. package/src/blocks/ecommerce/coupon-wallet/coupon-wallet.tsx +154 -0
  65. package/src/blocks/ecommerce/coupon-wallet/index.ts +2 -0
  66. package/src/blocks/ecommerce/delivery-tracker/delivery-tracker-types.ts +20 -0
  67. package/src/blocks/ecommerce/delivery-tracker/delivery-tracker.tsx +169 -0
  68. package/src/blocks/ecommerce/delivery-tracker/index.ts +2 -0
  69. package/src/blocks/ecommerce/index.ts +12 -0
  70. package/src/blocks/ecommerce/payment-methods/index.ts +2 -0
  71. package/src/blocks/ecommerce/payment-methods/payment-method-selector.tsx +224 -0
  72. package/src/blocks/ecommerce/payment-methods/payment-methods-types.ts +21 -0
  73. package/src/blocks/ecommerce/price-history/index.ts +2 -0
  74. package/src/blocks/ecommerce/price-history/price-history-chart.tsx +217 -0
  75. package/src/blocks/ecommerce/price-history/price-history-types.ts +16 -0
  76. package/src/blocks/ecommerce/reviews/index.ts +2 -0
  77. package/src/blocks/ecommerce/reviews/reviews-section.tsx +309 -0
  78. package/src/blocks/ecommerce/reviews/reviews-types.ts +26 -0
  79. package/src/blocks/ecommerce/wishlist/index.ts +2 -0
  80. package/src/blocks/ecommerce/wishlist/wishlist-grid.tsx +149 -0
  81. package/src/blocks/ecommerce/wishlist/wishlist-types.ts +19 -0
  82. package/src/blocks/execution-status/README.md +25 -0
  83. package/src/blocks/execution-status/execution-status.tsx +135 -0
  84. package/src/blocks/execution-status/index.ts +2 -0
  85. package/src/blocks/file-tree/file-icons.tsx +84 -0
  86. package/src/blocks/file-tree/file-tree-node.tsx +158 -0
  87. package/src/blocks/file-tree/file-tree-types.ts +33 -0
  88. package/src/blocks/file-tree/file-tree.tsx +163 -0
  89. package/src/blocks/file-tree/index.ts +5 -0
  90. package/src/blocks/filter-builder/filter-builder.tsx +169 -0
  91. package/src/blocks/filter-builder/filter-row.tsx +164 -0
  92. package/src/blocks/filter-builder/filter-types.ts +61 -0
  93. package/src/blocks/filter-builder/index.ts +12 -0
  94. package/src/blocks/footer/footer-types.ts +35 -0
  95. package/src/blocks/footer/index.ts +2 -0
  96. package/src/blocks/footer/site-footer.tsx +212 -0
  97. package/src/blocks/form/form-block.tsx +113 -0
  98. package/src/blocks/form/form-lookup-field.tsx +60 -0
  99. package/src/blocks/form/index.ts +4 -0
  100. package/src/blocks/handover-stack/handover-stack.tsx +41 -0
  101. package/src/blocks/handover-stack/index.ts +1 -0
  102. package/src/blocks/idea-handover/idea-handover-readiness.ts +41 -0
  103. package/src/blocks/idea-handover/idea-handover-workspace.tsx +150 -0
  104. package/src/blocks/idea-handover/index.ts +4 -0
  105. package/src/blocks/kanban/index.ts +11 -0
  106. package/src/blocks/kanban/kanban-board.tsx +146 -0
  107. package/src/blocks/kanban/kanban-card.tsx +149 -0
  108. package/src/blocks/kanban/kanban-column.tsx +102 -0
  109. package/src/blocks/kanban/kanban-types.ts +38 -0
  110. package/src/blocks/loader/global-loader.tsx +90 -0
  111. package/src/blocks/loader/index.ts +1 -0
  112. package/src/blocks/mascot/README.md +21 -0
  113. package/src/blocks/mascot/index.ts +2 -0
  114. package/src/blocks/mascot/mascot.tsx +202 -0
  115. package/src/blocks/master-list/README.md +21 -0
  116. package/src/blocks/master-list/index.ts +12 -0
  117. package/src/blocks/master-list/master-form.tsx +157 -0
  118. package/src/blocks/master-list/master-list-desk.tsx +370 -0
  119. package/src/blocks/master-list/master-list.tsx +189 -0
  120. package/src/blocks/master-list/types.ts +18 -0
  121. package/src/blocks/mermaid-preview/index.ts +1 -0
  122. package/src/blocks/mermaid-preview/mermaid-preview.tsx +164 -0
  123. package/src/blocks/notifications/README.md +7 -0
  124. package/src/blocks/notifications/index.ts +1 -0
  125. package/src/blocks/notifications/notification-center-page.tsx +73 -0
  126. package/src/blocks/pricing/index.ts +7 -0
  127. package/src/blocks/pricing/pricing-table.tsx +173 -0
  128. package/src/blocks/pricing/pricing-types.ts +34 -0
  129. package/src/blocks/product-card/index.ts +2 -0
  130. package/src/blocks/product-card/product-card-types.ts +35 -0
  131. package/src/blocks/product-card/product-card.tsx +183 -0
  132. package/src/blocks/table/data-table-block.tsx +313 -0
  133. package/src/blocks/table/data-table-filter-menu.tsx +48 -0
  134. package/src/blocks/table/data-table-icon-menu-trigger.tsx +44 -0
  135. package/src/blocks/table/data-table-menu-content.tsx +32 -0
  136. package/src/blocks/table/data-table-pagination.tsx +149 -0
  137. package/src/blocks/table/data-table-row-actions.tsx +53 -0
  138. package/src/blocks/table/data-table-status.tsx +42 -0
  139. package/src/blocks/table/data-table-toolbar.tsx +124 -0
  140. package/src/blocks/table/data-table-totals.tsx +31 -0
  141. package/src/blocks/table/index.ts +13 -0
  142. package/src/blocks/workspace/index.ts +19 -0
  143. package/src/blocks/workspace/workspace-action-card.tsx +73 -0
  144. package/src/blocks/workspace/workspace-application-header.tsx +67 -0
  145. package/src/blocks/workspace/workspace-entity-card.tsx +48 -0
  146. package/src/blocks/workspace/workspace-health-summary.tsx +15 -0
  147. package/src/blocks/workspace/workspace-metric-card.tsx +97 -0
  148. package/src/blocks/workspace/workspace-page-header.tsx +43 -0
  149. package/src/blocks/workspace/workspace-publish-status.tsx +15 -0
  150. package/src/blocks/workspace/workspace-route-checklist.tsx +28 -0
  151. package/src/blocks/workspace/workspace-runtime-status.tsx +48 -0
  152. package/src/blocks/workspace/workspace-section-card.tsx +42 -0
  153. package/src/components/accordion.tsx +65 -0
  154. package/src/components/alert-dialog.tsx +160 -0
  155. package/src/components/alert.tsx +68 -0
  156. package/src/components/aspect-ratio.tsx +22 -0
  157. package/src/components/attachment.tsx +195 -0
  158. package/src/components/avatar.tsx +90 -0
  159. package/src/components/badge.tsx +55 -0
  160. package/src/components/breadcrumb.tsx +100 -0
  161. package/src/components/bubble.tsx +123 -0
  162. package/src/components/button-group.tsx +79 -0
  163. package/src/components/button.tsx +71 -0
  164. package/src/components/calendar.tsx +185 -0
  165. package/src/components/card.tsx +100 -0
  166. package/src/components/carousel.tsx +229 -0
  167. package/src/components/chart.tsx +338 -0
  168. package/src/components/checkbox.tsx +27 -0
  169. package/src/components/collapsible.tsx +15 -0
  170. package/src/components/combobox.tsx +269 -0
  171. package/src/components/command.tsx +181 -0
  172. package/src/components/compact-model-switcher.tsx +128 -0
  173. package/src/components/context-menu.tsx +244 -0
  174. package/src/components/dialog.tsx +138 -0
  175. package/src/components/direction.tsx +1 -0
  176. package/src/components/drawer.tsx +208 -0
  177. package/src/components/dropdown-menu.tsx +257 -0
  178. package/src/components/empty.tsx +93 -0
  179. package/src/components/field.tsx +232 -0
  180. package/src/components/hover-card.tsx +45 -0
  181. package/src/components/input-group.tsx +146 -0
  182. package/src/components/input-otp.tsx +83 -0
  183. package/src/components/input.tsx +19 -0
  184. package/src/components/item.tsx +188 -0
  185. package/src/components/kbd.tsx +26 -0
  186. package/src/components/label.tsx +17 -0
  187. package/src/components/markdown-content.tsx +113 -0
  188. package/src/components/marker.tsx +67 -0
  189. package/src/components/menubar.tsx +267 -0
  190. package/src/components/message-scroller.tsx +91 -0
  191. package/src/components/message.tsx +84 -0
  192. package/src/components/native-select.tsx +54 -0
  193. package/src/components/navigation-menu.tsx +160 -0
  194. package/src/components/pagination.tsx +118 -0
  195. package/src/components/popover.tsx +74 -0
  196. package/src/components/progress.tsx +82 -0
  197. package/src/components/questionnaire.tsx +150 -0
  198. package/src/components/radio-group.tsx +35 -0
  199. package/src/components/resizable.tsx +41 -0
  200. package/src/components/rich-text-editor.tsx +604 -0
  201. package/src/components/scroll-area.tsx +47 -0
  202. package/src/components/select.tsx +189 -0
  203. package/src/components/separator.tsx +18 -0
  204. package/src/components/sheet.tsx +125 -0
  205. package/src/components/sidebar.tsx +693 -0
  206. package/src/components/skeleton.tsx +13 -0
  207. package/src/components/slider.tsx +51 -0
  208. package/src/components/sonner.tsx +45 -0
  209. package/src/components/sparkline.tsx +231 -0
  210. package/src/components/spinner.tsx +20 -0
  211. package/src/components/status-badge.tsx +114 -0
  212. package/src/components/switch.tsx +31 -0
  213. package/src/components/table.tsx +91 -0
  214. package/src/components/tabs.tsx +72 -0
  215. package/src/components/textarea.tsx +17 -0
  216. package/src/components/toast.tsx +222 -0
  217. package/src/components/toggle-group.tsx +85 -0
  218. package/src/components/toggle.tsx +42 -0
  219. package/src/components/tooltip.tsx +53 -0
  220. package/src/design-system/README.md +55 -0
  221. package/src/design-system/action-intents.ts +21 -0
  222. package/src/design-system/agent-manifest.ts +83 -0
  223. package/src/design-system/block-registry.ts +272 -0
  224. package/src/design-system/component-registry.ts +142 -0
  225. package/src/design-system/contracts.ts +69 -0
  226. package/src/design-system/defaults.ts +3 -0
  227. package/src/design-system/index.ts +29 -0
  228. package/src/design-system/mcp-server.ts +156 -0
  229. package/src/design-system/page-registry.ts +74 -0
  230. package/src/design-system/selection.ts +67 -0
  231. package/src/design-system/template-registry.ts +33 -0
  232. package/src/features/interface-topology/index.ts +14 -0
  233. package/src/features/interface-topology/interface-topology.types.ts +40 -0
  234. package/src/features/interface-topology/topology-control.tsx +18 -0
  235. package/src/features/interface-topology/topology-inspector.tsx +228 -0
  236. package/src/features/interface-topology/topology-marker.tsx +47 -0
  237. package/src/features/interface-topology/topology-region.tsx +44 -0
  238. package/src/features/interface-topology/use-interface-topology.ts +178 -0
  239. package/src/hooks/use-mobile.ts +19 -0
  240. package/src/hooks/use-scroll-follow.ts +22 -0
  241. package/src/index.ts +11 -0
  242. package/src/layouts/README.md +65 -0
  243. package/src/layouts/agent-workspace/agent-activity-rail.tsx +101 -0
  244. package/src/layouts/agent-workspace/agent-workspace.tsx +27 -0
  245. package/src/layouts/agent-workspace/agent-workspace.types.ts +28 -0
  246. package/src/layouts/agent-workspace/index.ts +7 -0
  247. package/src/layouts/blog-header/blog-header-types.ts +25 -0
  248. package/src/layouts/blog-header/blog-header.tsx +172 -0
  249. package/src/layouts/blog-header/index.ts +2 -0
  250. package/src/layouts/documentation-workspace/README.md +8 -0
  251. package/src/layouts/documentation-workspace/documentation-workspace.tsx +34 -0
  252. package/src/layouts/documentation-workspace/index.ts +1 -0
  253. package/src/layouts/ecommerce-header/ecommerce-actions.tsx +89 -0
  254. package/src/layouts/ecommerce-header/ecommerce-announcement.tsx +43 -0
  255. package/src/layouts/ecommerce-header/ecommerce-drawer.tsx +97 -0
  256. package/src/layouts/ecommerce-header/ecommerce-header-types.ts +59 -0
  257. package/src/layouts/ecommerce-header/ecommerce-header.tsx +47 -0
  258. package/src/layouts/ecommerce-header/ecommerce-navigation.tsx +98 -0
  259. package/src/layouts/ecommerce-header/ecommerce-search.tsx +86 -0
  260. package/src/layouts/ecommerce-header/index.ts +2 -0
  261. package/src/layouts/main-workspace/index.ts +28 -0
  262. package/src/layouts/mdi/index.ts +1 -0
  263. package/src/layouts/mdi/mdi.tsx +20 -0
  264. package/src/layouts/mdi-main/index.ts +27 -0
  265. package/src/layouts/mdi-main/mdi-app-catalog.generated.ts +159 -0
  266. package/src/layouts/mdi-main/mdi-app-catalog.ts +76 -0
  267. package/src/layouts/mdi-main/mdi-app-switcher.tsx +107 -0
  268. package/src/layouts/mdi-main/mdi-feature-settings.tsx +135 -0
  269. package/src/layouts/mdi-main/mdi-global-search.tsx +192 -0
  270. package/src/layouts/mdi-main/mdi-main.tsx +241 -0
  271. package/src/layouts/mdi-main/mdi-notifications-menu.tsx +197 -0
  272. package/src/layouts/mdi-main/mdi-profile-menu.tsx +79 -0
  273. package/src/layouts/mdi-main/mdi-sidebar-navigation.tsx +226 -0
  274. package/src/layouts/mdi-main/mdi-sidebar.tsx +110 -0
  275. package/src/layouts/mdi-main/mdi-status-bar.tsx +26 -0
  276. package/src/layouts/mdi-main/mdi-top-menu-control.ts +4 -0
  277. package/src/layouts/mdi-main/mdi-top-menu.tsx +117 -0
  278. package/src/layouts/mdi-main/mdi-topology.tsx +297 -0
  279. package/src/layouts/mdi-main/mdi-tweak-panel.tsx +104 -0
  280. package/src/layouts/mdi-main/mdi-types.ts +131 -0
  281. package/src/layouts/mdi-main/use-mdi-features.ts +36 -0
  282. package/src/layouts/mdi-main/use-mdi-sidebar-state.ts +59 -0
  283. package/src/layouts/site-header/announcement-bar.tsx +55 -0
  284. package/src/layouts/site-header/category-strip.tsx +41 -0
  285. package/src/layouts/site-header/index.ts +16 -0
  286. package/src/layouts/site-header/main-navbar.tsx +179 -0
  287. package/src/layouts/site-header/mobile-drawer.tsx +140 -0
  288. package/src/layouts/site-header/site-header-types.ts +63 -0
  289. package/src/layouts/site-header/site-header.tsx +58 -0
  290. package/src/lib/random-id.ts +19 -0
  291. package/src/lib/utils.ts +6 -0
  292. package/src/providers/pdf-provider.ts +137 -0
  293. package/src/styles/globals.css +374 -0
  294. package/src/templates/README.md +12 -0
  295. package/src/templates/dashboard-01/components/app-sidebar.tsx +177 -0
  296. package/src/templates/dashboard-01/components/chart-area-interactive.tsx +276 -0
  297. package/src/templates/dashboard-01/components/data-table-cell-viewer.tsx +213 -0
  298. package/src/templates/dashboard-01/components/data-table.tsx +577 -0
  299. package/src/templates/dashboard-01/components/nav-documents.tsx +79 -0
  300. package/src/templates/dashboard-01/components/nav-main.tsx +55 -0
  301. package/src/templates/dashboard-01/components/nav-secondary.tsx +39 -0
  302. package/src/templates/dashboard-01/components/nav-user.tsx +97 -0
  303. package/src/templates/dashboard-01/components/section-cards.tsx +99 -0
  304. package/src/templates/dashboard-01/components/site-header.tsx +14 -0
  305. package/src/templates/dashboard-01/data.json +614 -0
  306. package/src/templates/dashboard-01/index.ts +7 -0
  307. package/src/templates/documentation-sidebar/app-sidebar.tsx +95 -0
  308. package/src/templates/documentation-sidebar/index.ts +2 -0
  309. package/src/templates/sidebar-07/components/app-sidebar.tsx +175 -0
  310. package/src/templates/sidebar-07/components/nav-main.tsx +64 -0
  311. package/src/templates/sidebar-07/components/nav-projects.tsx +79 -0
  312. package/src/templates/sidebar-07/components/nav-user.tsx +105 -0
  313. package/src/templates/sidebar-07/components/team-switcher.tsx +94 -0
  314. package/src/templates/sidebar-07/index.ts +1 -0
  315. package/src/templates/ui-page/index.ts +7 -0
  316. package/src/templates/ui-page/ui-browser-frame.tsx +27 -0
  317. package/src/templates/ui-page/ui-template-code.tsx +48 -0
  318. package/src/templates/ui-page/ui-template-header.tsx +87 -0
  319. package/src/templates/ui-page/ui-template-navigation.tsx +60 -0
  320. package/src/templates/ui-page/ui-template-page.tsx +97 -0
  321. package/src/theme/index.ts +12 -0
  322. package/src/theme/theme-config.ts +30 -0
  323. package/src/theme/theme-provider.tsx +142 -0
  324. package/src/theme/theme-selector.tsx +75 -0
  325. package/src/tokens/index.ts +15 -0
  326. package/src/vite-env.d.ts +3 -0
@@ -0,0 +1,74 @@
1
+ import type { DesignSystemPageDefinition } from './contracts'
2
+
3
+ export const designSystemPages: readonly DesignSystemPageDefinition[] = [
4
+ {
5
+ defaultVariantId: 'v1',
6
+ description: 'A presentation-only sign-in page with application-owned authentication.',
7
+ id: 'login',
8
+ name: 'Login',
9
+ source: '@devxcrew/react-ui/blocks/auth',
10
+ variants: [
11
+ {
12
+ description: 'Centered CODEXSUN sign-in card for focused application entry.',
13
+ id: 'v1',
14
+ name: 'Login v1',
15
+ },
16
+ {
17
+ description: 'Split sign-in card with provider actions and a supporting visual panel.',
18
+ id: 'v2',
19
+ name: 'Login v2',
20
+ },
21
+ ],
22
+ },
23
+ {
24
+ defaultVariantId: 'v1',
25
+ description: 'A presentation-only account registration page.',
26
+ id: 'register',
27
+ name: 'Register',
28
+ source: '@devxcrew/react-ui/blocks/auth',
29
+ variants: [
30
+ {
31
+ description: 'Centered registration card for the standard account flow.',
32
+ id: 'v1',
33
+ name: 'Register v1',
34
+ },
35
+ {
36
+ description: 'Split registration page with workspace onboarding context.',
37
+ id: 'v2',
38
+ name: 'Register v2',
39
+ },
40
+ ],
41
+ },
42
+ {
43
+ defaultVariantId: 'default',
44
+ description: 'A focused account-recovery page that does not disclose account existence.',
45
+ id: 'forgot-password',
46
+ name: 'Forgot Password',
47
+ source: '@devxcrew/react-ui/blocks/auth',
48
+ variants: [
49
+ {
50
+ description: 'The package-owned account recovery page.',
51
+ id: 'default',
52
+ name: 'Forgot Password',
53
+ },
54
+ ],
55
+ },
56
+ {
57
+ defaultVariantId: 'default',
58
+ description: 'A full-page notification inbox with application-owned records and actions.',
59
+ id: 'notifications',
60
+ name: 'Notifications Page',
61
+ source: '@devxcrew/react-ui/blocks/notifications',
62
+ variants: [
63
+ {
64
+ description: 'The package-owned notification inbox page.',
65
+ id: 'default',
66
+ name: 'Notifications Page',
67
+ },
68
+ ],
69
+ },
70
+ ]
71
+
72
+ export function getDesignSystemPage(pageId: string) {
73
+ return designSystemPages.find(({ id }) => id === pageId)
74
+ }
@@ -0,0 +1,67 @@
1
+ import { designSystemBlocks, getDesignSystemBlock } from "./block-registry";
2
+ import { designSystemComponents, getDesignSystemComponent } from "./component-registry";
3
+ import { designSystemPages, getDesignSystemPage } from "./page-registry";
4
+ import { designSystemTemplates, getDesignSystemTemplate } from "./template-registry";
5
+ import type { DesignSystemSelection, DesignSystemSelectionInput } from "./contracts";
6
+
7
+ export const defaultDesignSystemSelection = createDesignSystemSelection();
8
+
9
+ export function createDesignSystemSelection(input: DesignSystemSelectionInput = {}): DesignSystemSelection {
10
+ return Object.freeze({
11
+ blocks: Object.freeze(resolveSelections(designSystemBlocks, input.blocks)),
12
+ components: Object.freeze(resolveSelections(designSystemComponents, input.components)),
13
+ pages: Object.freeze(resolveSelections(designSystemPages, input.pages)),
14
+ templates: Object.freeze(resolveSelections(designSystemTemplates, input.templates)),
15
+ });
16
+ }
17
+
18
+ export function resolveDesignSystemComponentVariant(componentId: string, requestedVariantId?: string) {
19
+ const component = getDesignSystemComponent(componentId);
20
+ if (!component) throw new Error(`Unknown design-system component: ${componentId}`);
21
+ return resolveVariant(component, requestedVariantId);
22
+ }
23
+
24
+ export function resolveDesignSystemBlockVariant(blockId: string, requestedVariantId?: string) {
25
+ const block = getDesignSystemBlock(blockId);
26
+ if (!block) throw new Error(`Unknown design-system block: ${blockId}`);
27
+ return resolveVariant(block, requestedVariantId);
28
+ }
29
+
30
+ export function resolveDesignSystemPageVariant(pageId: string, requestedVariantId?: string) {
31
+ const page = getDesignSystemPage(pageId);
32
+ if (!page) throw new Error(`Unknown design-system page: ${pageId}`);
33
+ return resolveVariant(page, requestedVariantId);
34
+ }
35
+
36
+ export function resolveDesignSystemTemplateVariant(templateId: string, requestedVariantId?: string) {
37
+ const template = getDesignSystemTemplate(templateId);
38
+ if (!template) throw new Error(`Unknown design-system template: ${templateId}`);
39
+ return resolveVariant(template, requestedVariantId);
40
+ }
41
+
42
+ type VariantOwner = {
43
+ defaultVariantId: string;
44
+ id: string;
45
+ variants: readonly { id: string }[];
46
+ };
47
+
48
+ function resolveSelections(definitions: readonly VariantOwner[], requested: Readonly<Record<string, string>> = {}) {
49
+ rejectUnknownKeys(definitions, requested);
50
+ return Object.fromEntries(
51
+ definitions.map((definition) => [definition.id, resolveVariant(definition, requested[definition.id])]),
52
+ );
53
+ }
54
+
55
+ function resolveVariant(definition: VariantOwner, requestedVariantId?: string) {
56
+ const variantId = requestedVariantId ?? definition.defaultVariantId;
57
+ if (!definition.variants.some(({ id }) => id === variantId)) {
58
+ throw new Error(`Unknown ${definition.id} variant: ${variantId}`);
59
+ }
60
+ return variantId;
61
+ }
62
+
63
+ function rejectUnknownKeys(definitions: readonly VariantOwner[], requested: Readonly<Record<string, string>>) {
64
+ const knownIds = new Set(definitions.map(({ id }) => id));
65
+ const unknownId = Object.keys(requested).find((id) => !knownIds.has(id));
66
+ if (unknownId) throw new Error(`Unknown design-system selection: ${unknownId}`);
67
+ }
@@ -0,0 +1,33 @@
1
+ import type { DesignSystemTemplateDefinition } from "./contracts";
2
+
3
+ export const designSystemTemplates: readonly DesignSystemTemplateDefinition[] = [
4
+ {
5
+ defaultVariantId: "v1",
6
+ description: "A configurable master-data list with table and card views plus a generated record form.",
7
+ id: "master-list",
8
+ name: "Master List",
9
+ source: "@devxcrew/react-ui/blocks/master-list",
10
+ variants: [
11
+ { id: "v1", name: "Master List v1", description: "A table-first master list page." },
12
+ { id: "v2", name: "Master List v2", description: "A dense Desk-style list with quick filters and row activity." },
13
+ { id: "v3", name: "Master List v3", description: "A dense Desk-style master list page." },
14
+ {
15
+ id: "v4",
16
+ name: "Master List v4",
17
+ description: "A full-width application header with a centered master-data table.",
18
+ },
19
+ ],
20
+ },
21
+ {
22
+ defaultVariantId: "default",
23
+ description: "A compact status system with semantic colors and a check mark for record states.",
24
+ id: "status",
25
+ name: "Status Template",
26
+ source: "@devxcrew/react-ui/components/status-badge",
27
+ variants: [{ id: "default", name: "Status", description: "Standard colored status badges for record lists." }],
28
+ },
29
+ ];
30
+
31
+ export function getDesignSystemTemplate(id: string) {
32
+ return designSystemTemplates.find((template) => template.id === id);
33
+ }
@@ -0,0 +1,14 @@
1
+ export type {
2
+ InterfaceTopologyController,
3
+ InterfaceTopologyDesk,
4
+ InterfaceTopologySection,
5
+ } from './interface-topology.types'
6
+ export { TopologyInspectionControl } from './topology-control'
7
+ export { TopologyInspector } from './topology-inspector'
8
+ export { TopologyMarker } from './topology-marker'
9
+ export { TopologyRegion } from './topology-region'
10
+ export { useInterfaceTopology } from './use-interface-topology'
11
+ export {
12
+ validateInterfaceTopologyDesks,
13
+ validateInterfaceTopologySections,
14
+ } from './use-interface-topology'
@@ -0,0 +1,40 @@
1
+ export type InterfaceTopologySection = {
2
+ description: string;
3
+ id: string;
4
+ name: string;
5
+ scope: string;
6
+ technicalName: string;
7
+ };
8
+
9
+ export type InterfaceTopologyDesk = {
10
+ id: string;
11
+ name: string;
12
+ sections: readonly InterfaceTopologySection[];
13
+ };
14
+
15
+ export type InterfaceTopologyRegionProps = {
16
+ 'data-ito-highlighted': boolean;
17
+ 'data-ito-section': string;
18
+ };
19
+
20
+ export type InterfaceTopologyController = {
21
+ activeDeskId: string;
22
+ allSections: readonly InterfaceTopologySection[];
23
+ close: () => void;
24
+ copyTechnicalName: (id: string) => void;
25
+ desks: readonly InterfaceTopologyDesk[];
26
+ highlightClassName: (id: string) => string;
27
+ inspect: (id: string) => void;
28
+ labelsVisible: boolean;
29
+ open: boolean;
30
+ regionProps: (id: string) => InterfaceTopologyRegionProps;
31
+ sections: readonly InterfaceTopologySection[];
32
+ selected: string;
33
+ select: (id: string) => void;
34
+ selectDesk: (id: string) => void;
35
+ setScope: (rootId: string | null) => void;
36
+ toggleHighlight: () => void;
37
+ toggleLabels: () => void;
38
+ toggleOpen: () => void;
39
+ highlighting: boolean;
40
+ };
@@ -0,0 +1,18 @@
1
+ import { Tags } from 'lucide-react';
2
+ import type { InterfaceTopologyController } from './interface-topology.types';
3
+
4
+ export function TopologyInspectionControl({ topology }: { topology: InterfaceTopologyController }) {
5
+ const action = topology.open ? 'Close Topology Inspection' : 'Open Topology Inspection';
6
+ return (
7
+ <button
8
+ aria-label={action}
9
+ className="pointer-events-auto absolute right-4 bottom-8 z-10 grid size-9 cursor-pointer place-items-center rounded-md border border-border bg-white text-violet-700 shadow-sm transition hover:bg-violet-50 hover:text-violet-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 data-[open=true]:bg-violet-100"
10
+ data-open={topology.open}
11
+ onClick={topology.toggleOpen}
12
+ title={action}
13
+ type="button"
14
+ >
15
+ <Tags aria-hidden="true" size={16} />
16
+ </button>
17
+ );
18
+ }
@@ -0,0 +1,228 @@
1
+ import { Check, ChevronRight, Copy, Eye, EyeOff, Highlighter, X } from 'lucide-react';
2
+ import { useEffect, useState } from 'react';
3
+ import {
4
+ Select,
5
+ SelectContent,
6
+ SelectGroup,
7
+ SelectItem,
8
+ SelectTrigger,
9
+ SelectValue,
10
+ } from '@devxcrew/react-ui/components/select';
11
+ import type { InterfaceTopologyController, InterfaceTopologySection } from './interface-topology.types';
12
+
13
+ export function TopologyInspector({ topology }: { topology: InterfaceTopologyController }) {
14
+ if (!topology.open) return null;
15
+ const selected = topology.sections.find(({ id }) => id === topology.selected) ?? topology.sections[0];
16
+ if (!selected) return null;
17
+
18
+ return (
19
+ <aside
20
+ aria-label="Interface Topology Overlay"
21
+ className="pointer-events-auto absolute top-4 right-14 bottom-20 flex w-88 max-w-[calc(100vw-4.5rem)] flex-col overflow-hidden rounded-xl border border-border bg-white text-neutral-950 shadow-xl"
22
+ >
23
+ <InspectorHeader topology={topology} />
24
+ <SelectedSectionDetails section={selected} topology={topology} />
25
+ <nav
26
+ aria-label="Topology sections"
27
+ className="min-h-0 flex-1 overflow-y-auto px-2 py-2 [scrollbar-color:#a78bfa_transparent] [scrollbar-width:thin] [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-violet-400 [&::-webkit-scrollbar]:w-1"
28
+ >
29
+ {topology.sections
30
+ .filter((section) => isRootSection(section, topology.sections))
31
+ .map((section) => (
32
+ <TopologyGroup key={section.id} section={section} topology={topology} />
33
+ ))}
34
+ </nav>
35
+ </aside>
36
+ );
37
+ }
38
+
39
+ function SelectedSectionDetails({
40
+ section,
41
+ topology,
42
+ }: {
43
+ section: InterfaceTopologySection;
44
+ topology: InterfaceTopologyController;
45
+ }) {
46
+ const [copied, setCopied] = useState(false);
47
+
48
+ useEffect(() => setCopied(false), [section.id]);
49
+ useEffect(() => {
50
+ if (!copied) return;
51
+ const timer = window.setTimeout(() => setCopied(false), 1_500);
52
+ return () => window.clearTimeout(timer);
53
+ }, [copied]);
54
+
55
+ return (
56
+ <div className="border-b border-border px-3 py-3">
57
+ <strong className="block truncate text-sm">
58
+ {section.id} · {section.name}
59
+ </strong>
60
+ <button
61
+ aria-label={`Copy ${section.technicalName}`}
62
+ className="mt-1 flex w-full cursor-pointer items-center gap-2 rounded-md py-1 text-left text-violet-700 transition hover:bg-violet-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-500"
63
+ onClick={() => {
64
+ topology.copyTechnicalName(section.id);
65
+ setCopied(true);
66
+ }}
67
+ title="Copy technical name"
68
+ type="button"
69
+ >
70
+ <code className="min-w-0 flex-1 break-all text-xs font-bold">{section.technicalName}</code>
71
+ {copied ? <Check aria-hidden="true" size={15} /> : <Copy aria-hidden="true" size={15} />}
72
+ <span className="sr-only" aria-live="polite">
73
+ {copied ? 'Copied' : ''}
74
+ </span>
75
+ </button>
76
+ </div>
77
+ );
78
+ }
79
+
80
+ function InspectorHeader({ topology }: { topology: InterfaceTopologyController }) {
81
+ return (
82
+ <header className="flex items-center gap-2 border-b border-border p-3">
83
+ {topology.desks.length > 1 ? (
84
+ <Select
85
+ items={topology.desks.map((desk) => ({ label: desk.name, value: desk.id }))}
86
+ onValueChange={(value) => {
87
+ if (value) topology.selectDesk(value);
88
+ }}
89
+ value={topology.activeDeskId}
90
+ >
91
+ <SelectTrigger aria-label="Select topology desk" className="min-w-0 flex-1" size="sm">
92
+ <SelectValue />
93
+ </SelectTrigger>
94
+ <SelectContent align="start">
95
+ <SelectGroup>
96
+ {topology.desks.map((desk) => (
97
+ <SelectItem key={desk.id} value={desk.id}>
98
+ {desk.name}
99
+ </SelectItem>
100
+ ))}
101
+ </SelectGroup>
102
+ </SelectContent>
103
+ </Select>
104
+ ) : (
105
+ <span className="flex-1" />
106
+ )}
107
+ <div className="flex shrink-0 items-center gap-1">
108
+ <HeaderAction
109
+ active={topology.labelsVisible}
110
+ label={topology.labelsVisible ? 'Hide ITO labels' : 'Show ITO labels'}
111
+ onClick={topology.toggleLabels}
112
+ >
113
+ {topology.labelsVisible ? <Eye size={16} /> : <EyeOff size={16} />}
114
+ </HeaderAction>
115
+ <HeaderAction
116
+ active={topology.highlighting}
117
+ label="Toggle boundary highlighter"
118
+ onClick={topology.toggleHighlight}
119
+ >
120
+ <Highlighter size={16} />
121
+ </HeaderAction>
122
+ <HeaderAction label="Close Topology Inspection" onClick={topology.close}>
123
+ <X size={16} />
124
+ </HeaderAction>
125
+ </div>
126
+ </header>
127
+ );
128
+ }
129
+
130
+ function HeaderAction({
131
+ active = false,
132
+ children,
133
+ label,
134
+ onClick,
135
+ }: {
136
+ active?: boolean;
137
+ children: React.ReactNode;
138
+ label: string;
139
+ onClick: () => void;
140
+ }) {
141
+ return (
142
+ <button
143
+ aria-label={label}
144
+ aria-pressed={active}
145
+ className="grid size-8 cursor-pointer place-items-center rounded-md text-neutral-600 transition hover:bg-neutral-100 hover:text-neutral-950 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 data-[active=true]:bg-violet-700 data-[active=true]:text-white"
146
+ data-active={active}
147
+ onClick={onClick}
148
+ title={label}
149
+ type="button"
150
+ >
151
+ {children}
152
+ </button>
153
+ );
154
+ }
155
+
156
+ function TopologyGroup({
157
+ section,
158
+ topology,
159
+ }: {
160
+ section: InterfaceTopologySection;
161
+ topology: InterfaceTopologyController;
162
+ }) {
163
+ const [collapsed, setCollapsed] = useState(false);
164
+ const children = topology.sections.filter(
165
+ ({ id }) => id.includes('.') && id.slice(0, id.lastIndexOf('.')) === section.id,
166
+ );
167
+ const selected = topology.selected === section.id;
168
+ const scopedToCurrentRegion = topology.sections.length < topology.allSections.length;
169
+ const expanded =
170
+ !collapsed &&
171
+ (scopedToCurrentRegion || (topology.highlighting && (selected || topology.selected.startsWith(`${section.id}.`))));
172
+ useEffect(() => setCollapsed(false), [topology.highlighting, topology.selected]);
173
+
174
+ return (
175
+ <div>
176
+ <div className="flex items-center gap-1">
177
+ <button
178
+ aria-expanded={children.length ? expanded : undefined}
179
+ className="grid min-w-0 flex-1 cursor-pointer grid-cols-[auto_1fr_auto] items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm text-neutral-600 transition hover:bg-neutral-100 hover:text-neutral-950 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 data-[selected=true]:bg-neutral-200 data-[selected=true]:text-violet-800"
180
+ data-selected={selected}
181
+ onClick={() => {
182
+ if (children.length && expanded) setCollapsed(true);
183
+ else {
184
+ setCollapsed(false);
185
+ topology.inspect(section.id);
186
+ }
187
+ }}
188
+ title={`Inspect ${section.technicalName}`}
189
+ type="button"
190
+ >
191
+ <b className="min-w-7 rounded bg-violet-700 px-1.5 py-1 text-center text-xs text-white">{section.id}</b>
192
+ <span className="truncate">{section.name}</span>
193
+ {children.length ? (
194
+ <ChevronRight className={expanded ? 'rotate-90' : ''} size={15} />
195
+ ) : selected ? (
196
+ <Check size={15} />
197
+ ) : null}
198
+ </button>
199
+ <button
200
+ aria-label={`Copy ${section.technicalName}`}
201
+ className="grid size-8 shrink-0 cursor-pointer place-items-center rounded-md text-violet-700 transition hover:bg-violet-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-500"
202
+ onClick={(event) => {
203
+ event.stopPropagation();
204
+ topology.copyTechnicalName(section.id);
205
+ }}
206
+ onPointerDown={(event) => event.stopPropagation()}
207
+ title={`Copy ${section.technicalName}`}
208
+ type="button"
209
+ >
210
+ <Copy aria-hidden="true" size={14} />
211
+ </button>
212
+ </div>
213
+ {expanded ? (
214
+ <div className="ml-4 border-l border-border pl-1">
215
+ {children.map((child) => (
216
+ <TopologyGroup key={child.id} section={child} topology={topology} />
217
+ ))}
218
+ </div>
219
+ ) : null}
220
+ </div>
221
+ );
222
+ }
223
+
224
+ function isRootSection(section: InterfaceTopologySection, sections: readonly InterfaceTopologySection[]) {
225
+ if (!section.id.includes('.')) return true;
226
+ const parentId = section.id.slice(0, section.id.lastIndexOf('.'));
227
+ return !sections.some((candidate) => candidate.id === parentId);
228
+ }
@@ -0,0 +1,47 @@
1
+ import type { CSSProperties } from 'react';
2
+ import type { InterfaceTopologyController } from './interface-topology.types';
3
+
4
+ const itoAccent = 'hsl(265 85% 52% / 0.9)';
5
+ const itoAccentSoft = 'hsl(265 92% 94% / 0.95)';
6
+
7
+ export function TopologyMarker({ id, topology }: { id: string; topology: InterfaceTopologyController }) {
8
+ const section = topology.sections.find((candidate) => candidate.id === id);
9
+ if (!section || !topology.labelsVisible || !isLabelVisible(id, topology)) return null;
10
+ const selected = topology.open && topology.selected === id;
11
+ const isBanner = !id.includes('.');
12
+ const style = {
13
+ '--ito-sticker': itoAccent,
14
+ '--ito-sticker-soft': itoAccentSoft,
15
+ } as CSSProperties;
16
+
17
+ return (
18
+ <button
19
+ aria-label={`Inspect ${section.name}: ${section.technicalName}`}
20
+ className="absolute top-2 left-2 z-30 flex min-h-6 min-w-7 max-w-48 cursor-pointer items-center justify-center gap-1.5 rounded-md border border-white/60 bg-[var(--ito-sticker-soft)] px-1.5 text-xs font-extrabold text-[var(--ito-sticker)] shadow-lg backdrop-blur-md transition hover:-translate-y-0.5 hover:bg-[var(--ito-sticker)] hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[selected=true]:bg-[var(--ito-sticker)] data-[selected=true]:text-white"
21
+ data-ito-marker={id}
22
+ data-selected={selected}
23
+ onClick={(event) => {
24
+ event.preventDefault();
25
+ event.stopPropagation();
26
+ topology.inspect(id);
27
+ }}
28
+ onPointerDown={(event) => event.stopPropagation()}
29
+ style={style}
30
+ title={`${id} · ${section.name} · ${section.technicalName}`}
31
+ type="button"
32
+ >
33
+ <span>{displayId(id)}</span>
34
+ {isBanner && <span className="truncate font-semibold">{section.name}</span>}
35
+ </button>
36
+ );
37
+ }
38
+
39
+ function displayId(id: string) {
40
+ return id.replace(/^[a-z]+/i, '').padStart(2, '0');
41
+ }
42
+
43
+ function isLabelVisible(id: string, topology: InterfaceTopologyController) {
44
+ if (!id.includes('.')) return true;
45
+ if (!topology.highlighting) return false;
46
+ return id === topology.selected || id.slice(0, id.lastIndexOf('.')) === topology.selected;
47
+ }
@@ -0,0 +1,44 @@
1
+ import type { CSSProperties, ElementType, HTMLAttributes, ReactNode } from 'react';
2
+ import { cn } from '../../lib/utils';
3
+ import type { InterfaceTopologyController } from './interface-topology.types';
4
+ import { TopologyMarker } from './topology-marker';
5
+
6
+ export function TopologyRegion({
7
+ as: Component = 'section',
8
+ children,
9
+ className,
10
+ id,
11
+ topology,
12
+ ...props
13
+ }: Omit<HTMLAttributes<HTMLElement>, 'id'> & {
14
+ as?: ElementType;
15
+ children: ReactNode;
16
+ className?: string;
17
+ id: string;
18
+ topology: InterfaceTopologyController;
19
+ }) {
20
+ const regionProps = topology.regionProps(id);
21
+ const highlighted = regionProps['data-ito-highlighted'];
22
+ const style = {
23
+ ...props.style,
24
+ '--ito-sticker': 'hsl(265 85% 52% / 0.9)',
25
+ } as CSSProperties;
26
+
27
+ return (
28
+ <Component
29
+ className={cn('relative data-[ito-highlighted=true]:z-20', className)}
30
+ {...props}
31
+ {...regionProps}
32
+ style={style}
33
+ >
34
+ <TopologyMarker id={id} topology={topology} />
35
+ {children}
36
+ {highlighted ? (
37
+ <span
38
+ aria-hidden="true"
39
+ className="pointer-events-none absolute inset-0 z-40 rounded-[inherit] border-2 border-[var(--ito-sticker)]"
40
+ />
41
+ ) : null}
42
+ </Component>
43
+ );
44
+ }