@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.
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +8 -5
- package/dist/AdminRoot.js.map +1 -1
- package/dist/__tests__/layout/primitives.test.d.ts +2 -0
- package/dist/__tests__/layout/primitives.test.d.ts.map +1 -0
- package/dist/__tests__/layout/primitives.test.js +34 -0
- package/dist/__tests__/layout/primitives.test.js.map +1 -0
- package/dist/__tests__/lib/cv.test.d.ts +2 -0
- package/dist/__tests__/lib/cv.test.d.ts.map +1 -0
- package/dist/__tests__/lib/cv.test.js +66 -0
- package/dist/__tests__/lib/cv.test.js.map +1 -0
- package/dist/actuate-admin.css +1 -1
- package/dist/assets/actuate-logo.d.ts +36 -0
- package/dist/assets/actuate-logo.d.ts.map +1 -0
- package/dist/assets/actuate-logo.js +15 -0
- package/dist/assets/actuate-logo.js.map +1 -0
- package/dist/components/Breadcrumbs.js +2 -2
- package/dist/components/CommandPalette.js +10 -10
- package/dist/components/ContentOverviewChart.js +3 -3
- package/dist/components/ErrorBoundary.js +1 -1
- package/dist/components/FocalPointPicker.js +2 -2
- package/dist/components/FolderTree.js +20 -20
- package/dist/components/LivePreview.js +3 -3
- package/dist/components/LocaleSwitcher.js +1 -1
- package/dist/components/MediaPickerModal.js +4 -4
- package/dist/components/PresenceIndicator.js +1 -1
- package/dist/components/SEOConfigPanel.d.ts +2 -0
- package/dist/components/SEOConfigPanel.d.ts.map +1 -0
- package/dist/components/SEOConfigPanel.js +174 -0
- package/dist/components/SEOConfigPanel.js.map +1 -0
- package/dist/components/SEOPanel.js +9 -9
- package/dist/components/SEOPerformance.js +2 -2
- package/dist/components/SchedulePublishDialog.js +1 -1
- package/dist/components/SharePreviewLinkDialog.js +1 -1
- package/dist/components/TipTapEditor.js +5 -5
- package/dist/components/VersionHistory.js +2 -2
- package/dist/components/ui/Badge.d.ts +33 -3
- package/dist/components/ui/Badge.d.ts.map +1 -1
- package/dist/components/ui/Badge.js +42 -8
- package/dist/components/ui/Badge.js.map +1 -1
- package/dist/components/ui/Button.d.ts +19 -8
- package/dist/components/ui/Button.d.ts.map +1 -1
- package/dist/components/ui/Button.js +35 -14
- package/dist/components/ui/Button.js.map +1 -1
- package/dist/components/ui/Card.d.ts +26 -0
- package/dist/components/ui/Card.d.ts.map +1 -0
- package/dist/components/ui/Card.js +45 -0
- package/dist/components/ui/Card.js.map +1 -0
- package/dist/components/ui/DataTable.js +1 -1
- package/dist/components/ui/Input.d.ts +15 -0
- package/dist/components/ui/Input.d.ts.map +1 -0
- package/dist/components/ui/Input.js +23 -0
- package/dist/components/ui/Input.js.map +1 -0
- package/dist/components/ui/SearchInput.js +1 -1
- package/dist/components/ui/Select.d.ts +16 -0
- package/dist/components/ui/Select.d.ts.map +1 -0
- package/dist/components/ui/Select.js +25 -0
- package/dist/components/ui/Select.js.map +1 -0
- package/dist/components/ui/Toast.js +1 -1
- package/dist/components/ui/index.d.ts +10 -4
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +5 -2
- package/dist/components/ui/index.js.map +1 -1
- package/dist/fields/BlockBuilderField.js +3 -3
- package/dist/fields/DateField.js +1 -1
- package/dist/fields/RelationshipField.js +3 -3
- package/dist/fields/TextField.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/layout/Header.js +1 -1
- package/dist/layout/Layout.d.ts +14 -0
- package/dist/layout/Layout.d.ts.map +1 -1
- package/dist/layout/Layout.js +17 -11
- package/dist/layout/Layout.js.map +1 -1
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Sidebar.js +21 -11
- package/dist/layout/Sidebar.js.map +1 -1
- package/dist/layout/primitives/AdminShell.d.ts +43 -0
- package/dist/layout/primitives/AdminShell.d.ts.map +1 -0
- package/dist/layout/primitives/AdminShell.js +51 -0
- package/dist/layout/primitives/AdminShell.js.map +1 -0
- package/dist/layout/primitives/Box.d.ts +19 -0
- package/dist/layout/primitives/Box.d.ts.map +1 -0
- package/dist/layout/primitives/Box.js +12 -0
- package/dist/layout/primitives/Box.js.map +1 -0
- package/dist/layout/primitives/Cluster.d.ts +27 -0
- package/dist/layout/primitives/Cluster.d.ts.map +1 -0
- package/dist/layout/primitives/Cluster.js +37 -0
- package/dist/layout/primitives/Cluster.js.map +1 -0
- package/dist/layout/primitives/Grid.d.ts +45 -0
- package/dist/layout/primitives/Grid.d.ts.map +1 -0
- package/dist/layout/primitives/Grid.js +59 -0
- package/dist/layout/primitives/Grid.js.map +1 -0
- package/dist/layout/primitives/PageContainer.d.ts +36 -0
- package/dist/layout/primitives/PageContainer.d.ts.map +1 -0
- package/dist/layout/primitives/PageContainer.js +41 -0
- package/dist/layout/primitives/PageContainer.js.map +1 -0
- package/dist/layout/primitives/Split.d.ts +34 -0
- package/dist/layout/primitives/Split.d.ts.map +1 -0
- package/dist/layout/primitives/Split.js +27 -0
- package/dist/layout/primitives/Split.js.map +1 -0
- package/dist/layout/primitives/Stack.d.ts +23 -0
- package/dist/layout/primitives/Stack.d.ts.map +1 -0
- package/dist/layout/primitives/Stack.js +34 -0
- package/dist/layout/primitives/Stack.js.map +1 -0
- package/dist/layout/primitives/index.d.ts +30 -0
- package/dist/layout/primitives/index.d.ts.map +1 -0
- package/dist/layout/primitives/index.js +22 -0
- package/dist/layout/primitives/index.js.map +1 -0
- package/dist/layout/primitives/tokens.d.ts +48 -0
- package/dist/layout/primitives/tokens.d.ts.map +1 -0
- package/dist/layout/primitives/tokens.js +54 -0
- package/dist/layout/primitives/tokens.js.map +1 -0
- package/dist/lib/cv.d.ts +53 -0
- package/dist/lib/cv.d.ts.map +1 -0
- package/dist/lib/cv.js +39 -0
- package/dist/lib/cv.js.map +1 -0
- package/dist/views/ApiKeys.js +7 -7
- package/dist/views/CollectionList.js +8 -8
- package/dist/views/Dashboard.d.ts.map +1 -1
- package/dist/views/Dashboard.js +333 -78
- package/dist/views/Dashboard.js.map +1 -1
- package/dist/views/DocumentEdit.js +3 -3
- package/dist/views/ForgotPassword.js +2 -2
- package/dist/views/FormEditor.js +5 -5
- package/dist/views/FormSubmissions.js +6 -6
- package/dist/views/Forms.js +2 -2
- package/dist/views/Login.d.ts +16 -1
- package/dist/views/Login.d.ts.map +1 -1
- package/dist/views/Login.js +17 -7
- package/dist/views/Login.js.map +1 -1
- package/dist/views/MediaBrowser.js +16 -16
- package/dist/views/PageEditor.js +2 -2
- package/dist/views/Pages.js +10 -10
- package/dist/views/PostEditor.js +2 -2
- package/dist/views/Posts.js +4 -4
- package/dist/views/Redirects.js +4 -4
- package/dist/views/ResetPassword.js +2 -2
- package/dist/views/SEO.js +6 -6
- package/dist/views/ScriptTagEditor.js +4 -4
- package/dist/views/ScriptTags.js +2 -2
- package/dist/views/Settings.d.ts.map +1 -1
- package/dist/views/Settings.js +9 -8
- package/dist/views/Settings.js.map +1 -1
- package/dist/views/SetupWizard.js +2 -2
- package/dist/views/Users.js +4 -4
- package/dist/views/page-builder/AIBlockAssist.js +1 -1
- package/dist/views/page-builder/AIGenerateDialog.js +10 -10
- package/dist/views/page-builder/BlockEditor.js +10 -10
- package/dist/views/page-builder/BlockPicker.js +4 -4
- package/dist/views/page-builder/BottomBar.js +1 -1
- package/dist/views/page-builder/BuilderToolbar.js +2 -2
- package/dist/views/page-builder/ContextPanel.js +2 -2
- package/dist/views/page-builder/DesignScore.js +9 -9
- package/dist/views/page-builder/NodeSettings.js +8 -8
- package/dist/views/page-builder/PageBuilder.js +3 -3
- package/dist/views/page-builder/PageSettings.js +1 -1
- package/dist/views/page-builder/PageTemplates.js +2 -2
- package/dist/views/page-builder/SEOPanel.js +13 -13
- package/dist/views/page-builder/SavedSections.js +5 -5
- package/dist/views/page-builder/TemplatePicker.js +2 -2
- package/dist/views/page-builder/block-renderers/CTAPreview.js +5 -5
- package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
- package/dist/views/page-builder/block-renderers/CodePreview.js +1 -1
- package/dist/views/page-builder/block-renderers/FAQPreview.js +3 -3
- package/dist/views/page-builder/block-renderers/FallbackPreview.js +1 -1
- package/dist/views/page-builder/block-renderers/FormPreview.js +3 -3
- package/dist/views/page-builder/block-renderers/GalleryPreview.js +5 -5
- package/dist/views/page-builder/block-renderers/HeroPreview.js +3 -3
- package/dist/views/page-builder/block-renderers/ImagePreview.js +3 -3
- package/dist/views/page-builder/block-renderers/TextPreview.js +3 -3
- package/dist/views/page-builder/block-renderers/VideoPreview.js +4 -4
- package/dist/views/page-builder/canvas/BlockRenderer.js +1 -1
- package/dist/views/page-builder/canvas/BuilderCanvas.js +3 -3
- package/dist/views/page-builder/canvas/ColumnRenderer.js +2 -2
- package/dist/views/page-builder/canvas/ContainerRenderer.js +2 -2
- package/dist/views/page-builder/canvas/RowRenderer.js +2 -2
- package/dist/views/page-builder/canvas/SectionRenderer.js +2 -2
- package/package.json +6 -2
- package/src/AdminRoot.tsx +21 -11
- package/src/__tests__/layout/primitives.test.ts +37 -0
- package/src/__tests__/lib/cv.test.ts +74 -0
- package/src/assets/actuate-logo.tsx +72 -0
- package/src/components/Breadcrumbs.tsx +6 -6
- package/src/components/CommandPalette.tsx +34 -34
- package/src/components/ContentOverviewChart.tsx +3 -3
- package/src/components/ErrorBoundary.tsx +3 -3
- package/src/components/FocalPointPicker.tsx +4 -4
- package/src/components/FolderTree.tsx +38 -38
- package/src/components/LivePreview.tsx +16 -16
- package/src/components/LocaleSwitcher.tsx +7 -7
- package/src/components/MediaPickerModal.tsx +21 -21
- package/src/components/PresenceIndicator.tsx +2 -2
- package/src/components/SEOConfigPanel.tsx +582 -0
- package/src/components/SEOPanel.tsx +46 -46
- package/src/components/SEOPerformance.tsx +21 -21
- package/src/components/SchedulePublishDialog.tsx +4 -4
- package/src/components/SharePreviewLinkDialog.tsx +1 -1
- package/src/components/TipTapEditor.tsx +33 -33
- package/src/components/VersionHistory.tsx +16 -16
- package/src/components/ui/Badge.tsx +66 -14
- package/src/components/ui/Button.tsx +70 -33
- package/src/components/ui/Card.tsx +101 -0
- package/src/components/ui/DataTable.tsx +1 -1
- package/src/components/ui/Input.tsx +35 -0
- package/src/components/ui/SearchInput.tsx +4 -4
- package/src/components/ui/Select.tsx +56 -0
- package/src/components/ui/Toast.tsx +1 -1
- package/src/components/ui/index.ts +18 -4
- package/src/fields/BlockBuilderField.tsx +3 -3
- package/src/fields/DateField.tsx +1 -1
- package/src/fields/RelationshipField.tsx +10 -10
- package/src/fields/TextField.tsx +1 -1
- package/src/index.ts +28 -0
- package/src/layout/Header.tsx +28 -28
- package/src/layout/Layout.tsx +39 -46
- package/src/layout/Sidebar.tsx +37 -64
- package/src/layout/primitives/AdminShell.tsx +118 -0
- package/src/layout/primitives/Box.tsx +30 -0
- package/src/layout/primitives/Cluster.tsx +74 -0
- package/src/layout/primitives/Grid.tsx +120 -0
- package/src/layout/primitives/PageContainer.tsx +96 -0
- package/src/layout/primitives/Split.tsx +73 -0
- package/src/layout/primitives/Stack.tsx +67 -0
- package/src/layout/primitives/index.ts +36 -0
- package/src/layout/primitives/tokens.ts +76 -0
- package/src/lib/cv.ts +96 -0
- package/src/styles/build-input.css +1 -1
- package/src/views/ApiKeys.tsx +57 -57
- package/src/views/CollectionList.tsx +30 -30
- package/src/views/Dashboard.tsx +737 -186
- package/src/views/DocumentEdit.tsx +9 -9
- package/src/views/ForgotPassword.tsx +18 -18
- package/src/views/FormEditor.tsx +75 -75
- package/src/views/FormSubmissions.tsx +76 -76
- package/src/views/Forms.tsx +27 -27
- package/src/views/Login.tsx +65 -25
- package/src/views/MediaBrowser.tsx +127 -127
- package/src/views/PageEditor.tsx +25 -25
- package/src/views/Pages.tsx +59 -59
- package/src/views/PostEditor.tsx +37 -37
- package/src/views/Posts.tsx +48 -48
- package/src/views/Redirects.tsx +21 -21
- package/src/views/ResetPassword.tsx +28 -28
- package/src/views/SEO.tsx +144 -144
- package/src/views/ScriptTagEditor.tsx +24 -24
- package/src/views/ScriptTags.tsx +10 -10
- package/src/views/Settings.tsx +88 -80
- package/src/views/SetupWizard.tsx +28 -28
- package/src/views/Users.tsx +20 -20
- package/src/views/page-builder/AIBlockAssist.tsx +1 -1
- package/src/views/page-builder/AIGenerateDialog.tsx +63 -63
- package/src/views/page-builder/BlockEditor.tsx +26 -26
- package/src/views/page-builder/BlockPicker.tsx +22 -22
- package/src/views/page-builder/BottomBar.tsx +8 -8
- package/src/views/page-builder/BuilderToolbar.tsx +17 -17
- package/src/views/page-builder/ContextPanel.tsx +3 -3
- package/src/views/page-builder/DesignScore.tsx +21 -21
- package/src/views/page-builder/NodeSettings.tsx +27 -27
- package/src/views/page-builder/PageBuilder.tsx +11 -11
- package/src/views/page-builder/PageSettings.tsx +4 -4
- package/src/views/page-builder/PageTemplates.tsx +18 -18
- package/src/views/page-builder/SEOPanel.tsx +53 -53
- package/src/views/page-builder/SavedSections.tsx +37 -37
- package/src/views/page-builder/TemplatePicker.tsx +17 -17
- package/src/views/page-builder/block-renderers/CTAPreview.tsx +13 -13
- package/src/views/page-builder/block-renderers/CardsPreview.tsx +5 -5
- package/src/views/page-builder/block-renderers/CodePreview.tsx +6 -6
- package/src/views/page-builder/block-renderers/FAQPreview.tsx +13 -13
- package/src/views/page-builder/block-renderers/FallbackPreview.tsx +3 -3
- package/src/views/page-builder/block-renderers/FormPreview.tsx +20 -20
- package/src/views/page-builder/block-renderers/GalleryPreview.tsx +8 -8
- package/src/views/page-builder/block-renderers/HeroPreview.tsx +16 -16
- package/src/views/page-builder/block-renderers/ImagePreview.tsx +4 -4
- package/src/views/page-builder/block-renderers/TextPreview.tsx +14 -14
- package/src/views/page-builder/block-renderers/VideoPreview.tsx +12 -12
- package/src/views/page-builder/canvas/BlockRenderer.tsx +4 -4
- package/src/views/page-builder/canvas/BuilderCanvas.tsx +6 -6
- package/src/views/page-builder/canvas/ColumnRenderer.tsx +3 -3
- package/src/views/page-builder/canvas/ContainerRenderer.tsx +2 -2
- package/src/views/page-builder/canvas/RowRenderer.tsx +2 -2
- 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
|
+
}
|