@actuate-media/cms-admin 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/dist/AdminRoot.d.ts.map +1 -1
  2. package/dist/AdminRoot.js +8 -5
  3. package/dist/AdminRoot.js.map +1 -1
  4. package/dist/__tests__/layout/primitives.test.d.ts +2 -0
  5. package/dist/__tests__/layout/primitives.test.d.ts.map +1 -0
  6. package/dist/__tests__/layout/primitives.test.js +34 -0
  7. package/dist/__tests__/layout/primitives.test.js.map +1 -0
  8. package/dist/__tests__/lib/cv.test.d.ts +2 -0
  9. package/dist/__tests__/lib/cv.test.d.ts.map +1 -0
  10. package/dist/__tests__/lib/cv.test.js +66 -0
  11. package/dist/__tests__/lib/cv.test.js.map +1 -0
  12. package/dist/actuate-admin.css +1 -1
  13. package/dist/assets/actuate-logo.d.ts +36 -0
  14. package/dist/assets/actuate-logo.d.ts.map +1 -0
  15. package/dist/assets/actuate-logo.js +15 -0
  16. package/dist/assets/actuate-logo.js.map +1 -0
  17. package/dist/components/Breadcrumbs.js +2 -2
  18. package/dist/components/CommandPalette.js +10 -10
  19. package/dist/components/ContentOverviewChart.js +3 -3
  20. package/dist/components/ErrorBoundary.js +1 -1
  21. package/dist/components/FocalPointPicker.js +2 -2
  22. package/dist/components/FolderTree.js +20 -20
  23. package/dist/components/LivePreview.js +3 -3
  24. package/dist/components/LocaleSwitcher.js +1 -1
  25. package/dist/components/MediaPickerModal.js +4 -4
  26. package/dist/components/PresenceIndicator.js +1 -1
  27. package/dist/components/SEOConfigPanel.d.ts +2 -0
  28. package/dist/components/SEOConfigPanel.d.ts.map +1 -0
  29. package/dist/components/SEOConfigPanel.js +174 -0
  30. package/dist/components/SEOConfigPanel.js.map +1 -0
  31. package/dist/components/SEOPanel.js +9 -9
  32. package/dist/components/SEOPerformance.js +2 -2
  33. package/dist/components/SchedulePublishDialog.js +1 -1
  34. package/dist/components/SharePreviewLinkDialog.js +1 -1
  35. package/dist/components/TipTapEditor.js +5 -5
  36. package/dist/components/VersionHistory.js +2 -2
  37. package/dist/components/ui/Badge.d.ts +33 -3
  38. package/dist/components/ui/Badge.d.ts.map +1 -1
  39. package/dist/components/ui/Badge.js +42 -8
  40. package/dist/components/ui/Badge.js.map +1 -1
  41. package/dist/components/ui/Button.d.ts +19 -8
  42. package/dist/components/ui/Button.d.ts.map +1 -1
  43. package/dist/components/ui/Button.js +35 -14
  44. package/dist/components/ui/Button.js.map +1 -1
  45. package/dist/components/ui/Card.d.ts +26 -0
  46. package/dist/components/ui/Card.d.ts.map +1 -0
  47. package/dist/components/ui/Card.js +45 -0
  48. package/dist/components/ui/Card.js.map +1 -0
  49. package/dist/components/ui/DataTable.js +1 -1
  50. package/dist/components/ui/Input.d.ts +15 -0
  51. package/dist/components/ui/Input.d.ts.map +1 -0
  52. package/dist/components/ui/Input.js +23 -0
  53. package/dist/components/ui/Input.js.map +1 -0
  54. package/dist/components/ui/SearchInput.js +1 -1
  55. package/dist/components/ui/Select.d.ts +16 -0
  56. package/dist/components/ui/Select.d.ts.map +1 -0
  57. package/dist/components/ui/Select.js +25 -0
  58. package/dist/components/ui/Select.js.map +1 -0
  59. package/dist/components/ui/Toast.js +1 -1
  60. package/dist/components/ui/index.d.ts +10 -4
  61. package/dist/components/ui/index.d.ts.map +1 -1
  62. package/dist/components/ui/index.js +5 -2
  63. package/dist/components/ui/index.js.map +1 -1
  64. package/dist/fields/BlockBuilderField.js +3 -3
  65. package/dist/fields/DateField.js +1 -1
  66. package/dist/fields/RelationshipField.js +3 -3
  67. package/dist/fields/TextField.js +1 -1
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +3 -0
  71. package/dist/index.js.map +1 -1
  72. package/dist/layout/Header.js +1 -1
  73. package/dist/layout/Layout.d.ts +14 -0
  74. package/dist/layout/Layout.d.ts.map +1 -1
  75. package/dist/layout/Layout.js +17 -11
  76. package/dist/layout/Layout.js.map +1 -1
  77. package/dist/layout/Sidebar.d.ts.map +1 -1
  78. package/dist/layout/Sidebar.js +21 -11
  79. package/dist/layout/Sidebar.js.map +1 -1
  80. package/dist/layout/primitives/AdminShell.d.ts +43 -0
  81. package/dist/layout/primitives/AdminShell.d.ts.map +1 -0
  82. package/dist/layout/primitives/AdminShell.js +51 -0
  83. package/dist/layout/primitives/AdminShell.js.map +1 -0
  84. package/dist/layout/primitives/Box.d.ts +19 -0
  85. package/dist/layout/primitives/Box.d.ts.map +1 -0
  86. package/dist/layout/primitives/Box.js +12 -0
  87. package/dist/layout/primitives/Box.js.map +1 -0
  88. package/dist/layout/primitives/Cluster.d.ts +27 -0
  89. package/dist/layout/primitives/Cluster.d.ts.map +1 -0
  90. package/dist/layout/primitives/Cluster.js +37 -0
  91. package/dist/layout/primitives/Cluster.js.map +1 -0
  92. package/dist/layout/primitives/Grid.d.ts +45 -0
  93. package/dist/layout/primitives/Grid.d.ts.map +1 -0
  94. package/dist/layout/primitives/Grid.js +59 -0
  95. package/dist/layout/primitives/Grid.js.map +1 -0
  96. package/dist/layout/primitives/PageContainer.d.ts +36 -0
  97. package/dist/layout/primitives/PageContainer.d.ts.map +1 -0
  98. package/dist/layout/primitives/PageContainer.js +41 -0
  99. package/dist/layout/primitives/PageContainer.js.map +1 -0
  100. package/dist/layout/primitives/Split.d.ts +34 -0
  101. package/dist/layout/primitives/Split.d.ts.map +1 -0
  102. package/dist/layout/primitives/Split.js +27 -0
  103. package/dist/layout/primitives/Split.js.map +1 -0
  104. package/dist/layout/primitives/Stack.d.ts +23 -0
  105. package/dist/layout/primitives/Stack.d.ts.map +1 -0
  106. package/dist/layout/primitives/Stack.js +34 -0
  107. package/dist/layout/primitives/Stack.js.map +1 -0
  108. package/dist/layout/primitives/index.d.ts +30 -0
  109. package/dist/layout/primitives/index.d.ts.map +1 -0
  110. package/dist/layout/primitives/index.js +22 -0
  111. package/dist/layout/primitives/index.js.map +1 -0
  112. package/dist/layout/primitives/tokens.d.ts +48 -0
  113. package/dist/layout/primitives/tokens.d.ts.map +1 -0
  114. package/dist/layout/primitives/tokens.js +54 -0
  115. package/dist/layout/primitives/tokens.js.map +1 -0
  116. package/dist/lib/cv.d.ts +53 -0
  117. package/dist/lib/cv.d.ts.map +1 -0
  118. package/dist/lib/cv.js +39 -0
  119. package/dist/lib/cv.js.map +1 -0
  120. package/dist/views/ApiKeys.js +7 -7
  121. package/dist/views/CollectionList.js +8 -8
  122. package/dist/views/Dashboard.d.ts.map +1 -1
  123. package/dist/views/Dashboard.js +333 -78
  124. package/dist/views/Dashboard.js.map +1 -1
  125. package/dist/views/DocumentEdit.js +3 -3
  126. package/dist/views/ForgotPassword.js +2 -2
  127. package/dist/views/FormEditor.js +5 -5
  128. package/dist/views/FormSubmissions.js +6 -6
  129. package/dist/views/Forms.js +2 -2
  130. package/dist/views/Login.d.ts +16 -1
  131. package/dist/views/Login.d.ts.map +1 -1
  132. package/dist/views/Login.js +17 -7
  133. package/dist/views/Login.js.map +1 -1
  134. package/dist/views/MediaBrowser.js +16 -16
  135. package/dist/views/PageEditor.js +2 -2
  136. package/dist/views/Pages.js +10 -10
  137. package/dist/views/PostEditor.js +2 -2
  138. package/dist/views/Posts.js +4 -4
  139. package/dist/views/Redirects.js +4 -4
  140. package/dist/views/ResetPassword.js +2 -2
  141. package/dist/views/SEO.js +6 -6
  142. package/dist/views/ScriptTagEditor.js +4 -4
  143. package/dist/views/ScriptTags.js +2 -2
  144. package/dist/views/Settings.d.ts.map +1 -1
  145. package/dist/views/Settings.js +9 -8
  146. package/dist/views/Settings.js.map +1 -1
  147. package/dist/views/SetupWizard.js +2 -2
  148. package/dist/views/Users.js +4 -4
  149. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  150. package/dist/views/page-builder/AIGenerateDialog.js +10 -10
  151. package/dist/views/page-builder/BlockEditor.js +10 -10
  152. package/dist/views/page-builder/BlockPicker.js +4 -4
  153. package/dist/views/page-builder/BottomBar.js +1 -1
  154. package/dist/views/page-builder/BuilderToolbar.js +2 -2
  155. package/dist/views/page-builder/ContextPanel.js +2 -2
  156. package/dist/views/page-builder/DesignScore.js +9 -9
  157. package/dist/views/page-builder/NodeSettings.js +8 -8
  158. package/dist/views/page-builder/PageBuilder.js +3 -3
  159. package/dist/views/page-builder/PageSettings.js +1 -1
  160. package/dist/views/page-builder/PageTemplates.js +2 -2
  161. package/dist/views/page-builder/SEOPanel.js +13 -13
  162. package/dist/views/page-builder/SavedSections.js +5 -5
  163. package/dist/views/page-builder/TemplatePicker.js +2 -2
  164. package/dist/views/page-builder/block-renderers/CTAPreview.js +5 -5
  165. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  166. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -1
  167. package/dist/views/page-builder/block-renderers/FAQPreview.js +3 -3
  168. package/dist/views/page-builder/block-renderers/FallbackPreview.js +1 -1
  169. package/dist/views/page-builder/block-renderers/FormPreview.js +3 -3
  170. package/dist/views/page-builder/block-renderers/GalleryPreview.js +5 -5
  171. package/dist/views/page-builder/block-renderers/HeroPreview.js +3 -3
  172. package/dist/views/page-builder/block-renderers/ImagePreview.js +3 -3
  173. package/dist/views/page-builder/block-renderers/TextPreview.js +3 -3
  174. package/dist/views/page-builder/block-renderers/VideoPreview.js +4 -4
  175. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -1
  176. package/dist/views/page-builder/canvas/BuilderCanvas.js +3 -3
  177. package/dist/views/page-builder/canvas/ColumnRenderer.js +2 -2
  178. package/dist/views/page-builder/canvas/ContainerRenderer.js +2 -2
  179. package/dist/views/page-builder/canvas/RowRenderer.js +2 -2
  180. package/dist/views/page-builder/canvas/SectionRenderer.js +2 -2
  181. package/package.json +6 -2
  182. package/src/AdminRoot.tsx +21 -11
  183. package/src/__tests__/layout/primitives.test.ts +37 -0
  184. package/src/__tests__/lib/cv.test.ts +74 -0
  185. package/src/assets/actuate-logo.tsx +72 -0
  186. package/src/components/Breadcrumbs.tsx +6 -6
  187. package/src/components/CommandPalette.tsx +34 -34
  188. package/src/components/ContentOverviewChart.tsx +3 -3
  189. package/src/components/ErrorBoundary.tsx +3 -3
  190. package/src/components/FocalPointPicker.tsx +4 -4
  191. package/src/components/FolderTree.tsx +38 -38
  192. package/src/components/LivePreview.tsx +16 -16
  193. package/src/components/LocaleSwitcher.tsx +7 -7
  194. package/src/components/MediaPickerModal.tsx +21 -21
  195. package/src/components/PresenceIndicator.tsx +2 -2
  196. package/src/components/SEOConfigPanel.tsx +582 -0
  197. package/src/components/SEOPanel.tsx +46 -46
  198. package/src/components/SEOPerformance.tsx +21 -21
  199. package/src/components/SchedulePublishDialog.tsx +4 -4
  200. package/src/components/SharePreviewLinkDialog.tsx +1 -1
  201. package/src/components/TipTapEditor.tsx +33 -33
  202. package/src/components/VersionHistory.tsx +16 -16
  203. package/src/components/ui/Badge.tsx +66 -14
  204. package/src/components/ui/Button.tsx +70 -33
  205. package/src/components/ui/Card.tsx +101 -0
  206. package/src/components/ui/DataTable.tsx +1 -1
  207. package/src/components/ui/Input.tsx +35 -0
  208. package/src/components/ui/SearchInput.tsx +4 -4
  209. package/src/components/ui/Select.tsx +56 -0
  210. package/src/components/ui/Toast.tsx +1 -1
  211. package/src/components/ui/index.ts +18 -4
  212. package/src/fields/BlockBuilderField.tsx +3 -3
  213. package/src/fields/DateField.tsx +1 -1
  214. package/src/fields/RelationshipField.tsx +10 -10
  215. package/src/fields/TextField.tsx +1 -1
  216. package/src/index.ts +28 -0
  217. package/src/layout/Header.tsx +28 -28
  218. package/src/layout/Layout.tsx +39 -46
  219. package/src/layout/Sidebar.tsx +37 -64
  220. package/src/layout/primitives/AdminShell.tsx +118 -0
  221. package/src/layout/primitives/Box.tsx +30 -0
  222. package/src/layout/primitives/Cluster.tsx +74 -0
  223. package/src/layout/primitives/Grid.tsx +120 -0
  224. package/src/layout/primitives/PageContainer.tsx +96 -0
  225. package/src/layout/primitives/Split.tsx +73 -0
  226. package/src/layout/primitives/Stack.tsx +67 -0
  227. package/src/layout/primitives/index.ts +36 -0
  228. package/src/layout/primitives/tokens.ts +76 -0
  229. package/src/lib/cv.ts +96 -0
  230. package/src/styles/build-input.css +1 -1
  231. package/src/views/ApiKeys.tsx +57 -57
  232. package/src/views/CollectionList.tsx +30 -30
  233. package/src/views/Dashboard.tsx +737 -186
  234. package/src/views/DocumentEdit.tsx +9 -9
  235. package/src/views/ForgotPassword.tsx +18 -18
  236. package/src/views/FormEditor.tsx +75 -75
  237. package/src/views/FormSubmissions.tsx +76 -76
  238. package/src/views/Forms.tsx +27 -27
  239. package/src/views/Login.tsx +65 -25
  240. package/src/views/MediaBrowser.tsx +127 -127
  241. package/src/views/PageEditor.tsx +25 -25
  242. package/src/views/Pages.tsx +59 -59
  243. package/src/views/PostEditor.tsx +37 -37
  244. package/src/views/Posts.tsx +48 -48
  245. package/src/views/Redirects.tsx +21 -21
  246. package/src/views/ResetPassword.tsx +28 -28
  247. package/src/views/SEO.tsx +144 -144
  248. package/src/views/ScriptTagEditor.tsx +24 -24
  249. package/src/views/ScriptTags.tsx +10 -10
  250. package/src/views/Settings.tsx +88 -80
  251. package/src/views/SetupWizard.tsx +28 -28
  252. package/src/views/Users.tsx +20 -20
  253. package/src/views/page-builder/AIBlockAssist.tsx +1 -1
  254. package/src/views/page-builder/AIGenerateDialog.tsx +63 -63
  255. package/src/views/page-builder/BlockEditor.tsx +26 -26
  256. package/src/views/page-builder/BlockPicker.tsx +22 -22
  257. package/src/views/page-builder/BottomBar.tsx +8 -8
  258. package/src/views/page-builder/BuilderToolbar.tsx +17 -17
  259. package/src/views/page-builder/ContextPanel.tsx +3 -3
  260. package/src/views/page-builder/DesignScore.tsx +21 -21
  261. package/src/views/page-builder/NodeSettings.tsx +27 -27
  262. package/src/views/page-builder/PageBuilder.tsx +11 -11
  263. package/src/views/page-builder/PageSettings.tsx +4 -4
  264. package/src/views/page-builder/PageTemplates.tsx +18 -18
  265. package/src/views/page-builder/SEOPanel.tsx +53 -53
  266. package/src/views/page-builder/SavedSections.tsx +37 -37
  267. package/src/views/page-builder/TemplatePicker.tsx +17 -17
  268. package/src/views/page-builder/block-renderers/CTAPreview.tsx +13 -13
  269. package/src/views/page-builder/block-renderers/CardsPreview.tsx +5 -5
  270. package/src/views/page-builder/block-renderers/CodePreview.tsx +6 -6
  271. package/src/views/page-builder/block-renderers/FAQPreview.tsx +13 -13
  272. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +3 -3
  273. package/src/views/page-builder/block-renderers/FormPreview.tsx +20 -20
  274. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +8 -8
  275. package/src/views/page-builder/block-renderers/HeroPreview.tsx +16 -16
  276. package/src/views/page-builder/block-renderers/ImagePreview.tsx +4 -4
  277. package/src/views/page-builder/block-renderers/TextPreview.tsx +14 -14
  278. package/src/views/page-builder/block-renderers/VideoPreview.tsx +12 -12
  279. package/src/views/page-builder/canvas/BlockRenderer.tsx +4 -4
  280. package/src/views/page-builder/canvas/BuilderCanvas.tsx +6 -6
  281. package/src/views/page-builder/canvas/ColumnRenderer.tsx +3 -3
  282. package/src/views/page-builder/canvas/ContainerRenderer.tsx +2 -2
  283. package/src/views/page-builder/canvas/RowRenderer.tsx +2 -2
  284. package/src/views/page-builder/canvas/SectionRenderer.tsx +2 -2
