@actuate-media/cms-admin 0.9.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.d.ts +18 -0
- package/dist/components/SchedulePublishDialog.d.ts.map +1 -0
- package/dist/components/SchedulePublishDialog.js +106 -0
- package/dist/components/SchedulePublishDialog.js.map +1 -0
- package/dist/components/SharePreviewLinkDialog.d.ts +17 -0
- package/dist/components/SharePreviewLinkDialog.d.ts.map +1 -0
- package/dist/components/SharePreviewLinkDialog.js +83 -0
- package/dist/components/SharePreviewLinkDialog.js.map +1 -0
- 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 +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -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.d.ts.map +1 -1
- package/dist/views/ApiKeys.js +13 -11
- package/dist/views/ApiKeys.js.map +1 -1
- 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.d.ts.map +1 -1
- package/dist/views/DocumentEdit.js +17 -5
- package/dist/views/DocumentEdit.js.map +1 -1
- 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 +241 -0
- package/src/components/SharePreviewLinkDialog.tsx +227 -0
- 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 +32 -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 +90 -10
- 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
|
@@ -1,47 +1,79 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { type ButtonHTMLAttributes, type ReactNode } from 'react'
|
|
3
|
+
import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react'
|
|
4
|
+
import { cv, type VariantProps } from '../../lib/cv.js'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
const button = cv(
|
|
7
|
+
// Base classes apply to every variant.
|
|
8
|
+
'focus-visible:ring-offset-background inline-flex items-center justify-center gap-2 rounded-[var(--radius)] font-medium transition-colors focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
primary: 'bg-[var(--primary)] text-[var(--primary-foreground)] hover:opacity-90',
|
|
13
|
+
secondary: 'bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:opacity-80',
|
|
14
|
+
danger: 'bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:opacity-90',
|
|
15
|
+
ghost: 'bg-transparent text-[var(--foreground)] hover:bg-[var(--accent)]',
|
|
16
|
+
outline:
|
|
17
|
+
'border border-[var(--border)] bg-transparent text-[var(--foreground)] hover:bg-[var(--accent)]',
|
|
18
|
+
link: 'bg-transparent text-[var(--primary)] underline-offset-4 hover:underline',
|
|
19
|
+
},
|
|
20
|
+
size: {
|
|
21
|
+
xs: 'h-7 px-2 text-xs',
|
|
22
|
+
sm: 'h-8 px-2.5 text-xs',
|
|
23
|
+
md: 'h-9 px-4 text-sm',
|
|
24
|
+
lg: 'h-10 px-6 text-base',
|
|
25
|
+
icon: 'h-9 w-9 p-0',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
variant: 'primary',
|
|
30
|
+
size: 'md',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
)
|
|
7
34
|
|
|
8
|
-
export
|
|
9
|
-
variant?: ButtonVariant
|
|
10
|
-
size?: ButtonSize
|
|
11
|
-
loading?: boolean
|
|
12
|
-
children: ReactNode
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const variantClasses: Record<ButtonVariant, string> = {
|
|
16
|
-
primary: 'bg-[var(--primary)] text-[var(--primary-foreground)] hover:opacity-90',
|
|
17
|
-
secondary: 'bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:opacity-80',
|
|
18
|
-
danger: 'bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:opacity-90',
|
|
19
|
-
ghost: 'bg-transparent hover:bg-[var(--accent)] text-[var(--foreground)]',
|
|
20
|
-
}
|
|
35
|
+
export type ButtonVariants = VariantProps<typeof button>
|
|
21
36
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, ButtonVariants {
|
|
38
|
+
loading?: boolean
|
|
39
|
+
/** Stretch the button to fill its container width. */
|
|
40
|
+
full?: boolean
|
|
41
|
+
/** Icon rendered before the children. Use with `size="icon"` for icon-only buttons. */
|
|
42
|
+
leftIcon?: ReactNode
|
|
43
|
+
/** Icon rendered after the children. */
|
|
44
|
+
rightIcon?: ReactNode
|
|
45
|
+
children?: ReactNode
|
|
26
46
|
}
|
|
27
47
|
|
|
28
|
-
export function Button(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
|
49
|
+
{
|
|
50
|
+
variant,
|
|
51
|
+
size,
|
|
52
|
+
full,
|
|
53
|
+
loading = false,
|
|
54
|
+
disabled,
|
|
55
|
+
leftIcon,
|
|
56
|
+
rightIcon,
|
|
57
|
+
children,
|
|
58
|
+
className,
|
|
59
|
+
...rest
|
|
60
|
+
},
|
|
61
|
+
ref,
|
|
62
|
+
) {
|
|
37
63
|
return (
|
|
38
64
|
<button
|
|
65
|
+
ref={ref}
|
|
39
66
|
disabled={disabled || loading}
|
|
40
|
-
|
|
67
|
+
aria-busy={loading || undefined}
|
|
68
|
+
className={button({
|
|
69
|
+
variant,
|
|
70
|
+
size,
|
|
71
|
+
class: [full ? 'w-full' : '', className].filter(Boolean).join(' '),
|
|
72
|
+
})}
|
|
41
73
|
{...rest}
|
|
42
74
|
>
|
|
43
|
-
{loading
|
|
44
|
-
<svg className="h-4 w-4 animate-spin" viewBox="0 0 24 24" fill="none">
|
|
75
|
+
{loading ? (
|
|
76
|
+
<svg className="h-4 w-4 animate-spin" viewBox="0 0 24 24" fill="none" aria-hidden>
|
|
45
77
|
<circle
|
|
46
78
|
className="opacity-25"
|
|
47
79
|
cx="12"
|
|
@@ -56,8 +88,13 @@ export function Button({
|
|
|
56
88
|
d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"
|
|
57
89
|
/>
|
|
58
90
|
</svg>
|
|
91
|
+
) : (
|
|
92
|
+
leftIcon
|
|
59
93
|
)}
|
|
60
94
|
{children}
|
|
95
|
+
{!loading && rightIcon}
|
|
61
96
|
</button>
|
|
62
97
|
)
|
|
63
|
-
}
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
export { button as buttonVariants }
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { forwardRef, type HTMLAttributes, type ReactNode } from 'react'
|
|
2
|
+
import { cv, type VariantProps } from '../../lib/cv.js'
|
|
3
|
+
|
|
4
|
+
const card = cv(
|
|
5
|
+
'rounded-[var(--radius)] border border-[var(--border)] bg-[var(--card)] text-[var(--card-foreground)]',
|
|
6
|
+
{
|
|
7
|
+
variants: {
|
|
8
|
+
padding: {
|
|
9
|
+
none: 'p-0',
|
|
10
|
+
sm: 'p-4',
|
|
11
|
+
md: 'p-6',
|
|
12
|
+
lg: 'p-8',
|
|
13
|
+
},
|
|
14
|
+
elevation: {
|
|
15
|
+
flat: 'shadow-none',
|
|
16
|
+
sm: 'shadow-sm',
|
|
17
|
+
md: 'shadow-md',
|
|
18
|
+
lg: 'shadow-lg',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: { padding: 'md', elevation: 'sm' },
|
|
22
|
+
},
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
export type CardVariants = VariantProps<typeof card>
|
|
26
|
+
|
|
27
|
+
const INTERACTIVE_CLASS = 'transition-shadow hover:shadow-md focus-within:shadow-md'
|
|
28
|
+
|
|
29
|
+
export interface CardProps extends HTMLAttributes<HTMLDivElement>, CardVariants {
|
|
30
|
+
/** Apply hover/focus elevation transitions (e.g. for clickable cards). */
|
|
31
|
+
interactive?: boolean
|
|
32
|
+
children?: ReactNode
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const Card = forwardRef<HTMLDivElement, CardProps>(function Card(
|
|
36
|
+
{ padding, elevation, interactive, className, children, ...rest },
|
|
37
|
+
ref,
|
|
38
|
+
) {
|
|
39
|
+
const extras = [interactive ? INTERACTIVE_CLASS : '', className].filter(Boolean).join(' ')
|
|
40
|
+
return (
|
|
41
|
+
<div ref={ref} className={card({ padding, elevation, class: extras })} {...rest}>
|
|
42
|
+
{children}
|
|
43
|
+
</div>
|
|
44
|
+
)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Header slot — sits at the top of a card. Pair with CardTitle / CardDescription.
|
|
49
|
+
*/
|
|
50
|
+
export function CardHeader({ className = '', children, ...rest }: HTMLAttributes<HTMLDivElement>) {
|
|
51
|
+
return (
|
|
52
|
+
<div className={`flex flex-col space-y-1.5 ${className}`} {...rest}>
|
|
53
|
+
{children}
|
|
54
|
+
</div>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function CardTitle({
|
|
59
|
+
className = '',
|
|
60
|
+
children,
|
|
61
|
+
...rest
|
|
62
|
+
}: HTMLAttributes<HTMLHeadingElement>) {
|
|
63
|
+
return (
|
|
64
|
+
<h3
|
|
65
|
+
className={`text-lg leading-tight font-semibold tracking-tight text-[var(--card-foreground)] ${className}`}
|
|
66
|
+
{...rest}
|
|
67
|
+
>
|
|
68
|
+
{children}
|
|
69
|
+
</h3>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function CardDescription({
|
|
74
|
+
className = '',
|
|
75
|
+
children,
|
|
76
|
+
...rest
|
|
77
|
+
}: HTMLAttributes<HTMLParagraphElement>) {
|
|
78
|
+
return (
|
|
79
|
+
<p className={`text-sm text-[var(--muted-foreground)] ${className}`} {...rest}>
|
|
80
|
+
{children}
|
|
81
|
+
</p>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function CardContent({ className = '', children, ...rest }: HTMLAttributes<HTMLDivElement>) {
|
|
86
|
+
return (
|
|
87
|
+
<div className={className} {...rest}>
|
|
88
|
+
{children}
|
|
89
|
+
</div>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function CardFooter({ className = '', children, ...rest }: HTMLAttributes<HTMLDivElement>) {
|
|
94
|
+
return (
|
|
95
|
+
<div className={`flex items-center justify-end gap-2 pt-4 ${className}`} {...rest}>
|
|
96
|
+
{children}
|
|
97
|
+
</div>
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export { card as cardVariants }
|
|
@@ -161,7 +161,7 @@ function RowActionsMenu({ actions, row }: { actions: RowAction[]; row: Row }) {
|
|
|
161
161
|
<MoreVerticalIcon />
|
|
162
162
|
</button>
|
|
163
163
|
{open && (
|
|
164
|
-
<div className="absolute right-0
|
|
164
|
+
<div className="absolute top-full right-0 z-50 mt-1 w-40 rounded-md border border-[var(--border)] bg-[var(--popover)] py-1 shadow-lg">
|
|
165
165
|
{actions.map((action) => (
|
|
166
166
|
<button
|
|
167
167
|
key={action.key}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { forwardRef, type InputHTMLAttributes } from 'react'
|
|
2
|
+
import { cv, type VariantProps } from '../../lib/cv.js'
|
|
3
|
+
|
|
4
|
+
const input = cv(
|
|
5
|
+
'focus-visible:ring-offset-background flex w-full rounded-[var(--radius)] border bg-[var(--background)] text-[var(--foreground)] file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-[var(--muted-foreground)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
|
6
|
+
{
|
|
7
|
+
variants: {
|
|
8
|
+
size: {
|
|
9
|
+
sm: 'h-8 px-2.5 text-xs',
|
|
10
|
+
md: 'h-9 px-3 text-sm',
|
|
11
|
+
lg: 'h-10 px-4 text-base',
|
|
12
|
+
},
|
|
13
|
+
state: {
|
|
14
|
+
default: 'border-[var(--border)]',
|
|
15
|
+
invalid: 'border-[var(--destructive)] focus-visible:ring-[var(--destructive)]',
|
|
16
|
+
valid: 'border-emerald-500 focus-visible:ring-emerald-500',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
defaultVariants: { size: 'md', state: 'default' },
|
|
20
|
+
},
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
export type InputVariants = VariantProps<typeof input>
|
|
24
|
+
|
|
25
|
+
export interface InputProps
|
|
26
|
+
extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'>, InputVariants {}
|
|
27
|
+
|
|
28
|
+
export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
|
|
29
|
+
{ size, state, className, ...rest },
|
|
30
|
+
ref,
|
|
31
|
+
) {
|
|
32
|
+
return <input ref={ref} className={input({ size, state, class: className })} {...rest} />
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
export { input as inputVariants }
|
|
@@ -10,7 +10,7 @@ export function SearchInput({ value, onChange, placeholder = 'Search...' }: Sear
|
|
|
10
10
|
return (
|
|
11
11
|
<div className="relative flex-1">
|
|
12
12
|
<svg
|
|
13
|
-
className="absolute
|
|
13
|
+
className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-[var(--muted-foreground)]"
|
|
14
14
|
fill="none"
|
|
15
15
|
viewBox="0 0 24 24"
|
|
16
16
|
stroke="currentColor"
|
|
@@ -27,12 +27,12 @@ export function SearchInput({ value, onChange, placeholder = 'Search...' }: Sear
|
|
|
27
27
|
value={value}
|
|
28
28
|
onChange={(e) => onChange(e.target.value)}
|
|
29
29
|
placeholder={placeholder}
|
|
30
|
-
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] py-2 pl-9
|
|
30
|
+
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] py-2 pr-8 pl-9 text-sm outline-none focus:ring-2 focus:ring-[var(--ring)]"
|
|
31
31
|
/>
|
|
32
32
|
{value && (
|
|
33
33
|
<button
|
|
34
34
|
onClick={() => onChange('')}
|
|
35
|
-
className="absolute
|
|
35
|
+
className="absolute top-1/2 right-2 -translate-y-1/2 rounded p-0.5 text-[var(--muted-foreground)] hover:text-[var(--foreground)]"
|
|
36
36
|
aria-label="Clear search"
|
|
37
37
|
>
|
|
38
38
|
<svg
|
|
@@ -46,7 +46,7 @@ export function SearchInput({ value, onChange, placeholder = 'Search...' }: Sear
|
|
|
46
46
|
</svg>
|
|
47
47
|
</button>
|
|
48
48
|
)}
|
|
49
|
-
<kbd className="pointer-events-none absolute
|
|
49
|
+
<kbd className="pointer-events-none absolute top-1/2 right-8 hidden -translate-y-1/2 rounded border border-[var(--border)] px-1.5 py-0.5 text-[10px] text-[var(--muted-foreground)] sm:inline-block">
|
|
50
50
|
⌘K
|
|
51
51
|
</kbd>
|
|
52
52
|
</div>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { forwardRef, type SelectHTMLAttributes, type ReactNode } from 'react'
|
|
2
|
+
import { cv, type VariantProps } from '../../lib/cv.js'
|
|
3
|
+
|
|
4
|
+
const select = cv(
|
|
5
|
+
// Shares geometry with Input so they line up in forms.
|
|
6
|
+
'focus-visible:ring-offset-background flex w-full appearance-none rounded-[var(--radius)] border bg-[var(--background)] pr-8 text-[var(--foreground)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
size: {
|
|
10
|
+
sm: 'h-8 pr-7 pl-2.5 text-xs',
|
|
11
|
+
md: 'h-9 pr-8 pl-3 text-sm',
|
|
12
|
+
lg: 'h-10 pr-9 pl-4 text-base',
|
|
13
|
+
},
|
|
14
|
+
state: {
|
|
15
|
+
default: 'border-[var(--border)]',
|
|
16
|
+
invalid: 'border-[var(--destructive)] focus-visible:ring-[var(--destructive)]',
|
|
17
|
+
valid: 'border-emerald-500 focus-visible:ring-emerald-500',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: { size: 'md', state: 'default' },
|
|
21
|
+
},
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
export type SelectVariants = VariantProps<typeof select>
|
|
25
|
+
|
|
26
|
+
export interface SelectProps
|
|
27
|
+
extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'size'>, SelectVariants {
|
|
28
|
+
children?: ReactNode
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const Select = forwardRef<HTMLSelectElement, SelectProps>(function Select(
|
|
32
|
+
{ size, state, className, children, ...rest },
|
|
33
|
+
ref,
|
|
34
|
+
) {
|
|
35
|
+
return (
|
|
36
|
+
<div className="relative">
|
|
37
|
+
<select ref={ref} className={select({ size, state, class: className })} {...rest}>
|
|
38
|
+
{children}
|
|
39
|
+
</select>
|
|
40
|
+
<svg
|
|
41
|
+
aria-hidden
|
|
42
|
+
className="pointer-events-none absolute top-1/2 right-2 h-4 w-4 -translate-y-1/2 text-[var(--muted-foreground)]"
|
|
43
|
+
viewBox="0 0 20 20"
|
|
44
|
+
fill="currentColor"
|
|
45
|
+
>
|
|
46
|
+
<path
|
|
47
|
+
fillRule="evenodd"
|
|
48
|
+
d="M5.23 7.21a.75.75 0 011.06.02L10 11.06l3.71-3.83a.75.75 0 111.08 1.04l-4.25 4.39a.75.75 0 01-1.08 0L5.21 8.27a.75.75 0 01.02-1.06z"
|
|
49
|
+
clipRule="evenodd"
|
|
50
|
+
/>
|
|
51
|
+
</svg>
|
|
52
|
+
</div>
|
|
53
|
+
)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
export { select as selectVariants }
|
|
@@ -45,7 +45,7 @@ export function ToastContainer({ toasts, onDismiss }: ToastContainerProps) {
|
|
|
45
45
|
if (toasts.length === 0) return null
|
|
46
46
|
|
|
47
47
|
return (
|
|
48
|
-
<div className="fixed
|
|
48
|
+
<div className="fixed right-4 bottom-4 z-[100] flex flex-col gap-2">
|
|
49
49
|
{toasts.map((toast) => (
|
|
50
50
|
<div
|
|
51
51
|
key={toast.id}
|
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
export { Button } from './Button.js'
|
|
2
|
-
export type { ButtonProps } from './Button.js'
|
|
3
|
-
export { Badge } from './Badge.js'
|
|
4
|
-
export type { BadgeProps } from './Badge.js'
|
|
1
|
+
export { Button, buttonVariants } from './Button.js'
|
|
2
|
+
export type { ButtonProps, ButtonVariants } from './Button.js'
|
|
3
|
+
export { Badge, badgeVariants, STATUS_TONE, STATUS_LABEL } from './Badge.js'
|
|
4
|
+
export type { BadgeProps, BadgeVariants, DocumentStatus } from './Badge.js'
|
|
5
|
+
export {
|
|
6
|
+
Card,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle,
|
|
9
|
+
CardDescription,
|
|
10
|
+
CardContent,
|
|
11
|
+
CardFooter,
|
|
12
|
+
cardVariants,
|
|
13
|
+
} from './Card.js'
|
|
14
|
+
export type { CardProps, CardVariants } from './Card.js'
|
|
15
|
+
export { Input, inputVariants } from './Input.js'
|
|
16
|
+
export type { InputProps, InputVariants } from './Input.js'
|
|
17
|
+
export { Select, selectVariants } from './Select.js'
|
|
18
|
+
export type { SelectProps, SelectVariants } from './Select.js'
|
|
5
19
|
export { Avatar } from './Avatar.js'
|
|
6
20
|
export type { AvatarProps } from './Avatar.js'
|
|
7
21
|
export { EmptyState } from './EmptyState.js'
|
|
@@ -74,7 +74,7 @@ function BlockField({ field, value, onChange }: BlockFieldProps) {
|
|
|
74
74
|
<select
|
|
75
75
|
value={(value as string) ?? ''}
|
|
76
76
|
onChange={(e) => onChange(e.target.value)}
|
|
77
|
-
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm outline-none
|
|
77
|
+
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm transition-colors outline-none focus:ring-2 focus:ring-[var(--ring)]"
|
|
78
78
|
>
|
|
79
79
|
<option value="">Select...</option>
|
|
80
80
|
{field.options.map((opt) => (
|
|
@@ -98,7 +98,7 @@ function BlockField({ field, value, onChange }: BlockFieldProps) {
|
|
|
98
98
|
value={(value as string) ?? ''}
|
|
99
99
|
onChange={(e) => onChange(e.target.value)}
|
|
100
100
|
rows={4}
|
|
101
|
-
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm outline-none
|
|
101
|
+
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm transition-colors outline-none focus:ring-2 focus:ring-[var(--ring)]"
|
|
102
102
|
/>
|
|
103
103
|
</div>
|
|
104
104
|
)
|
|
@@ -134,7 +134,7 @@ function BlockField({ field, value, onChange }: BlockFieldProps) {
|
|
|
134
134
|
value={(value as string) ?? ''}
|
|
135
135
|
onChange={(e) => onChange(e.target.value)}
|
|
136
136
|
required={field.required}
|
|
137
|
-
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm outline-none
|
|
137
|
+
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm transition-colors outline-none focus:ring-2 focus:ring-[var(--ring)]"
|
|
138
138
|
/>
|
|
139
139
|
</div>
|
|
140
140
|
)
|
package/src/fields/DateField.tsx
CHANGED
|
@@ -25,7 +25,7 @@ export function DateField({ label, value = '', onChange, required, helpText }: D
|
|
|
25
25
|
/>
|
|
26
26
|
<button
|
|
27
27
|
type="button"
|
|
28
|
-
className="absolute
|
|
28
|
+
className="absolute top-1/2 right-2 -translate-y-1/2 text-[var(--muted-foreground)]"
|
|
29
29
|
aria-label="Open calendar"
|
|
30
30
|
>
|
|
31
31
|
<svg
|
|
@@ -158,12 +158,12 @@ export function RelationshipField({
|
|
|
158
158
|
onClick={() => handleToggle(opt.id)}
|
|
159
159
|
className={`flex w-full items-center gap-2 px-3 py-2 text-sm hover:bg-[var(--accent)] ${isSelected ? 'font-medium' : ''}`}
|
|
160
160
|
>
|
|
161
|
-
<div className="
|
|
161
|
+
<div className="min-w-0 flex-1 text-left">
|
|
162
162
|
<div className="flex items-center gap-2">
|
|
163
163
|
<span className="truncate">{getDocTitle(opt)}</span>
|
|
164
164
|
{isSelected && <span className="shrink-0 text-[var(--primary)]">✓</span>}
|
|
165
165
|
</div>
|
|
166
|
-
<div className="flex items-center gap-2
|
|
166
|
+
<div className="mt-0.5 flex items-center gap-2">
|
|
167
167
|
<span className="text-[10px] text-[var(--muted-foreground)]">{collection}</span>
|
|
168
168
|
{opt.updatedAt && (
|
|
169
169
|
<span className="text-[10px] text-[var(--muted-foreground)]">
|
|
@@ -201,7 +201,7 @@ export function RelationshipField({
|
|
|
201
201
|
onClick={() => handleRemove(item.id)}
|
|
202
202
|
className="hover:text-[var(--destructive)]"
|
|
203
203
|
>
|
|
204
|
-
<X className="
|
|
204
|
+
<X className="h-3 w-3" />
|
|
205
205
|
</button>
|
|
206
206
|
</span>
|
|
207
207
|
))}
|
|
@@ -209,26 +209,26 @@ export function RelationshipField({
|
|
|
209
209
|
)}
|
|
210
210
|
|
|
211
211
|
<div className="relative">
|
|
212
|
-
<Search className="absolute left-2.5
|
|
212
|
+
<Search className="pointer-events-none absolute top-1/2 left-2.5 h-4 w-4 -translate-y-1/2 text-[var(--muted-foreground)]" />
|
|
213
213
|
<input
|
|
214
214
|
type="text"
|
|
215
215
|
value={searchTerm}
|
|
216
216
|
onChange={(e) => handleSearch(e.target.value)}
|
|
217
217
|
onFocus={() => setOpen(true)}
|
|
218
218
|
placeholder={`Search ${relationTo}...`}
|
|
219
|
-
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)]
|
|
219
|
+
className="w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] py-2 pr-3 pl-8 text-sm outline-none focus:ring-2 focus:ring-[var(--ring)]"
|
|
220
220
|
/>
|
|
221
221
|
{loading && (
|
|
222
|
-
<Loader2 className="absolute right-2.5
|
|
222
|
+
<Loader2 className="absolute top-1/2 right-2.5 h-4 w-4 -translate-y-1/2 animate-spin text-[var(--muted-foreground)]" />
|
|
223
223
|
)}
|
|
224
224
|
|
|
225
225
|
{open && (
|
|
226
|
-
<ul className="absolute z-50 mt-1
|
|
226
|
+
<ul className="absolute z-50 mt-1 max-h-60 w-full overflow-y-auto rounded-md border border-[var(--border)] bg-[var(--popover)] py-1 shadow-lg">
|
|
227
227
|
{unselectedItems.map((opt) => (
|
|
228
228
|
<li key={opt.id}>{renderOption(opt, false)}</li>
|
|
229
229
|
))}
|
|
230
230
|
{selectedItems.length > 0 && unselectedItems.length > 0 && (
|
|
231
|
-
<li className="border-t border-[var(--border)]
|
|
231
|
+
<li className="my-1 border-t border-[var(--border)]" />
|
|
232
232
|
)}
|
|
233
233
|
{selectedItems.map((opt) => (
|
|
234
234
|
<li key={opt.id}>{renderOption(opt, true)}</li>
|
|
@@ -236,7 +236,7 @@ export function RelationshipField({
|
|
|
236
236
|
{options.length === 0 && !loading && (
|
|
237
237
|
<li className="px-3 py-2 text-sm text-[var(--muted-foreground)]">No results</li>
|
|
238
238
|
)}
|
|
239
|
-
<li className="border-t border-[var(--border)]
|
|
239
|
+
<li className="mt-1 border-t border-[var(--border)]">
|
|
240
240
|
<button
|
|
241
241
|
type="button"
|
|
242
242
|
onClick={() => {
|
|
@@ -245,7 +245,7 @@ export function RelationshipField({
|
|
|
245
245
|
}}
|
|
246
246
|
className="flex w-full items-center gap-2 px-3 py-2 text-sm text-[var(--primary)] hover:bg-[var(--accent)]"
|
|
247
247
|
>
|
|
248
|
-
<Plus className="
|
|
248
|
+
<Plus className="h-3.5 w-3.5" />
|
|
249
249
|
Create New
|
|
250
250
|
</button>
|
|
251
251
|
</li>
|
package/src/fields/TextField.tsx
CHANGED
|
@@ -43,7 +43,7 @@ export function TextField({
|
|
|
43
43
|
onChange={(e) => onChange(e.target.value)}
|
|
44
44
|
required={required}
|
|
45
45
|
maxLength={maxLength}
|
|
46
|
-
className={`w-full rounded-md border bg-[var(--input-background)] px-3 py-2 text-sm outline-none
|
|
46
|
+
className={`w-full rounded-md border bg-[var(--input-background)] px-3 py-2 text-sm transition-colors outline-none focus:ring-2 focus:ring-[var(--ring)] ${
|
|
47
47
|
hasError ? 'border-[var(--destructive)]' : 'border-[var(--border)]'
|
|
48
48
|
}`}
|
|
49
49
|
/>
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,34 @@ export type { SidebarProps } from './layout/Sidebar.js'
|
|
|
8
8
|
export { Header } from './layout/Header.js'
|
|
9
9
|
export type { HeaderProps } from './layout/Header.js'
|
|
10
10
|
|
|
11
|
+
// Layout primitives — the sanctioned way to compose admin views.
|
|
12
|
+
// Always prefer these to hand-rolled flex/grid utilities.
|
|
13
|
+
export {
|
|
14
|
+
AdminShell,
|
|
15
|
+
PageContainer,
|
|
16
|
+
Stack,
|
|
17
|
+
Cluster,
|
|
18
|
+
Grid,
|
|
19
|
+
Split,
|
|
20
|
+
Box,
|
|
21
|
+
tokens,
|
|
22
|
+
} from './layout/primitives/index.js'
|
|
23
|
+
export type {
|
|
24
|
+
AdminShellProps,
|
|
25
|
+
PageContainerProps,
|
|
26
|
+
StackProps,
|
|
27
|
+
StackSpace,
|
|
28
|
+
ClusterProps,
|
|
29
|
+
ClusterAlign,
|
|
30
|
+
ClusterJustify,
|
|
31
|
+
GridProps,
|
|
32
|
+
GridResponsive,
|
|
33
|
+
SplitProps,
|
|
34
|
+
BoxProps,
|
|
35
|
+
SpaceToken,
|
|
36
|
+
RadiusToken,
|
|
37
|
+
} from './layout/primitives/index.js'
|
|
38
|
+
|
|
11
39
|
export { Dashboard } from './views/Dashboard.js'
|
|
12
40
|
export { Posts } from './views/Posts.js'
|
|
13
41
|
export { Pages } from './views/Pages.js'
|
|
@@ -60,6 +88,10 @@ export type { SEOData, SEOPanelProps } from './components/SEOPanel.js'
|
|
|
60
88
|
export { LivePreview } from './components/LivePreview.js'
|
|
61
89
|
export { VersionHistory } from './components/VersionHistory.js'
|
|
62
90
|
export type { VersionHistoryProps } from './components/VersionHistory.js'
|
|
91
|
+
export { SchedulePublishDialog } from './components/SchedulePublishDialog.js'
|
|
92
|
+
export type { SchedulePublishDialogProps } from './components/SchedulePublishDialog.js'
|
|
93
|
+
export { SharePreviewLinkDialog } from './components/SharePreviewLinkDialog.js'
|
|
94
|
+
export type { SharePreviewLinkDialogProps } from './components/SharePreviewLinkDialog.js'
|
|
63
95
|
export { MediaPickerModal } from './components/MediaPickerModal.js'
|
|
64
96
|
export type { MediaPickerModalProps } from './components/MediaPickerModal.js'
|
|
65
97
|
export { ThemeProvider, useTheme } from './components/ThemeProvider.js'
|