@actuate-media/cms-admin 0.63.2 → 0.64.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/CHANGELOG.md +10 -0
- package/design-system/README.md +53 -0
- package/design-system/tokens.css +114 -0
- package/design-system/tokens.json +149 -0
- package/design-system/tokens.scss +108 -0
- package/design-system/tokens.tailwind.cjs +80 -0
- package/dist/__tests__/layout/primitives.test.js +9 -2
- package/dist/__tests__/layout/primitives.test.js.map +1 -1
- package/dist/actuate-admin.css +1 -1
- package/dist/components/EnabledSwitch.d.ts +2 -5
- package/dist/components/EnabledSwitch.d.ts.map +1 -1
- package/dist/components/EnabledSwitch.js +4 -7
- package/dist/components/EnabledSwitch.js.map +1 -1
- package/dist/components/ThemeProvider.d.ts.map +1 -1
- package/dist/components/ThemeProvider.js +5 -3
- package/dist/components/ThemeProvider.js.map +1 -1
- package/dist/components/forms/FieldsPanel.js +2 -2
- package/dist/components/forms/FieldsPanel.js.map +1 -1
- package/dist/components/forms/NotificationsPanel.js +2 -2
- package/dist/components/forms/NotificationsPanel.js.map +1 -1
- package/dist/components/forms/WebhooksPanel.d.ts.map +1 -1
- package/dist/components/forms/WebhooksPanel.js +2 -2
- package/dist/components/forms/WebhooksPanel.js.map +1 -1
- package/dist/components/seo/primitives.d.ts.map +1 -1
- package/dist/components/seo/primitives.js +2 -1
- package/dist/components/seo/primitives.js.map +1 -1
- package/dist/components/ui/Button.d.ts +1 -1
- package/dist/components/ui/Button.js +1 -1
- package/dist/components/ui/Button.js.map +1 -1
- package/dist/components/ui/Card.d.ts +6 -5
- package/dist/components/ui/Card.d.ts.map +1 -1
- package/dist/components/ui/Card.js +20 -18
- package/dist/components/ui/Card.js.map +1 -1
- package/dist/components/ui/Input.d.ts +2 -1
- package/dist/components/ui/Input.d.ts.map +1 -1
- package/dist/components/ui/Input.js +9 -8
- package/dist/components/ui/Input.js.map +1 -1
- package/dist/components/ui/SearchInput.d.ts.map +1 -1
- package/dist/components/ui/SearchInput.js +2 -1
- package/dist/components/ui/SearchInput.js.map +1 -1
- package/dist/components/ui/Select.d.ts.map +1 -1
- package/dist/components/ui/Select.js +9 -10
- package/dist/components/ui/Select.js.map +1 -1
- package/dist/components/ui/Toggle.d.ts +31 -0
- package/dist/components/ui/Toggle.d.ts.map +1 -0
- package/dist/components/ui/Toggle.js +41 -0
- package/dist/components/ui/Toggle.js.map +1 -0
- package/dist/components/ui/form-control.d.ts +11 -0
- package/dist/components/ui/form-control.d.ts.map +1 -0
- package/dist/components/ui/form-control.js +11 -0
- package/dist/components/ui/form-control.js.map +1 -0
- package/dist/components/ui/index.d.ts +3 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +2 -0
- package/dist/components/ui/index.js.map +1 -1
- package/dist/layout/Header.d.ts.map +1 -1
- package/dist/layout/Header.js +5 -2
- package/dist/layout/Header.js.map +1 -1
- package/dist/layout/Sidebar.js +1 -1
- package/dist/layout/Sidebar.js.map +1 -1
- package/dist/layout/primitives/tokens.d.ts +10 -4
- package/dist/layout/primitives/tokens.d.ts.map +1 -1
- package/dist/layout/primitives/tokens.js +10 -4
- package/dist/layout/primitives/tokens.js.map +1 -1
- package/dist/views/Forms.js +2 -2
- package/dist/views/Forms.js.map +1 -1
- package/dist/views/page-builder/BottomBar.d.ts.map +1 -1
- package/dist/views/page-builder/BottomBar.js +2 -2
- package/dist/views/page-builder/BottomBar.js.map +1 -1
- package/dist/views/seo/TechnicalTab.d.ts.map +1 -1
- package/dist/views/seo/TechnicalTab.js +2 -2
- package/dist/views/seo/TechnicalTab.js.map +1 -1
- package/dist/views/settings/components.d.ts.map +1 -1
- package/dist/views/settings/components.js +2 -1
- package/dist/views/settings/components.js.map +1 -1
- package/package.json +8 -3
- package/src/__tests__/layout/primitives.test.ts +10 -2
- package/src/components/EnabledSwitch.tsx +4 -22
- package/src/components/ThemeProvider.tsx +5 -3
- package/src/components/forms/FieldsPanel.tsx +4 -6
- package/src/components/forms/NotificationsPanel.tsx +2 -9
- package/src/components/forms/WebhooksPanel.tsx +4 -6
- package/src/components/seo/primitives.tsx +8 -7
- package/src/components/ui/Button.tsx +1 -1
- package/src/components/ui/Card.tsx +35 -18
- package/src/components/ui/Input.tsx +15 -17
- package/src/components/ui/SearchInput.tsx +9 -4
- package/src/components/ui/Select.tsx +15 -18
- package/src/components/ui/Toggle.tsx +85 -0
- package/src/components/ui/form-control.ts +12 -0
- package/src/components/ui/index.ts +3 -0
- package/src/layout/Header.tsx +6 -2
- package/src/layout/Sidebar.tsx +3 -3
- package/src/layout/primitives/tokens.ts +11 -4
- package/src/styles/actuate-tokens.css +97 -0
- package/src/styles/theme.css +88 -156
- package/src/views/Forms.tsx +4 -6
- package/src/views/page-builder/BottomBar.tsx +3 -6
- package/src/views/seo/TechnicalTab.tsx +3 -6
- package/src/views/settings/components.tsx +11 -10
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared form-control surface styles (`.inp` in the design system handoff).
|
|
3
|
+
* Imported by Input and Select so geometry stays aligned.
|
|
4
|
+
*/
|
|
5
|
+
export const formControlBase =
|
|
6
|
+
'w-full rounded-[var(--r-control)] border border-[var(--bdr)] bg-[var(--bg)] px-3 py-[9px] text-[length:var(--fs-body)] text-[var(--txt)] outline-none transition-[border-color] duration-150 placeholder:text-[var(--muted)] focus:border-[var(--acc-m)] focus-visible:border-[var(--acc-m)] disabled:cursor-not-allowed disabled:opacity-50'
|
|
7
|
+
|
|
8
|
+
export const formControlState = {
|
|
9
|
+
default: '',
|
|
10
|
+
invalid: 'border-[var(--err)] focus:border-[var(--err)] focus-visible:border-[var(--err)]',
|
|
11
|
+
valid: 'border-[var(--suc)] focus:border-[var(--suc)] focus-visible:border-[var(--suc)]',
|
|
12
|
+
} as const
|
|
@@ -34,5 +34,8 @@ export { Pagination } from './Pagination.js'
|
|
|
34
34
|
export type { PaginationProps } from './Pagination.js'
|
|
35
35
|
export { SearchInput } from './SearchInput.js'
|
|
36
36
|
export type { SearchInputProps } from './SearchInput.js'
|
|
37
|
+
export { Toggle, toggleTrackVariants, toggleThumbVariants } from './Toggle.js'
|
|
38
|
+
export type { ToggleProps, ToggleVariants } from './Toggle.js'
|
|
39
|
+
export { formControlBase, formControlState } from './form-control.js'
|
|
37
40
|
export { CommandPalette } from './CommandPalette.js'
|
|
38
41
|
export type { CommandPaletteProps } from './CommandPalette.js'
|
package/src/layout/Header.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import { CommandPalette } from '../components/CommandPalette.js'
|
|
|
8
8
|
import { NotificationBell } from '../components/NotificationBell.js'
|
|
9
9
|
import { useTheme } from '../components/ThemeProvider.js'
|
|
10
10
|
import { LocaleSwitcher } from '../components/LocaleSwitcher.js'
|
|
11
|
+
import { inputVariants } from '../components/ui/Input.js'
|
|
11
12
|
|
|
12
13
|
export interface HeaderProps {
|
|
13
14
|
onToggleSidebar: () => void
|
|
@@ -51,7 +52,7 @@ export function Header({
|
|
|
51
52
|
|
|
52
53
|
return (
|
|
53
54
|
<>
|
|
54
|
-
<header className="border-border bg-
|
|
55
|
+
<header className="border-sidebar-border bg-sidebar flex h-[var(--tbh)] items-center gap-3 border-b px-4">
|
|
55
56
|
<button
|
|
56
57
|
onClick={onToggleSidebar}
|
|
57
58
|
className="hover:bg-accent rounded-lg p-2 transition-colors md:hidden"
|
|
@@ -77,7 +78,10 @@ export function Header({
|
|
|
77
78
|
onKeyDown={(e) => {
|
|
78
79
|
if (e.key === 'Escape') (e.target as HTMLInputElement).blur()
|
|
79
80
|
}}
|
|
80
|
-
className=
|
|
81
|
+
className={inputVariants({
|
|
82
|
+
class:
|
|
83
|
+
'h-9 w-full max-w-md py-1.5 pr-14 pl-9 focus-visible:ring-0 focus-visible:ring-offset-0',
|
|
84
|
+
})}
|
|
81
85
|
/>
|
|
82
86
|
{/* Keyboard hint pill. Hidden on narrow widths to avoid overlap. */}
|
|
83
87
|
<span
|
package/src/layout/Sidebar.tsx
CHANGED
|
@@ -253,13 +253,13 @@ export function Sidebar({
|
|
|
253
253
|
|
|
254
254
|
return (
|
|
255
255
|
<aside
|
|
256
|
-
className={`bg-sidebar border-sidebar-border flex h-full flex-col border-r transition-
|
|
257
|
-
collapsed ? 'w-
|
|
256
|
+
className={`bg-sidebar border-sidebar-border flex h-full flex-col border-r transition-[width] duration-[var(--motion-layout)] ${
|
|
257
|
+
collapsed ? 'w-[var(--sbw-col)]' : 'w-[var(--sbw)]'
|
|
258
258
|
}`}
|
|
259
259
|
>
|
|
260
260
|
{/* Brand header — no toggle button here anymore; it now lives in the footer. */}
|
|
261
261
|
<div
|
|
262
|
-
className={`border-sidebar-border flex h-
|
|
262
|
+
className={`border-sidebar-border flex h-[var(--tbh)] shrink-0 items-center border-b px-4 ${
|
|
263
263
|
collapsed ? 'justify-center' : ''
|
|
264
264
|
}`}
|
|
265
265
|
>
|
|
@@ -49,13 +49,20 @@ export const tokens = {
|
|
|
49
49
|
|
|
50
50
|
radius: {
|
|
51
51
|
none: 0,
|
|
52
|
-
sm:
|
|
53
|
-
md:
|
|
54
|
-
lg:
|
|
52
|
+
sm: 6,
|
|
53
|
+
md: 8,
|
|
54
|
+
lg: 10,
|
|
55
55
|
xl: 12,
|
|
56
|
-
full:
|
|
56
|
+
full: 99,
|
|
57
57
|
} as const satisfies Record<RadiusToken, number>,
|
|
58
58
|
|
|
59
|
+
/** Layout dimensions from the design system (px). */
|
|
60
|
+
layout: {
|
|
61
|
+
sidebarWidth: 224,
|
|
62
|
+
sidebarWidthCollapsed: 60,
|
|
63
|
+
topbarHeight: 56,
|
|
64
|
+
} as const,
|
|
65
|
+
|
|
59
66
|
// Breakpoints mirror Tailwind defaults so primitives can compose with
|
|
60
67
|
// utility classes without surprises. Use `matchMedia(`(min-width: …`)` to
|
|
61
68
|
// sync JS-driven layout decisions with these values.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ActuateCMS design tokens — scoped to the admin root.
|
|
3
|
+
* Source: design-system/tokens.json (v1.0).
|
|
4
|
+
* Appearance accent overrides set --acc / --primary at runtime.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
.actuate-admin {
|
|
8
|
+
/* Surfaces */
|
|
9
|
+
--bg: #f5f4fa;
|
|
10
|
+
--sb: #ffffff;
|
|
11
|
+
--card: #ffffff;
|
|
12
|
+
--bdr: #e8e6f2;
|
|
13
|
+
|
|
14
|
+
/* Text */
|
|
15
|
+
--txt: #1a1827;
|
|
16
|
+
--sub: #6b6878;
|
|
17
|
+
--muted: #b0adbe;
|
|
18
|
+
|
|
19
|
+
/* Accent */
|
|
20
|
+
--acc: #7c3aed;
|
|
21
|
+
--acc-l: #ede9fe;
|
|
22
|
+
--acc-m: #c4b5fd;
|
|
23
|
+
|
|
24
|
+
/* Semantic */
|
|
25
|
+
--suc: #059669;
|
|
26
|
+
--suc-l: #ecfdf5;
|
|
27
|
+
--warn: #d97706;
|
|
28
|
+
--warn-l: #fffbeb;
|
|
29
|
+
--err: #dc2626;
|
|
30
|
+
--err-l: #fef2f2;
|
|
31
|
+
--info: #0891b2;
|
|
32
|
+
--info-l: #e0f7fa;
|
|
33
|
+
|
|
34
|
+
/* AI */
|
|
35
|
+
--ai1: #7c3aed;
|
|
36
|
+
--ai2: #c026d3;
|
|
37
|
+
--ai-soft: linear-gradient(135deg, rgba(124, 58, 237, 0.09), rgba(192, 38, 211, 0.07));
|
|
38
|
+
|
|
39
|
+
/* Layout */
|
|
40
|
+
--sbw: 224px;
|
|
41
|
+
--sbw-col: 60px;
|
|
42
|
+
--tbh: 56px;
|
|
43
|
+
--r: 10px;
|
|
44
|
+
--r-control: 8px;
|
|
45
|
+
--r-sm: 6px;
|
|
46
|
+
--r-pill: 99px;
|
|
47
|
+
|
|
48
|
+
/* Elevation */
|
|
49
|
+
--shd: 0 1px 2px rgba(0, 0, 0, 0.05), 0 1px 4px rgba(0, 0, 0, 0.04);
|
|
50
|
+
--shd2: 0 4px 16px rgba(0, 0, 0, 0.1);
|
|
51
|
+
|
|
52
|
+
/* Typography */
|
|
53
|
+
--font-sans: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
54
|
+
--font-mono: 'DM Mono', ui-monospace, 'SFMono-Regular', monospace;
|
|
55
|
+
--fs-page: 21px;
|
|
56
|
+
--fs-card: 14px;
|
|
57
|
+
--fs-body: 13px;
|
|
58
|
+
--fs-sub: 12px;
|
|
59
|
+
--fs-hint: 11.5px;
|
|
60
|
+
--fs-label: 10px;
|
|
61
|
+
|
|
62
|
+
/* Motion */
|
|
63
|
+
--motion-fast: 0.12s;
|
|
64
|
+
--motion-base: 0.18s;
|
|
65
|
+
--motion-layout: 0.22s cubic-bezier(0.4, 0, 0.2, 1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.dark .actuate-admin,
|
|
69
|
+
.actuate-admin.dark,
|
|
70
|
+
.actuate-admin[data-theme='dark'] {
|
|
71
|
+
--bg: #0d0c18;
|
|
72
|
+
--sb: #141222;
|
|
73
|
+
--card: #1c1a2e;
|
|
74
|
+
--bdr: #2c2a42;
|
|
75
|
+
|
|
76
|
+
--txt: #eae8f5;
|
|
77
|
+
--sub: #8e8ba8;
|
|
78
|
+
--muted: #504e68;
|
|
79
|
+
|
|
80
|
+
--acc: #9d71f0;
|
|
81
|
+
--acc-l: #231950;
|
|
82
|
+
--acc-m: #5e3eaa;
|
|
83
|
+
|
|
84
|
+
--suc: #10b981;
|
|
85
|
+
--suc-l: #022c22;
|
|
86
|
+
--warn: #fbbf24;
|
|
87
|
+
--warn-l: #1a1000;
|
|
88
|
+
--err: #f87171;
|
|
89
|
+
--err-l: #200808;
|
|
90
|
+
--info: #38bdf8;
|
|
91
|
+
--info-l: #0a2838;
|
|
92
|
+
|
|
93
|
+
--ai-soft: linear-gradient(135deg, rgba(157, 113, 240, 0.16), rgba(192, 38, 211, 0.12));
|
|
94
|
+
|
|
95
|
+
--shd: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.2);
|
|
96
|
+
--shd2: 0 4px 20px rgba(0, 0, 0, 0.45);
|
|
97
|
+
}
|
package/src/styles/theme.css
CHANGED
|
@@ -1,113 +1,74 @@
|
|
|
1
1
|
@custom-variant dark (&:is(.dark *));
|
|
2
2
|
|
|
3
|
+
@import './actuate-tokens.css';
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* Semantic Tailwind tokens mapped from the ActuateCMS design system.
|
|
7
|
+
* Raw tokens live in actuate-tokens.css; Appearance accent overrides
|
|
8
|
+
* mutate --acc, --primary, --sidebar-primary, etc. at runtime.
|
|
9
|
+
*/
|
|
3
10
|
.actuate-admin {
|
|
4
|
-
--font-size:
|
|
5
|
-
--background:
|
|
6
|
-
--foreground:
|
|
7
|
-
--card
|
|
8
|
-
--card-foreground:
|
|
9
|
-
--popover:
|
|
10
|
-
--popover-foreground:
|
|
11
|
-
--primary:
|
|
12
|
-
--primary-foreground:
|
|
13
|
-
--secondary:
|
|
14
|
-
--secondary-foreground:
|
|
15
|
-
--muted:
|
|
16
|
-
--muted-foreground:
|
|
17
|
-
--accent:
|
|
18
|
-
--accent-foreground:
|
|
19
|
-
--destructive:
|
|
11
|
+
--font-size: var(--fs-body);
|
|
12
|
+
--background: var(--bg);
|
|
13
|
+
--foreground: var(--txt);
|
|
14
|
+
/* --card surface token is defined in actuate-tokens.css */
|
|
15
|
+
--card-foreground: var(--txt);
|
|
16
|
+
--popover: var(--card);
|
|
17
|
+
--popover-foreground: var(--txt);
|
|
18
|
+
--primary: var(--acc);
|
|
19
|
+
--primary-foreground: #ffffff;
|
|
20
|
+
--secondary: var(--acc-l);
|
|
21
|
+
--secondary-foreground: var(--txt);
|
|
22
|
+
--muted: color-mix(in srgb, var(--bdr) 55%, var(--card));
|
|
23
|
+
--muted-foreground: var(--sub);
|
|
24
|
+
--accent: var(--acc-l);
|
|
25
|
+
--accent-foreground: var(--acc);
|
|
26
|
+
--destructive: var(--err);
|
|
20
27
|
--destructive-foreground: #ffffff;
|
|
21
|
-
|
|
22
|
-
* Semantic status + brand tokens.
|
|
23
|
-
* ----------------------------------------------------------------
|
|
24
|
-
* `destructive` already covers the "error/danger" state; these add
|
|
25
|
-
* the remaining semantic states the admin needs (success / warning /
|
|
26
|
-
* info) plus the violet brand accent used for links and primary
|
|
27
|
-
* affordances. Values are tuned to read as TEXT on both the card
|
|
28
|
-
* surface and their own `/10` tint (badge backgrounds), and as a
|
|
29
|
-
* solid fill (dots, progress bars). The `*-foreground` variants are
|
|
30
|
-
* for text placed on a SOLID fill. Light values match the previous
|
|
31
|
-
* emerald/amber/blue/violet-600 palette so tokenizing is a no-op
|
|
32
|
-
* visually; dark values track the *-300/*-400 tints used before.
|
|
33
|
-
*/
|
|
34
|
-
--success: oklch(0.5 0.13 155);
|
|
28
|
+
--success: var(--suc);
|
|
35
29
|
--success-foreground: #ffffff;
|
|
36
|
-
--warning:
|
|
37
|
-
--warning-foreground:
|
|
38
|
-
--info:
|
|
30
|
+
--warning: var(--warn);
|
|
31
|
+
--warning-foreground: var(--txt);
|
|
32
|
+
--info: var(--info);
|
|
39
33
|
--info-foreground: #ffffff;
|
|
40
|
-
--brand:
|
|
34
|
+
--brand: var(--acc);
|
|
41
35
|
--brand-foreground: #ffffff;
|
|
42
|
-
--border:
|
|
36
|
+
--border: var(--bdr);
|
|
43
37
|
--input: transparent;
|
|
44
|
-
--input-background:
|
|
45
|
-
--switch-background:
|
|
38
|
+
--input-background: var(--card);
|
|
39
|
+
--switch-background: var(--bdr);
|
|
46
40
|
--font-weight-medium: 500;
|
|
47
41
|
--font-weight-normal: 400;
|
|
48
|
-
--ring:
|
|
49
|
-
--chart-1:
|
|
50
|
-
--chart-2:
|
|
51
|
-
--chart-3:
|
|
52
|
-
--chart-4:
|
|
53
|
-
--chart-5:
|
|
54
|
-
--radius:
|
|
55
|
-
--sidebar:
|
|
56
|
-
--sidebar-foreground:
|
|
57
|
-
--sidebar-primary:
|
|
58
|
-
--sidebar-primary-foreground:
|
|
59
|
-
--sidebar-accent:
|
|
60
|
-
--sidebar-accent-foreground:
|
|
61
|
-
--sidebar-border:
|
|
62
|
-
--sidebar-ring:
|
|
42
|
+
--ring: var(--acc-m);
|
|
43
|
+
--chart-1: var(--acc);
|
|
44
|
+
--chart-2: var(--info);
|
|
45
|
+
--chart-3: var(--suc);
|
|
46
|
+
--chart-4: var(--warn);
|
|
47
|
+
--chart-5: var(--err);
|
|
48
|
+
--radius: var(--r);
|
|
49
|
+
--sidebar: var(--sb);
|
|
50
|
+
--sidebar-foreground: var(--txt);
|
|
51
|
+
--sidebar-primary: var(--acc);
|
|
52
|
+
--sidebar-primary-foreground: #ffffff;
|
|
53
|
+
--sidebar-accent: var(--acc-l);
|
|
54
|
+
--sidebar-accent-foreground: var(--acc);
|
|
55
|
+
--sidebar-border: var(--bdr);
|
|
56
|
+
--sidebar-ring: var(--acc-m);
|
|
57
|
+
--shadow-card: var(--shd);
|
|
58
|
+
--shadow-elevated: var(--shd2);
|
|
63
59
|
}
|
|
64
60
|
|
|
65
61
|
.dark .actuate-admin,
|
|
66
62
|
.actuate-admin.dark {
|
|
67
|
-
--
|
|
68
|
-
--foreground:
|
|
69
|
-
--
|
|
70
|
-
--
|
|
71
|
-
--
|
|
72
|
-
--
|
|
73
|
-
--
|
|
74
|
-
--primary-foreground:
|
|
75
|
-
--
|
|
76
|
-
--secondary-foreground: oklch(0.985 0 0);
|
|
77
|
-
--muted: oklch(0.269 0 0);
|
|
78
|
-
--muted-foreground: oklch(0.708 0 0);
|
|
79
|
-
--accent: oklch(0.269 0 0);
|
|
80
|
-
--accent-foreground: oklch(0.985 0 0);
|
|
81
|
-
--destructive: oklch(0.396 0.141 25.723);
|
|
82
|
-
--destructive-foreground: oklch(0.637 0.237 25.331);
|
|
83
|
-
--success: oklch(0.72 0.15 155);
|
|
84
|
-
--success-foreground: oklch(0.205 0 0);
|
|
85
|
-
--warning: oklch(0.8 0.13 80);
|
|
86
|
-
--warning-foreground: oklch(0.205 0 0);
|
|
87
|
-
--info: oklch(0.72 0.14 252);
|
|
88
|
-
--info-foreground: oklch(0.205 0 0);
|
|
89
|
-
--brand: oklch(0.72 0.18 293);
|
|
90
|
-
--brand-foreground: oklch(0.205 0 0);
|
|
91
|
-
--border: oklch(0.269 0 0);
|
|
92
|
-
--input: oklch(0.269 0 0);
|
|
93
|
-
--input-background: oklch(0.205 0 0);
|
|
94
|
-
--switch-background: oklch(0.35 0 0);
|
|
95
|
-
--ring: oklch(0.439 0 0);
|
|
96
|
-
--font-weight-medium: 500;
|
|
97
|
-
--font-weight-normal: 400;
|
|
98
|
-
--chart-1: oklch(0.488 0.243 264.376);
|
|
99
|
-
--chart-2: oklch(0.696 0.17 162.48);
|
|
100
|
-
--chart-3: oklch(0.769 0.188 70.08);
|
|
101
|
-
--chart-4: oklch(0.627 0.265 303.9);
|
|
102
|
-
--chart-5: oklch(0.645 0.246 16.439);
|
|
103
|
-
--sidebar: oklch(0.205 0 0);
|
|
104
|
-
--sidebar-foreground: oklch(0.985 0 0);
|
|
105
|
-
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
106
|
-
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
107
|
-
--sidebar-accent: oklch(0.269 0 0);
|
|
108
|
-
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
109
|
-
--sidebar-border: oklch(0.269 0 0);
|
|
110
|
-
--sidebar-ring: oklch(0.439 0 0);
|
|
63
|
+
--primary-foreground: #0d0c18;
|
|
64
|
+
--secondary-foreground: var(--txt);
|
|
65
|
+
--warning-foreground: var(--txt);
|
|
66
|
+
--brand-foreground: #0d0c18;
|
|
67
|
+
--success-foreground: #0d0c18;
|
|
68
|
+
--info-foreground: #0d0c18;
|
|
69
|
+
--destructive-foreground: #0d0c18;
|
|
70
|
+
--sidebar-primary-foreground: #0d0c18;
|
|
71
|
+
--muted: color-mix(in srgb, var(--bdr) 40%, var(--card));
|
|
111
72
|
}
|
|
112
73
|
|
|
113
74
|
@theme inline {
|
|
@@ -145,10 +106,10 @@
|
|
|
145
106
|
--color-chart-3: var(--chart-3);
|
|
146
107
|
--color-chart-4: var(--chart-4);
|
|
147
108
|
--color-chart-5: var(--chart-5);
|
|
148
|
-
--radius-sm:
|
|
149
|
-
--radius-md:
|
|
150
|
-
--radius-lg: var(--
|
|
151
|
-
--radius-xl: calc(var(--
|
|
109
|
+
--radius-sm: var(--r-sm);
|
|
110
|
+
--radius-md: var(--r-control);
|
|
111
|
+
--radius-lg: var(--r);
|
|
112
|
+
--radius-xl: calc(var(--r) + 2px);
|
|
152
113
|
--color-sidebar: var(--sidebar);
|
|
153
114
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
154
115
|
--color-sidebar-primary: var(--sidebar-primary);
|
|
@@ -157,6 +118,12 @@
|
|
|
157
118
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
158
119
|
--color-sidebar-border: var(--sidebar-border);
|
|
159
120
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
121
|
+
--text-2xl: var(--fs-page);
|
|
122
|
+
--text-xl: calc(var(--fs-card) + 4px);
|
|
123
|
+
--text-lg: var(--fs-card);
|
|
124
|
+
--text-base: var(--fs-body);
|
|
125
|
+
--text-sm: var(--fs-sub);
|
|
126
|
+
--text-xs: var(--fs-hint);
|
|
160
127
|
}
|
|
161
128
|
|
|
162
129
|
@layer base {
|
|
@@ -166,102 +133,67 @@
|
|
|
166
133
|
|
|
167
134
|
.actuate-admin {
|
|
168
135
|
@apply bg-background text-foreground;
|
|
169
|
-
|
|
170
|
-
* Content font is var-driven so the Appearance tab can switch it at
|
|
171
|
-
* runtime, but defaults to the system-ui stack. We do NOT load web fonts
|
|
172
|
-
* here (no Google Fonts / @font-face) — the chosen family is applied as a
|
|
173
|
-
* family string and falls back to system-ui when not installed, keeping
|
|
174
|
-
* the admin dependency-free per the design system. This is the single
|
|
175
|
-
* permitted `!important` (it must beat consumer global resets).
|
|
176
|
-
*/
|
|
177
|
-
font-family: var(
|
|
178
|
-
--actuate-admin-font,
|
|
179
|
-
system-ui,
|
|
180
|
-
-apple-system,
|
|
181
|
-
BlinkMacSystemFont,
|
|
182
|
-
'Segoe UI',
|
|
183
|
-
Roboto,
|
|
184
|
-
sans-serif
|
|
185
|
-
) !important;
|
|
136
|
+
font-family: var(--actuate-admin-font, var(--font-sans)) !important;
|
|
186
137
|
font-size: var(--font-size);
|
|
187
138
|
line-height: 1.5;
|
|
188
139
|
isolation: isolate;
|
|
189
|
-
/*
|
|
190
|
-
* Use `contain: style` only — NOT `contain: layout`.
|
|
191
|
-
*
|
|
192
|
-
* `contain: layout` would make every `.actuate-admin` element a
|
|
193
|
-
* *containing block* for `position: fixed` descendants. That
|
|
194
|
-
* silently breaks <AdminRoot>'s own fixed overlay (`position: fixed;
|
|
195
|
-
* inset: 0`) whenever a consumer wraps AdminRoot in their own
|
|
196
|
-
* `<div className="actuate-admin">` for tailwind isolation — the
|
|
197
|
-
* inner fixed div resolves relative to the wrapper instead of the
|
|
198
|
-
* viewport, and if the wrapper is 0-height (because all its
|
|
199
|
-
* children are out-of-flow), every admin element renders offscreen
|
|
200
|
-
* while still reporting non-zero computed dimensions. The visible
|
|
201
|
-
* symptom is `<body> intercepts pointer events` on every click in
|
|
202
|
-
* Playwright; the user-visible symptom is a blank-looking admin.
|
|
203
|
-
*
|
|
204
|
-
* `contain: style` keeps the style-scoping benefit (e.g. counters
|
|
205
|
-
* don't leak out) without the positioning footgun.
|
|
206
|
-
*/
|
|
207
140
|
contain: style;
|
|
208
141
|
-webkit-font-smoothing: antialiased;
|
|
209
142
|
-moz-osx-font-smoothing: grayscale;
|
|
210
143
|
}
|
|
211
144
|
|
|
212
145
|
.actuate-admin h1 {
|
|
213
|
-
font-size: var(--
|
|
214
|
-
font-weight:
|
|
146
|
+
font-size: var(--fs-page);
|
|
147
|
+
font-weight: 700;
|
|
148
|
+
letter-spacing: -0.5px;
|
|
215
149
|
line-height: 1.5;
|
|
216
150
|
}
|
|
217
151
|
|
|
218
152
|
.actuate-admin h2 {
|
|
219
|
-
font-size: var(--
|
|
220
|
-
font-weight:
|
|
153
|
+
font-size: var(--fs-card);
|
|
154
|
+
font-weight: 600;
|
|
221
155
|
line-height: 1.5;
|
|
222
156
|
}
|
|
223
157
|
|
|
224
158
|
.actuate-admin h3 {
|
|
225
|
-
font-size: var(--
|
|
226
|
-
font-weight:
|
|
159
|
+
font-size: var(--fs-card);
|
|
160
|
+
font-weight: 600;
|
|
227
161
|
line-height: 1.5;
|
|
228
162
|
}
|
|
229
163
|
|
|
230
164
|
.actuate-admin h4 {
|
|
231
|
-
font-size: var(--
|
|
232
|
-
font-weight:
|
|
165
|
+
font-size: var(--fs-body);
|
|
166
|
+
font-weight: 600;
|
|
233
167
|
line-height: 1.5;
|
|
234
168
|
}
|
|
235
169
|
|
|
236
170
|
.actuate-admin label {
|
|
237
|
-
font-size: var(--
|
|
171
|
+
font-size: var(--fs-body);
|
|
238
172
|
font-weight: var(--font-weight-medium);
|
|
239
173
|
line-height: 1.5;
|
|
240
174
|
}
|
|
241
175
|
|
|
242
176
|
.actuate-admin button {
|
|
243
|
-
font-size: var(--
|
|
177
|
+
font-size: var(--fs-body);
|
|
244
178
|
font-weight: var(--font-weight-medium);
|
|
245
179
|
line-height: 1.5;
|
|
246
180
|
}
|
|
247
181
|
|
|
248
182
|
.actuate-admin input {
|
|
249
|
-
font-size: var(--
|
|
183
|
+
font-size: var(--fs-body);
|
|
250
184
|
font-weight: var(--font-weight-normal);
|
|
251
185
|
line-height: 1.5;
|
|
252
186
|
}
|
|
187
|
+
|
|
188
|
+
.actuate-admin .actuate-section-label {
|
|
189
|
+
font-size: var(--fs-label);
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
letter-spacing: 0.08em;
|
|
192
|
+
text-transform: uppercase;
|
|
193
|
+
color: var(--sub);
|
|
194
|
+
}
|
|
253
195
|
}
|
|
254
196
|
|
|
255
|
-
/*
|
|
256
|
-
* Reduce-motion (admin-level Appearance toggle).
|
|
257
|
-
*
|
|
258
|
-
* Intentionally UNLAYERED: unlayered rules beat Tailwind's `@layer utilities`
|
|
259
|
-
* transition/animation classes without needing `!important`, so the toggle can
|
|
260
|
-
* neutralize utility-driven motion. We shorten (not delete) durations and never
|
|
261
|
-
* touch outlines/focus rings, so state changes and focus visibility remain
|
|
262
|
-
* intact. The OS `prefers-reduced-motion` is still respected app-wide via
|
|
263
|
-
* `motion-safe:`/`motion-reduce:`; this class lets users opt in regardless.
|
|
264
|
-
*/
|
|
265
197
|
.actuate-admin.reduce-motion,
|
|
266
198
|
.actuate-admin.reduce-motion *,
|
|
267
199
|
.actuate-admin.reduce-motion *::before,
|
package/src/views/Forms.tsx
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* opens the right-side `FormSchemaDrawer`.
|
|
9
9
|
*/
|
|
10
10
|
import { ChevronRight, ClipboardList, Plus, Search, Settings2 } from 'lucide-react'
|
|
11
|
-
import
|
|
11
|
+
import { Toggle } from '../components/ui/Toggle.js'
|
|
12
12
|
import { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react'
|
|
13
13
|
import { toast } from 'sonner'
|
|
14
14
|
import { sortByRelevance } from '../lib/search.js'
|
|
@@ -382,14 +382,12 @@ function FormsTable({
|
|
|
382
382
|
{formatRelative(form.lastEntryAt)}
|
|
383
383
|
</td>
|
|
384
384
|
<td className="px-4 py-3 text-center">
|
|
385
|
-
<
|
|
385
|
+
<Toggle
|
|
386
386
|
checked={form.notifyEnabled ?? false}
|
|
387
387
|
onCheckedChange={(v) => onNotifyToggle(form, v)}
|
|
388
388
|
aria-label={`Notifications for ${form.name}`}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
<Switch.Thumb className="bg-background block h-3.5 w-3.5 translate-x-0.5 rounded-full shadow-sm transition-transform data-[state=checked]:translate-x-[14px]" />
|
|
392
|
-
</Switch.Root>
|
|
389
|
+
variant="enabled"
|
|
390
|
+
/>
|
|
393
391
|
</td>
|
|
394
392
|
<td className="px-4 py-3 text-right">
|
|
395
393
|
<button
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { Plus, Grid3X3 } from 'lucide-react'
|
|
4
|
-
import
|
|
4
|
+
import { Toggle } from '../../components/ui/Toggle.js'
|
|
5
5
|
import type { DeviceMode } from '../../hooks/useBuilderState.js'
|
|
6
6
|
|
|
7
7
|
export interface BottomBarProps {
|
|
@@ -45,14 +45,11 @@ export function BottomBar({
|
|
|
45
45
|
{/* Grid overlay toggle */}
|
|
46
46
|
<label className="flex cursor-pointer items-center gap-2">
|
|
47
47
|
<Grid3X3 size={14} className="text-muted-foreground" />
|
|
48
|
-
<
|
|
48
|
+
<Toggle
|
|
49
49
|
checked={showGridOverlay}
|
|
50
50
|
onCheckedChange={onToggleGrid}
|
|
51
|
-
className="bg-input-background data-[state=checked]:bg-primary relative h-[18px] w-8 rounded-full transition-colors"
|
|
52
51
|
aria-label="Toggle grid overlay"
|
|
53
|
-
|
|
54
|
-
<Switch.Thumb className="bg-background block h-3.5 w-3.5 translate-x-0.5 rounded-full shadow-sm transition-transform data-[state=checked]:translate-x-[14px]" />
|
|
55
|
-
</Switch.Root>
|
|
52
|
+
/>
|
|
56
53
|
<span className="text-muted-foreground text-xs">Grid</span>
|
|
57
54
|
</label>
|
|
58
55
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useId, useState } from 'react'
|
|
4
4
|
import { RefreshCw, Map, AlertTriangle, CheckCircle2, ExternalLink, Bot } from 'lucide-react'
|
|
5
|
-
import
|
|
5
|
+
import { Toggle as UiToggle } from '../../components/ui/Toggle.js'
|
|
6
6
|
import { toast } from 'sonner'
|
|
7
7
|
import {
|
|
8
8
|
fetchSitemapStatus,
|
|
@@ -67,16 +67,13 @@ function Toggle({
|
|
|
67
67
|
{help}
|
|
68
68
|
</span>
|
|
69
69
|
</span>
|
|
70
|
-
<
|
|
70
|
+
<UiToggle
|
|
71
71
|
checked={checked}
|
|
72
72
|
onCheckedChange={onChange}
|
|
73
73
|
disabled={disabled}
|
|
74
74
|
aria-labelledby={labelId}
|
|
75
75
|
aria-describedby={helpId}
|
|
76
|
-
|
|
77
|
-
>
|
|
78
|
-
<Switch.Thumb className="bg-background block h-3.5 w-3.5 translate-x-0.5 rounded-full shadow-sm transition-transform data-[state=checked]:translate-x-[14px]" />
|
|
79
|
-
</Switch.Root>
|
|
76
|
+
/>
|
|
80
77
|
</div>
|
|
81
78
|
)
|
|
82
79
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import * as Dialog from '@radix-ui/react-dialog'
|
|
4
4
|
import { AlertTriangle, Check, Loader2, Lock } from 'lucide-react'
|
|
5
5
|
import { useId, type ReactNode } from 'react'
|
|
6
|
+
import { Card, CardContent, CardDescription, CardHeader } from '../../components/ui/Card.js'
|
|
6
7
|
import { adminPortalContainer } from '../../lib/portal-container.js'
|
|
7
8
|
import type { SettingsSourceMetadata, ValidationIssue } from './useGeneralSettings.js'
|
|
8
9
|
|
|
@@ -34,21 +35,21 @@ export function SettingsCard({
|
|
|
34
35
|
}) {
|
|
35
36
|
const headingId = useId()
|
|
36
37
|
return (
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
className={`border-border bg-card rounded-lg border p-6 ${className ?? ''}`}
|
|
40
|
-
>
|
|
41
|
-
<header className="mb-4 flex items-start justify-between gap-3">
|
|
38
|
+
<Card padding="none" aria-labelledby={headingId} role="region" className={className}>
|
|
39
|
+
<CardHeader className="flex items-start justify-between gap-3">
|
|
42
40
|
<div className="min-w-0">
|
|
43
|
-
<Heading
|
|
41
|
+
<Heading
|
|
42
|
+
id={headingId}
|
|
43
|
+
className="text-[length:var(--fs-card)] font-semibold text-[var(--txt)]"
|
|
44
|
+
>
|
|
44
45
|
{title}
|
|
45
46
|
</Heading>
|
|
46
|
-
{description && <
|
|
47
|
+
{description && <CardDescription>{description}</CardDescription>}
|
|
47
48
|
</div>
|
|
48
49
|
{actions && <div className="flex shrink-0 items-center gap-2">{actions}</div>}
|
|
49
|
-
</
|
|
50
|
-
{children}
|
|
51
|
-
</
|
|
50
|
+
</CardHeader>
|
|
51
|
+
<CardContent className="pt-0 text-[var(--txt)]">{children}</CardContent>
|
|
52
|
+
</Card>
|
|
52
53
|
)
|
|
53
54
|
}
|
|
54
55
|
|