@@ -0,0 +1,73 @@
1
+ import type { HTMLAttributes, ReactNode, ElementType } from 'react'
2
+ import type { SpaceToken } from './tokens.js'
3
+
4
+ export interface SplitProps extends HTMLAttributes<HTMLElement> {
5
+ /**
6
+ * Fraction of the container the primary pane should take, expressed as
7
+ * a CSS fraction string. Defaults to `'2fr 1fr'` (primary 2x sidebar).
8
+ *
9
+ * @example
10
+ * <Split fraction="3fr 1fr"> // 75% / 25%
11
+ * <Split fraction="minmax(0, 1fr) 320px"> // fluid + fixed sidebar
12
+ */
13
+ fraction?: string
14
+ /** Gap between the two panes. */
15
+ space?: SpaceToken
16
+ /**
17
+ * Stack vertically at this breakpoint and below. Pass `false` to never
18
+ * stack. Defaults to `md` (stacks on screens narrower than 768px).
19
+ */
20
+ stackBelow?: 'sm' | 'md' | 'lg' | 'xl' | false
21
+ /** Reverse the order of children (sidebar first instead of second). */
22
+ reverse?: boolean
23
+ /** Render as a different element. */
24
+ as?: ElementType
25
+ children: [ReactNode, ReactNode]
26
+ }
27
+
28
+ const STACK_BELOW_CLASS = {
29
+ sm: 'sm:grid',
30
+ md: 'md:grid',
31
+ lg: 'lg:grid',
32
+ xl: 'xl:grid',
33
+ } as const
34
+
35
+ /**
36
+ * Two-pane split layout (primary + sidebar/aside) that collapses to a
37
+ * stacked layout below a configurable breakpoint. Use this for the
38
+ * document editor (`<Split fraction="minmax(0, 1fr) 320px">`), settings
39
+ * pages with a navigation rail, etc. — anywhere two panes need to live
40
+ * side-by-side at desktop widths and stack on mobile.
41
+ */
42
+ export function Split({
43
+ fraction = '2fr 1fr',
44
+ space = '6',
45
+ stackBelow = 'md',
46
+ reverse,
47
+ as: Component = 'div',
48
+ className = '',
49
+ style,
50
+ children,
51
+ ...rest
52
+ }: SplitProps) {
53
+ const stackClass =
54
+ stackBelow === false ? 'grid' : `flex flex-col ${STACK_BELOW_CLASS[stackBelow]}`
55
+ const classes = [stackClass, `gap-${space}`, reverse ? 'flex-col-reverse' : '', className]
56
+ .filter(Boolean)
57
+ .join(' ')
58
+
59
+ return (
60
+ <Component
61
+ className={classes}
62
+ style={{
63
+ ...(stackBelow === false
64
+ ? { gridTemplateColumns: fraction }
65
+ : { gridTemplateColumns: fraction }),
66
+ ...style,
67
+ }}
68
+ {...rest}
69
+ >
70
+ {children}
71
+ </Component>
72
+ )
73
+ }
@@ -0,0 +1,67 @@
1
+ import type { HTMLAttributes, ReactNode, ElementType } from 'react'
2
+ import type { SpaceToken } from './tokens.js'
3
+
4
+ export type StackSpace = SpaceToken
5
+
6
+ export interface StackProps extends HTMLAttributes<HTMLElement> {
7
+ /** Vertical gap between children. Maps to Tailwind `gap-{space}`. */
8
+ space?: StackSpace
9
+ /** Render as a different element (e.g. `<section>`, `<article>`). Defaults to `div`. */
10
+ as?: ElementType
11
+ /** Center children horizontally (sets `items-center`). */
12
+ align?: 'start' | 'center' | 'end' | 'stretch'
13
+ /** Distribute vertical space (sets `justify-{value}`). */
14
+ justify?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'
15
+ /** Stretch the stack to fill its parent's height. */
16
+ fill?: boolean
17
+ children?: ReactNode
18
+ }
19
+
20
+ const ALIGN_CLASS: Record<NonNullable<StackProps['align']>, string> = {
21
+ start: 'items-start',
22
+ center: 'items-center',
23
+ end: 'items-end',
24
+ stretch: 'items-stretch',
25
+ }
26
+
27
+ const JUSTIFY_CLASS: Record<NonNullable<StackProps['justify']>, string> = {
28
+ start: 'justify-start',
29
+ center: 'justify-center',
30
+ end: 'justify-end',
31
+ between: 'justify-between',
32
+ around: 'justify-around',
33
+ evenly: 'justify-evenly',
34
+ }
35
+
36
+ /**
37
+ * Vertical stack with a consistent gap between children. This is the
38
+ * single sanctioned way to space block-level elements in the admin —
39
+ * never reach for `space-y-*` directly.
40
+ */
41
+ export function Stack({
42
+ space = '4',
43
+ as: Component = 'div',
44
+ align,
45
+ justify,
46
+ fill,
47
+ className = '',
48
+ children,
49
+ ...rest
50
+ }: StackProps) {
51
+ const classes = [
52
+ 'flex flex-col',
53
+ `gap-${space}`,
54
+ align ? ALIGN_CLASS[align] : '',
55
+ justify ? JUSTIFY_CLASS[justify] : '',
56
+ fill ? 'h-full' : '',
57
+ className,
58
+ ]
59
+ .filter(Boolean)
60
+ .join(' ')
61
+
62
+ return (
63
+ <Component className={classes} {...rest}>
64
+ {children}
65
+ </Component>
66
+ )
67
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Layout primitives for the Actuate admin.
3
+ *
4
+ * These exist so views never hand-roll their own flex/grid scaffolding.
5
+ * Every admin view should compose these primitives instead of writing raw
6
+ * Tailwind classes for spacing/alignment/structure. That contract is what
7
+ * keeps layout bugs (sidebar overlap, breakpoint mismatches, missing
8
+ * `min-w-0`) from recurring in new views.
9
+ *
10
+ * Naming follows the "Every Layout" canon
11
+ * (https://every-layout.dev/) plus our own `AdminShell` and
12
+ * `PageContainer` for the admin-specific outer chrome.
13
+ */
14
+ export { AdminShell } from './AdminShell.js'
15
+ export type { AdminShellProps } from './AdminShell.js'
16
+
17
+ export { PageContainer } from './PageContainer.js'
18
+ export type { PageContainerProps } from './PageContainer.js'
19
+
20
+ export { Stack } from './Stack.js'
21
+ export type { StackProps, StackSpace } from './Stack.js'
22
+
23
+ export { Cluster } from './Cluster.js'
24
+ export type { ClusterProps, ClusterAlign, ClusterJustify } from './Cluster.js'
25
+
26
+ export { Grid } from './Grid.js'
27
+ export type { GridProps, GridResponsive } from './Grid.js'
28
+
29
+ export { Split } from './Split.js'
30
+ export type { SplitProps } from './Split.js'
31
+
32
+ export { Box } from './Box.js'
33
+ export type { BoxProps } from './Box.js'
34
+
35
+ export { tokens } from './tokens.js'
36
+ export type { SpaceToken, RadiusToken } from './tokens.js'
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Design tokens — single source of truth for the admin design system.
3
+ *
4
+ * Tokens are surfaced both as TypeScript constants (for inline-style escape
5
+ * hatches) and via CSS custom properties in `styles/theme.css`. Always
6
+ * prefer the CSS variables in production code; the TS constants are for
7
+ * computed inline styles only (e.g. dynamic widths, computed grid sizes).
8
+ */
9
+
10
+ export type SpaceToken =
11
+ | '0'
12
+ | 'px'
13
+ | '0.5'
14
+ | '1'
15
+ | '1.5'
16
+ | '2'
17
+ | '2.5'
18
+ | '3'
19
+ | '4'
20
+ | '5'
21
+ | '6'
22
+ | '8'
23
+ | '10'
24
+ | '12'
25
+ | '16'
26
+
27
+ export type RadiusToken = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full'
28
+
29
+ /** Numeric pixel values for inline style escape hatches. */
30
+ export const tokens = {
31
+ // Spacing scale matches Tailwind's default (--spacing = 0.25rem = 4px).
32
+ space: {
33
+ '0': 0,
34
+ px: 1,
35
+ '0.5': 2,
36
+ '1': 4,
37
+ '1.5': 6,
38
+ '2': 8,
39
+ '2.5': 10,
40
+ '3': 12,
41
+ '4': 16,
42
+ '5': 20,
43
+ '6': 24,
44
+ '8': 32,
45
+ '10': 40,
46
+ '12': 48,
47
+ '16': 64,
48
+ } as const satisfies Record<SpaceToken, number>,
49
+
50
+ radius: {
51
+ none: 0,
52
+ sm: 2,
53
+ md: 6,
54
+ lg: 8,
55
+ xl: 12,
56
+ full: 9999,
57
+ } as const satisfies Record<RadiusToken, number>,
58
+
59
+ // Breakpoints mirror Tailwind defaults so primitives can compose with
60
+ // utility classes without surprises. Use `matchMedia(`(min-width: …`)` to
61
+ // sync JS-driven layout decisions with these values.
62
+ breakpoint: {
63
+ sm: 640,
64
+ md: 768,
65
+ lg: 1024,
66
+ xl: 1280,
67
+ '2xl': 1536,
68
+ } as const,
69
+ }
70
+
71
+ /** Map a space token to the corresponding Tailwind `space-y-*` / `gap-*` value. */
72
+ export function spaceToTw(t: SpaceToken): string {
73
+ // Tailwind's spacing utility already accepts the same scale, so we map
74
+ // 1:1. Centralizing here means callers don't repeat the string literal.
75
+ return t
76
+ }
package/src/lib/cv.ts ADDED
@@ -0,0 +1,96 @@
1
+ import clsx from 'clsx'
2
+
3
+ /**
4
+ * Tiny in-house implementation of the `class-variance-authority` pattern
5
+ * (a.k.a. `cva` / `tailwind-variants`). We roll our own to avoid a runtime
6
+ * dependency while keeping the API surface compatible with the shadcn /
7
+ * cva ecosystem — anyone familiar with cva can read these calls.
8
+ *
9
+ * @example
10
+ * const button = cv('inline-flex items-center', {
11
+ * variants: {
12
+ * intent: {
13
+ * primary: 'bg-primary text-white',
14
+ * secondary: 'bg-secondary text-foreground',
15
+ * },
16
+ * size: {
17
+ * sm: 'px-2 py-1 text-xs',
18
+ * md: 'px-4 py-2 text-sm',
19
+ * },
20
+ * },
21
+ * defaultVariants: { intent: 'primary', size: 'md' },
22
+ * })
23
+ *
24
+ * button({ intent: 'secondary' }) // -> "inline-flex … bg-secondary …"
25
+ * button({ intent: 'secondary', class: 'shadow' }) // append extras
26
+ */
27
+
28
+ type ClassValue = string | undefined | false | null
29
+
30
+ export type VariantsConfig = Record<string, Record<string, ClassValue>>
31
+
32
+ type VariantSelection<V extends VariantsConfig> = {
33
+ [K in keyof V]?: keyof V[K]
34
+ }
35
+
36
+ interface CompoundVariant<V extends VariantsConfig> {
37
+ // Subset of variants that must match for the compound classes to apply.
38
+ // Use string values from each variant key (or arrays for "match any").
39
+ [key: string]: keyof V[keyof V] | Array<keyof V[keyof V]> | ClassValue
40
+ class?: ClassValue
41
+ }
42
+
43
+ export interface CvConfig<V extends VariantsConfig> {
44
+ variants: V
45
+ defaultVariants?: VariantSelection<V>
46
+ compoundVariants?: Array<CompoundVariant<V>>
47
+ }
48
+
49
+ export type VariantProps<F extends (...args: any) => any> = Omit<
50
+ NonNullable<Parameters<F>[0]>,
51
+ 'class' | 'className'
52
+ >
53
+
54
+ /**
55
+ * Build a variant-aware class generator.
56
+ *
57
+ * The returned function accepts the variant selection plus an optional
58
+ * `class` / `className` escape hatch and returns the combined Tailwind
59
+ * class string. Compound variants run after the base + per-variant
60
+ * classes, so they take precedence when the Tailwind ordering matters.
61
+ */
62
+ export function cv<V extends VariantsConfig>(base: ClassValue, config: CvConfig<V>) {
63
+ return function variantClass(
64
+ props?: VariantSelection<V> & { class?: ClassValue; className?: ClassValue },
65
+ ): string {
66
+ const selected = { ...config.defaultVariants, ...props } as Record<string, unknown>
67
+
68
+ const variantClasses: ClassValue[] = []
69
+ for (const [key, valuesMap] of Object.entries(config.variants)) {
70
+ const value = selected[key]
71
+ if (value === undefined || value === null) continue
72
+ const cls = valuesMap[value as string]
73
+ if (cls) variantClasses.push(cls)
74
+ }
75
+
76
+ const compoundClasses: ClassValue[] = []
77
+ if (config.compoundVariants) {
78
+ for (const compound of config.compoundVariants) {
79
+ const { class: cClass, className: _cn, ...match } = compound as any
80
+ const matches = Object.entries(match).every(([k, v]) => {
81
+ const current = selected[k]
82
+ if (Array.isArray(v)) return (v as unknown[]).includes(current)
83
+ return current === v
84
+ })
85
+ if (matches && cClass) compoundClasses.push(cClass as ClassValue)
86
+ }
87
+ }
88
+
89
+ return clsx(
90
+ base,
91
+ ...variantClasses,
92
+ ...compoundClasses,
93
+ (props?.class ?? props?.className) as ClassValue,
94
+ )
95
+ }
96
+ }
@@ -7,5 +7,5 @@
7
7
  * import '@actuate-media/cms-admin/styles/precompiled.css'
8
8
  */
9
9
  @import 'tailwindcss';
10
- @source "../../src/**/*.{ts,tsx}";
10
+ @source '../../src/**/*.{ts,tsx}';
11
11
  @import './theme.css';