@revealui/core 0.13.1 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +3 -2
  2. package/dist/client/admin/components/AdminDashboard.d.ts +8 -1
  3. package/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
  4. package/dist/client/admin/components/AdminDashboard.js +11 -10
  5. package/dist/client/admin/components/CollectionList.d.ts.map +1 -1
  6. package/dist/client/admin/components/CollectionList.js +4 -6
  7. package/dist/client/admin/components/DocumentForm.d.ts.map +1 -1
  8. package/dist/client/admin/components/DocumentForm.js +26 -26
  9. package/dist/client/admin/components/GlobalForm.d.ts.map +1 -1
  10. package/dist/client/admin/components/GlobalForm.js +10 -9
  11. package/dist/client/admin/page.d.ts.map +1 -1
  12. package/dist/client/admin/page.js +2 -1
  13. package/dist/client/richtext/components/ImageNodeComponent.d.ts.map +1 -1
  14. package/dist/client/richtext/components/ImageNodeComponent.js +3 -22
  15. package/dist/client/richtext/components/ImageUploadButton.d.ts.map +1 -1
  16. package/dist/client/richtext/components/ImageUploadButton.js +2 -4
  17. package/dist/client/richtext/plugins/FloatingToolbarPlugin.d.ts.map +1 -1
  18. package/dist/client/richtext/plugins/FloatingToolbarPlugin.js +3 -2
  19. package/dist/client/richtext/plugins/ToolbarPlugin.d.ts.map +1 -1
  20. package/dist/client/richtext/plugins/ToolbarPlugin.js +3 -2
  21. package/dist/client/ui/index.d.ts.map +1 -1
  22. package/dist/client/ui/index.js +10 -6
  23. package/dist/cogs-breaker.d.ts +27 -0
  24. package/dist/cogs-breaker.d.ts.map +1 -0
  25. package/dist/cogs-breaker.js +29 -0
  26. package/dist/error-handling/error-boundary.d.ts.map +1 -1
  27. package/dist/error-handling/error-boundary.js +2 -9
  28. package/dist/error-handling/fallback-components.d.ts.map +1 -1
  29. package/dist/error-handling/fallback-components.js +9 -86
  30. package/dist/instance/logger.d.ts +2 -1
  31. package/dist/instance/logger.d.ts.map +1 -1
  32. package/dist/license/mint-client.d.ts +15 -4
  33. package/dist/license/mint-client.d.ts.map +1 -1
  34. package/dist/license/mint-client.js +38 -9
  35. package/dist/license.d.ts +39 -14
  36. package/dist/license.d.ts.map +1 -1
  37. package/dist/license.js +111 -34
  38. package/dist/margin-governor.d.ts +82 -0
  39. package/dist/margin-governor.d.ts.map +1 -0
  40. package/dist/margin-governor.js +143 -0
  41. package/dist/revforge-license-boot.d.ts +0 -10
  42. package/dist/revforge-license-boot.d.ts.map +1 -1
  43. package/dist/revforge-license-boot.js +41 -20
  44. package/dist/types/runtime.d.ts +3 -6
  45. package/dist/types/runtime.d.ts.map +1 -1
  46. package/dist/utils/block-conversion.d.ts.map +1 -1
  47. package/dist/utils/block-conversion.js +2 -1
  48. package/package.json +64 -3
package/README.md CHANGED
@@ -24,7 +24,7 @@ Part of the [RevealUI monorepo](https://github.com/RevealUIStudio/revealui) -
24
24
  - **Security** - CORS, CSP, HSTS, RBAC/ABAC policy engine, encryption (AES-256-GCM), audit logging
25
25
  - **GDPR Compliance** - Consent management, data export, deletion, anonymization, breach reporting
26
26
  - **Observability** - Structured logging, process health monitoring, alert system, graceful shutdown
27
- - **Plugins** - Extensible plugin system (form builder, nested docs, redirects)
27
+ - **Plugins** - Extensible plugin system (form builder, nested docs, redirects). Guide: [docs/PLUGINS.md](../../docs/PLUGINS.md)
28
28
  - **Feature Gating** - Tier-based licensing (free, pro, max, enterprise) with JWT license keys
29
29
  - **Database** - PostgreSQL adapters (NeonDB + PGlite for testing), connection pooling, SSL/TLS
30
30
  - **Storage** - Pluggable storage interface (Cloudflare R2 sole non-mock backend; mock adapter for tests)
@@ -41,11 +41,12 @@ pnpm add @revealui/core
41
41
 
42
42
  ```typescript
43
43
  import { buildConfig } from '@revealui/core/config'
44
+ import { formBuilderPlugin, nestedDocsPlugin } from '@revealui/core/plugins'
44
45
 
45
46
  const config = buildConfig({
46
47
  collections: [Posts, Categories, Users],
47
48
  globals: [Settings, Navigation],
48
- plugins: [formBuilder(), nestedDocs()],
49
+ plugins: [formBuilderPlugin(), nestedDocsPlugin()],
49
50
  })
50
51
  ```
51
52
 
@@ -1,3 +1,4 @@
1
+ import type { ReactNode } from 'react';
1
2
  import type { RevealConfig } from '../../../types/index.js';
2
3
  interface AdminDashboardProps {
3
4
  config: RevealConfig;
@@ -7,7 +8,13 @@ interface AdminDashboardProps {
7
8
  * files cannot read those env vars at runtime (build-time inlining).
8
9
  */
9
10
  siteName?: string;
11
+ /**
12
+ * Optional lead content above the Overview stats (GAP-300 onboarding
13
+ * checklist/nudge). Only shown on the home Overview view, not collection
14
+ * or document editors.
15
+ */
16
+ overviewLead?: ReactNode;
10
17
  }
11
- export declare function AdminDashboard({ config, siteName }: AdminDashboardProps): import("react").JSX.Element;
18
+ export declare function AdminDashboard({ config, siteName, overviewLead, }: AdminDashboardProps): import("react").JSX.Element;
12
19
  export {};
13
20
  //# sourceMappingURL=AdminDashboard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminDashboard.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/AdminDashboard.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,YAAY,EAGb,MAAM,yBAAyB,CAAC;AAUjC,UAAU,mBAAmB;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA2iBD,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAqB,EAAE,EAAE,mBAAmB,+BAoVpF"}
1
+ {"version":3,"file":"AdminDashboard.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/AdminDashboard.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAEV,YAAY,EAGb,MAAM,yBAAyB,CAAC;AAUjC,UAAU,mBAAmB;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;CAC1B;AAqhBD,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,QAAqB,EACrB,YAAY,GACb,EAAE,mBAAmB,+BAqVrB"}
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { logger } from '@revealui/core/utils/logger';
4
+ import { Button, IconPrimitiveContent, IconSettings } from '@revealui/presentation';
4
5
  import { useCallback, useEffect, useReducer, useState } from 'react';
5
6
  import { APIError, APIErrorType, apiClient, postSignOut } from '../utils/index.js';
6
7
  import { CollectionList } from './CollectionList.js';
@@ -53,7 +54,7 @@ function reducer(state, action) {
53
54
  // Shared sub-components
54
55
  // =============================================================================
55
56
  function AdminHeader({ title, onBack }) {
56
- return (_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("button", { type: "button", onClick: onBack, className: "text-muted-foreground hover:text-muted-foreground", children: "\u2190 Back to Dashboard" }), _jsx("h1", { className: "text-2xl font-bold text-foreground capitalize", children: title })] }), _jsx(SignOutButton, {})] }) }) }));
57
+ return (_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsxs("div", { className: "flex items-center space-x-4", children: [_jsx(Button, { type: "button", variant: "neutral", appearance: "ghost", size: "sm", onClick: onBack, children: "\u2190 Back to Dashboard" }), _jsx("h1", { className: "text-2xl font-bold text-foreground capitalize", children: title })] }), _jsx(SignOutButton, {})] }) }) }));
57
58
  }
58
59
  function StatusBanners({ error, successMessage, }) {
59
60
  return (_jsxs(_Fragment, { children: [error && (_jsxs("div", { className: "mb-4 bg-red-50 border border-red-200 text-red-800 px-4 py-3 rounded", children: [_jsx("p", { className: "font-medium", children: "Error" }), _jsx("p", { className: "text-sm", children: error })] })), successMessage && (_jsxs("div", { className: "mb-4 bg-success/10 border border-success/30 text-success px-4 py-3 rounded", children: [_jsx("p", { className: "font-medium", children: "Success" }), _jsx("p", { className: "text-sm", children: successMessage })] }))] }));
@@ -73,7 +74,7 @@ function SignOutButton() {
73
74
  }
74
75
  window.location.href = '/login';
75
76
  }, []);
76
- return (_jsx("button", { type: "button", onClick: () => void handleSignOut(), disabled: loading, className: "text-sm text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md hover:bg-muted transition-colors", children: loading ? 'Signing out...' : 'Sign Out' }));
77
+ return (_jsx(Button, { type: "button", variant: "neutral", appearance: "ghost", size: "sm", onClick: () => void handleSignOut(), disabled: loading, children: loading ? 'Signing out...' : 'Sign Out' }));
77
78
  }
78
79
  const TAXONOMY_GROUPS = ['Operate', 'Build', 'Configure'];
79
80
  function isTaxonomyGroup(value) {
@@ -123,8 +124,8 @@ const COLLECTION_LINK_OVERRIDES = {
123
124
  };
124
125
  // Static icons: hoisted so the same element is reused across renders instead
125
126
  // of re-created (they take no props and never change).
126
- const collectionsIcon = (_jsx("svg", { className: "h-5 w-5 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" }) }));
127
- const globalsIcon = (_jsx("svg", { className: "h-5 w-5 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" }) }));
127
+ const collectionsIcon = _jsx(IconPrimitiveContent, { size: "sm", className: "text-muted-foreground" });
128
+ const globalsIcon = _jsx(IconSettings, { size: "sm", className: "text-muted-foreground" });
128
129
  /**
129
130
  * Small local equivalents of `@revealui/presentation`'s `Badge` / `Stat` /
130
131
  * `StatusDot`, built from the same `--rvui-*` token bridge classes (`bg-muted`,
@@ -160,11 +161,11 @@ function CollectionGroupCard({ group, collections, onCollectionClick, }) {
160
161
  const slug = String(collection.slug);
161
162
  const overrideHref = COLLECTION_LINK_OVERRIDES[slug];
162
163
  const rowClassName = 'flex w-full items-center px-5 py-2.5 text-left text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground cursor-pointer';
163
- return (_jsx("li", { children: overrideHref ? (_jsx("a", { href: overrideHref, className: rowClassName, children: slug })) : (_jsx("button", { type: "button", onClick: () => onCollectionClick(collection), className: rowClassName, children: slug })) }, slug));
164
+ return (_jsx("li", { children: overrideHref ? (_jsx("a", { href: overrideHref, className: rowClassName, children: slug })) : (_jsx(Button, { type: "button", variant: "neutral", appearance: "ghost", size: "clear", onClick: () => onCollectionClick(collection), className: rowClassName, children: slug })) }, slug));
164
165
  }) })] }));
165
166
  }
166
167
  function GlobalsCard({ globals, onGlobalClick, }) {
167
- return (_jsxs("section", { "aria-labelledby": "dashboard-globals", className: "overflow-hidden rounded-lg bg-card shadow", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-5 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [globalsIcon, _jsx("h3", { id: "dashboard-globals", className: "text-sm font-semibold text-foreground", children: "Globals" })] }), _jsx(CountBadge, { count: globals.length })] }), globals.length > 0 ? (_jsx("ul", { className: "divide-y divide-border", children: globals.map((global) => (_jsx("li", { children: _jsx("button", { type: "button", onClick: () => onGlobalClick(global), className: "flex w-full items-center px-5 py-2.5 text-left text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground cursor-pointer", children: global.label || String(global.slug) }) }, String(global.slug)))) })) : (_jsx("p", { className: "px-5 py-4 text-sm text-muted-foreground", children: "No globals configured" }))] }));
168
+ return (_jsxs("section", { "aria-labelledby": "dashboard-globals", className: "overflow-hidden rounded-lg bg-card shadow", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-5 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [globalsIcon, _jsx("h3", { id: "dashboard-globals", className: "text-sm font-semibold text-foreground", children: "Globals" })] }), _jsx(CountBadge, { count: globals.length })] }), globals.length > 0 ? (_jsx("ul", { className: "divide-y divide-border", children: globals.map((global) => (_jsx("li", { children: _jsx(Button, { type: "button", variant: "neutral", appearance: "ghost", size: "clear", onClick: () => onGlobalClick(global), className: "flex w-full items-center px-5 py-2.5 text-left text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground cursor-pointer", children: global.label || String(global.slug) }) }, String(global.slug)))) })) : (_jsx("p", { className: "px-5 py-4 text-sm text-muted-foreground", children: "No globals configured" }))] }));
168
169
  }
169
170
  /** System status card: a status-dot-led card, never a bare prose sentence. */
170
171
  function SystemStatusCard({ degraded }) {
@@ -174,9 +175,9 @@ function SystemStatusCard({ degraded }) {
174
175
  : 'The admin console is responding normally.';
175
176
  return (_jsxs("section", { "aria-labelledby": "dashboard-system-status", className: "overflow-hidden rounded-lg bg-card shadow", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-5 py-3", children: [_jsx("h3", { id: "dashboard-system-status", className: "text-sm font-semibold text-foreground", children: "System status" }), _jsxs("span", { className: "inline-flex items-center gap-2 text-sm font-medium text-foreground", children: [_jsx(StatusIndicator, { degraded: degraded, label: `System status: ${word}`, pulse: !degraded }), word] })] }), _jsx("p", { className: "px-5 py-4 text-sm text-muted-foreground", children: description })] }));
176
177
  }
177
- function DashboardHome({ siteName, collections, globals, degraded, onCollectionClick, onGlobalClick, }) {
178
+ function DashboardHome({ siteName, collections, globals, degraded, onCollectionClick, onGlobalClick, overviewLead, }) {
178
179
  const grouped = groupCollectionsByTaxonomy(collections);
179
- return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-foreground", children: `${siteName} Admin` }) }), _jsxs("div", { className: "flex shrink-0 items-center gap-3", children: [_jsxs("span", { className: "shrink-0 text-sm tabular-nums text-muted-foreground", title: "Application version", children: ["v", process.env.NEXT_PUBLIC_APP_VERSION ?? process.env.APP_VERSION ?? '0.0.0'] }), _jsx(SignOutButton, {})] })] }) }) }), _jsxs("main", { className: "max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8", children: [_jsxs("div", { className: "mb-6", children: [_jsx("h2", { className: "text-2xl font-bold tracking-tight text-foreground", children: "Overview" }), _jsxs("p", { className: "mt-1 text-sm text-muted-foreground", children: ["Collections, globals, and system status for ", siteName, "."] })] }), _jsxs("div", { className: "mb-8 grid grid-cols-1 gap-4 sm:grid-cols-3", children: [_jsx(StatTile, { label: "Collections", value: collections.length, icon: collectionsIcon }), _jsx(StatTile, { label: "Globals", value: globals.length, icon: globalsIcon }), _jsx(StatTile, { label: "Status", value: degraded ? 'Degraded' : 'Healthy', icon: _jsx(StatusIndicator, { degraded: degraded, label: degraded ? 'Degraded' : 'Healthy' }) })] }), _jsxs("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-3", children: [_jsx("div", { className: "lg:col-span-2 flex flex-col gap-6", children: collections.length > 0 ? (TAXONOMY_GROUPS.map((group) => (_jsx(CollectionGroupCard, { group: group, collections: grouped[group], onCollectionClick: onCollectionClick }, group)))) : (_jsx("div", { className: "rounded-lg bg-card p-5 shadow", children: _jsx("p", { className: "text-sm text-muted-foreground", children: "No collections configured" }) })) }), _jsxs("div", { className: "flex flex-col gap-6", children: [_jsx(GlobalsCard, { globals: globals, onGlobalClick: onGlobalClick }), _jsx(SystemStatusCard, { degraded: degraded })] })] })] })] }));
180
+ return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-foreground", children: `${siteName} Admin` }) }), _jsxs("div", { className: "flex shrink-0 items-center gap-3", children: [_jsxs("span", { className: "shrink-0 text-sm tabular-nums text-muted-foreground", title: "Application version", children: ["v", process.env.NEXT_PUBLIC_APP_VERSION ?? process.env.APP_VERSION ?? '0.0.0'] }), _jsx(SignOutButton, {})] })] }) }) }), _jsxs("main", { className: "max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8", children: [_jsxs("div", { className: "mb-6", children: [_jsx("h2", { className: "text-2xl font-bold tracking-tight text-foreground", children: "Overview" }), _jsxs("p", { className: "mt-1 text-sm text-muted-foreground", children: ["Collections, globals, and system status for ", siteName, "."] })] }), overviewLead ? _jsx("div", { className: "mb-6", children: overviewLead }) : null, _jsxs("div", { className: "mb-8 grid grid-cols-1 gap-4 sm:grid-cols-3", children: [_jsx(StatTile, { label: "Collections", value: collections.length, icon: collectionsIcon }), _jsx(StatTile, { label: "Globals", value: globals.length, icon: globalsIcon }), _jsx(StatTile, { label: "Status", value: degraded ? 'Degraded' : 'Healthy', icon: _jsx(StatusIndicator, { degraded: degraded, label: degraded ? 'Degraded' : 'Healthy' }) })] }), _jsxs("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-3", children: [_jsx("div", { className: "lg:col-span-2 flex flex-col gap-6", children: collections.length > 0 ? (TAXONOMY_GROUPS.map((group) => (_jsx(CollectionGroupCard, { group: group, collections: grouped[group], onCollectionClick: onCollectionClick }, group)))) : (_jsx("div", { className: "rounded-lg bg-card p-5 shadow", children: _jsx("p", { className: "text-sm text-muted-foreground", children: "No collections configured" }) })) }), _jsxs("div", { className: "flex flex-col gap-6", children: [_jsx(GlobalsCard, { globals: globals, onGlobalClick: onGlobalClick }), _jsx(SystemStatusCard, { degraded: degraded })] })] })] })] }));
180
181
  }
181
182
  // =============================================================================
182
183
  // Error handling helpers
@@ -193,7 +194,7 @@ function logApiError(err, context) {
193
194
  // =============================================================================
194
195
  // Main component
195
196
  // =============================================================================
196
- export function AdminDashboard({ config, siteName = 'RevealUI' }) {
197
+ export function AdminDashboard({ config, siteName = 'RevealUI', overviewLead, }) {
197
198
  const [state, dispatch] = useReducer(reducer, initialState);
198
199
  const collections = config.collections || [];
199
200
  const globals = config.globals || [];
@@ -441,5 +442,5 @@ export function AdminDashboard({ config, siteName = 'RevealUI' }) {
441
442
  return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx(AdminHeader, { title: state.view.global.label || String(state.view.global.slug), onBack: goToDashboard }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsxs("div", { className: "max-w-3xl", children: [_jsx(StatusBanners, { error: state.error, successMessage: state.successMessage }), state.globalLoading && _jsx(LoadingSpinner, {}), !state.globalLoading && state.globalDocument && (_jsx(GlobalForm, { global: state.view.global, document: state.globalDocument, onSave: (data) => void handleSaveGlobal(data), onCancel: goToDashboard, isLoading: state.saving }))] }) })] }));
442
443
  }
443
444
  // ── Dashboard home ────────────────────────────────────────────────────
444
- return (_jsx(DashboardHome, { siteName: siteName, collections: collections, globals: globals, degraded: Boolean(state.error), onCollectionClick: (c) => void handleCollectionClick(c), onGlobalClick: (g) => void handleGlobalClick(g) }));
445
+ return (_jsx(DashboardHome, { siteName: siteName, collections: collections, globals: globals, degraded: Boolean(state.error), onCollectionClick: (c) => void handleCollectionClick(c), onGlobalClick: (g) => void handleGlobalClick(g), overviewLead: overviewLead }));
445
446
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CollectionList.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/CollectionList.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAoCjC,UAAU,mBAAmB;IAC3B,UAAU,EAAE,sBAAsB,CAAC;IACnC,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACvC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACzC;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,SAAS,EACT,SAAS,EACT,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,aAAa,GACd,EAAE,mBAAmB,qBAgRrB"}
1
+ {"version":3,"file":"CollectionList.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/CollectionList.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAoCjC,UAAU,mBAAmB;IAC3B,UAAU,EAAE,sBAAsB,CAAC;IACnC,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACvC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACzC;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,SAAS,EACT,SAAS,EACT,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,aAAa,GACd,EAAE,mBAAmB,qBAkRrB"}
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Button, Checkbox, IconPlus } from '@revealui/presentation';
3
4
  import { useState } from 'react';
4
5
  function getFieldLabel(field) {
5
6
  const { label } = field;
@@ -83,13 +84,10 @@ export function CollectionList({ collection, documents, totalDocs, page, totalPa
83
84
  })
84
85
  .slice(0, 5); // Show first 5 visible fields
85
86
  const colCount = displayFields.length + 1 + (hasBulk ? 1 : 0);
86
- return (_jsxs("div", { className: "bg-card shadow overflow-hidden sm:rounded-md", children: [_jsxs("div", { className: "px-4 py-5 sm:px-6 flex justify-between items-center", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-lg leading-6 font-medium text-foreground capitalize", children: collection.slug }), _jsxs("p", { className: "mt-1 max-w-2xl text-sm text-muted-foreground", children: [totalDocs, " ", totalDocs === 1 ? 'document' : 'documents'] })] }), _jsxs("button", { type: "button", onClick: onCreate, className: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-primary-foreground bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background focus:ring-ring", children: [_jsxs("svg", { className: "-ml-1 mr-2 h-5 w-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", role: "img", focusable: "false", children: [_jsx("title", { children: "Create New" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" })] }), "Create New"] })] }), hasBulk && selectedIds.size > 0 && (_jsxs("div", { className: "bg-primary/10 border-y border-primary/20 px-4 py-2 flex items-center gap-3", children: [_jsxs("span", { className: "text-sm font-medium text-primary", children: [selectedIds.size, " selected"] }), onBulkDelete && (_jsx("button", { type: "button", onClick: () => void handleBulkAction('delete'), disabled: bulkLoading, className: "inline-flex items-center px-3 py-1 text-xs font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 disabled:opacity-50", children: "Delete" })), onBulkPublish && (_jsx("button", { type: "button", onClick: () => void handleBulkAction('publish'), disabled: bulkLoading, className: "inline-flex items-center px-3 py-1 text-xs font-medium rounded-md text-success bg-success/15 hover:bg-success/25 disabled:opacity-50", children: "Publish" })), _jsx("button", { type: "button", onClick: () => setSelectedIds(new Set()), className: "ml-auto text-xs text-muted-foreground hover:text-foreground", children: "Clear selection" })] })), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "min-w-full divide-y divide-border", children: [_jsx("thead", { className: "bg-muted", children: _jsxs("tr", { children: [hasBulk && (_jsx("th", { scope: "col", className: "w-10 px-3 py-3", children: _jsx("input", { type: "checkbox", checked: allSelected, ref: (el) => {
87
- if (el)
88
- el.indeterminate = someSelected;
89
- }, onChange: toggleAll, className: "h-4 w-4 rounded border-input text-primary focus:ring-ring", "aria-label": "Select all" }) })), displayFields.map((field) => (_jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider", children: getFieldLabel(field) }, field.name))), _jsx("th", { scope: "col", className: "relative px-6 py-3", children: _jsx("span", { className: "sr-only", children: "Actions" }) })] }) }), _jsx("tbody", { className: "bg-card divide-y divide-border", children: documents.length === 0 ? (_jsx("tr", { children: _jsxs("td", { colSpan: colCount, className: "px-6 py-4 text-center text-sm text-muted-foreground", children: ["No documents found.", ' ', _jsx("button", { type: "button", onClick: onCreate, className: "text-primary hover:text-primary/80", children: "Create the first one" }), "."] }) })) : (documents.map((doc) => {
87
+ return (_jsxs("div", { className: "bg-card shadow overflow-hidden sm:rounded-md", children: [_jsxs("div", { className: "px-4 py-5 sm:px-6 flex justify-between items-center", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-lg leading-6 font-medium text-foreground capitalize", children: collection.slug }), _jsxs("p", { className: "mt-1 max-w-2xl text-sm text-muted-foreground", children: [totalDocs, " ", totalDocs === 1 ? 'document' : 'documents'] })] }), _jsxs(Button, { type: "button", variant: "brand", appearance: "solid", onClick: onCreate, children: [_jsx(IconPlus, { size: "sm", label: "Create New", className: "-ml-1 mr-2" }), "Create New"] })] }), hasBulk && selectedIds.size > 0 && (_jsxs("div", { className: "bg-primary/10 border-y border-primary/20 px-4 py-2 flex items-center gap-3", children: [_jsxs("span", { className: "text-sm font-medium text-primary", children: [selectedIds.size, " selected"] }), onBulkDelete && (_jsx(Button, { type: "button", variant: "danger", appearance: "solid", size: "sm", onClick: () => void handleBulkAction('delete'), disabled: bulkLoading, children: "Delete" })), onBulkPublish && (_jsx(Button, { type: "button", variant: "success", appearance: "solid", size: "sm", onClick: () => void handleBulkAction('publish'), disabled: bulkLoading, children: "Publish" })), _jsx(Button, { type: "button", variant: "neutral", appearance: "ghost", size: "sm", onClick: () => setSelectedIds(new Set()), className: "ml-auto", children: "Clear selection" })] })), _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "min-w-full divide-y divide-border", children: [_jsx("thead", { className: "bg-muted", children: _jsxs("tr", { children: [hasBulk && (_jsx("th", { scope: "col", className: "w-10 px-3 py-3", children: _jsx(Checkbox, { checked: allSelected, indeterminate: someSelected, onChange: () => toggleAll(), "aria-label": "Select all" }) })), displayFields.map((field) => (_jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider", children: getFieldLabel(field) }, field.name))), _jsx("th", { scope: "col", className: "relative px-6 py-3", children: _jsx("span", { className: "sr-only", children: "Actions" }) })] }) }), _jsx("tbody", { className: "bg-card divide-y divide-border", children: documents.length === 0 ? (_jsx("tr", { children: _jsxs("td", { colSpan: colCount, className: "px-6 py-4 text-center text-sm text-muted-foreground", children: ["No documents found.", ' ', _jsx(Button, { type: "button", variant: "brand", appearance: "link", size: "clear", onClick: onCreate, className: "inline p-0 h-auto", children: "Create the first one" }), "."] }) })) : (documents.map((doc) => {
90
88
  const docId = String(doc.id);
91
- return (_jsxs("tr", { className: `hover:bg-muted ${selectedIds.has(docId) ? 'bg-primary/10' : ''}`, children: [hasBulk && (_jsx("td", { className: "w-10 px-3 py-4", children: _jsx("input", { type: "checkbox", checked: selectedIds.has(docId), onChange: () => toggleOne(docId), className: "h-4 w-4 rounded border-input text-primary focus:ring-ring", "aria-label": `Select ${docId}` }) })), displayFields.map((field) => (_jsx("td", { className: "px-6 py-4 whitespace-nowrap text-sm text-foreground", children: renderFieldValue(field.name ? doc[field.name] : undefined, field) }, field.name))), _jsxs("td", { className: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium space-x-2", children: [_jsx("button", { type: "button", onClick: () => onEdit(doc), className: "text-primary hover:text-primary/80 disabled:opacity-50 disabled:cursor-not-allowed", disabled: deleting !== null, children: "Edit" }), _jsx("button", { type: "button", onClick: () => onDelete(doc), className: "text-red-600 hover:text-red-900 disabled:opacity-50 disabled:cursor-not-allowed", disabled: deleting !== null, children: deleting === docId ? 'Deleting...' : 'Delete' })] })] }, docId));
92
- })) })] }) }), totalPages > 1 && (_jsxs("div", { className: "bg-card px-4 py-3 flex items-center justify-between border-t border-border sm:px-6", children: [_jsxs("div", { className: "flex-1 flex justify-between sm:hidden", children: [_jsx("button", { type: "button", onClick: () => onPageChange(page - 1), disabled: page <= 1, className: "relative inline-flex items-center px-4 py-2 border border-input text-sm font-medium rounded-md text-foreground bg-card hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed", children: "Previous" }), _jsx("button", { type: "button", onClick: () => onPageChange(page + 1), disabled: page >= totalPages, className: "ml-3 relative inline-flex items-center px-4 py-2 border border-input text-sm font-medium rounded-md text-foreground bg-card hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed", children: "Next" })] }), _jsxs("div", { className: "hidden sm:flex-1 sm:flex sm:items-center sm:justify-between", children: [_jsx("div", { children: _jsxs("p", { className: "text-sm text-foreground", children: ["Showing page ", _jsx("span", { className: "font-medium", children: page }), " of", ' ', _jsx("span", { className: "font-medium", children: totalPages })] }) }), _jsx("div", { children: _jsxs("nav", { className: "relative z-0 inline-flex rounded-md shadow-sm -space-x-px", children: [_jsx("button", { type: "button", onClick: () => onPageChange(page - 1), disabled: page <= 1, className: "relative inline-flex items-center px-2 py-2 rounded-l-md border border-input bg-card text-sm font-medium text-muted-foreground hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed", children: "Previous" }), _jsx("button", { type: "button", onClick: () => onPageChange(page + 1), disabled: page >= totalPages, className: "relative inline-flex items-center px-2 py-2 rounded-r-md border border-input bg-card text-sm font-medium text-muted-foreground hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed", children: "Next" })] }) })] })] }))] }));
89
+ return (_jsxs("tr", { className: `hover:bg-muted ${selectedIds.has(docId) ? 'bg-primary/10' : ''}`, children: [hasBulk && (_jsx("td", { className: "w-10 px-3 py-4", children: _jsx(Checkbox, { checked: selectedIds.has(docId), onChange: () => toggleOne(docId), "aria-label": `Select ${docId}` }) })), displayFields.map((field) => (_jsx("td", { className: "px-6 py-4 whitespace-nowrap text-sm text-foreground", children: renderFieldValue(field.name ? doc[field.name] : undefined, field) }, field.name))), _jsxs("td", { className: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium space-x-2", children: [_jsx(Button, { type: "button", variant: "brand", appearance: "link", size: "sm", onClick: () => onEdit(doc), disabled: deleting !== null, children: "Edit" }), _jsx(Button, { type: "button", variant: "danger", appearance: "link", size: "sm", onClick: () => onDelete(doc), disabled: deleting !== null, children: deleting === docId ? 'Deleting...' : 'Delete' })] })] }, docId));
90
+ })) })] }) }), totalPages > 1 && (_jsxs("div", { className: "bg-card px-4 py-3 flex items-center justify-between border-t border-border sm:px-6", children: [_jsxs("div", { className: "flex-1 flex justify-between sm:hidden", children: [_jsx(Button, { type: "button", variant: "neutral", appearance: "outline", onClick: () => onPageChange(page - 1), disabled: page <= 1, children: "Previous" }), _jsx(Button, { type: "button", variant: "neutral", appearance: "outline", onClick: () => onPageChange(page + 1), disabled: page >= totalPages, className: "ml-3", children: "Next" })] }), _jsxs("div", { className: "hidden sm:flex-1 sm:flex sm:items-center sm:justify-between", children: [_jsx("div", { children: _jsxs("p", { className: "text-sm text-foreground", children: ["Showing page ", _jsx("span", { className: "font-medium", children: page }), " of", ' ', _jsx("span", { className: "font-medium", children: totalPages })] }) }), _jsx("div", { children: _jsxs("nav", { className: "relative z-0 inline-flex rounded-md shadow-sm -space-x-px", children: [_jsx(Button, { type: "button", variant: "neutral", appearance: "outline", size: "sm", onClick: () => onPageChange(page - 1), disabled: page <= 1, className: "rounded-r-none", children: "Previous" }), _jsx(Button, { type: "button", variant: "neutral", appearance: "outline", size: "sm", onClick: () => onPageChange(page + 1), disabled: page >= totalPages, className: "rounded-l-none", children: "Next" })] }) })] })] }))] }));
93
91
  }
94
92
  function renderFieldValue(value, field) {
95
93
  if (value === null || value === undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/DocumentForm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAiEjC,UAAU,iBAAiB;IACzB,UAAU,EAAE,sBAAsB,CAAC;IACnC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,UAAU,EACV,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAiB,GAClB,EAAE,iBAAiB,qBA8EnB"}
1
+ {"version":3,"file":"DocumentForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/DocumentForm.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAiEjC,UAAU,iBAAiB;IACzB,UAAU,EAAE,sBAAsB,CAAC;IACnC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,UAAU,EACV,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAiB,GAClB,EAAE,iBAAiB,qBAsEnB"}
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
+ import { Button, Checkbox, FieldLabel, Input, Radio, RadioField, RadioGroup, Select, Textarea, } from '@revealui/presentation';
3
4
  import { lazy, Suspense, useCallback, useState } from 'react';
4
5
  // Lazy-loaded so Lexical (~1.2MB) is only bundled for edit pages with richText
5
6
  // fields - list/dashboard pages skip the entire Lexical chunk.
@@ -70,11 +71,11 @@ export function DocumentForm({ collection, document, onSave, onCancel, isLoading
70
71
  const handleFieldChange = (fieldName, value) => {
71
72
  setFormData((prev) => ({ ...prev, [fieldName]: value }));
72
73
  };
73
- return (_jsx("div", { className: "bg-card shadow overflow-hidden sm:rounded-lg", children: _jsxs("div", { className: "px-4 py-5 sm:p-6", children: [_jsxs("h3", { className: "text-lg leading-6 font-medium text-foreground mb-4", children: [document ? 'Edit' : 'Create', " ", collection.slug.slice(0, -1)] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [collection.upload && !document ? (_jsxs("div", { children: [_jsxs("label", { htmlFor: "__file", className: "block text-sm font-medium text-foreground", children: ["File", _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx("input", { type: "file", id: "__file", required: true, onChange: (e) => {
74
+ return (_jsx("div", { className: "bg-card shadow overflow-hidden sm:rounded-lg", children: _jsxs("div", { className: "px-4 py-5 sm:p-6", children: [_jsxs("h3", { className: "text-lg leading-6 font-medium text-foreground mb-4", children: [document ? 'Edit' : 'Create', " ", collection.slug.slice(0, -1)] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [collection.upload && !document ? (_jsxs("div", { children: [_jsxs("label", { htmlFor: "__file", className: "block text-sm font-medium text-foreground", children: ["File", _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx(Input, { type: "file", id: "__file", required: true, onChange: (e) => {
74
75
  const file = e.target.files?.[0];
75
76
  if (file)
76
77
  handleFieldChange('file', file);
77
- }, className: "block w-full text-sm text-muted-foreground file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-medium file:bg-primary/10 file:text-primary hover:file:bg-primary/20" }) })] })) : null, visibleFields.map((field) => (_jsxs("div", { children: [_jsxs("label", { htmlFor: field.name, className: "block text-sm font-medium text-foreground", children: [getFieldLabel(field), field.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx(FieldInput, { field: field, value: field.name ? formData[field.name] : undefined, onChange: (value) => field.name && handleFieldChange(field.name, value) }) })] }, field.name || 'layout'))), _jsxs("div", { className: "flex justify-end space-x-3 pt-6", children: [_jsx("button", { type: "button", onClick: onCancel, className: "bg-card py-2 px-4 border border-input rounded-md shadow-sm text-sm font-medium text-foreground hover:bg-muted focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background focus:ring-ring", children: "Cancel" }), _jsx("button", { type: "submit", disabled: isLoading, className: "inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-primary-foreground bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background focus:ring-ring disabled:opacity-50 disabled:cursor-not-allowed", children: isLoading ? 'Saving...' : 'Save' })] })] })] }) }));
78
+ }, className: "block w-full text-sm text-muted-foreground file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-medium file:bg-primary/10 file:text-primary hover:file:bg-primary/20" }) })] })) : null, visibleFields.map((field) => (_jsxs("div", { children: [_jsxs("label", { htmlFor: field.name, className: "block text-sm font-medium text-foreground", children: [getFieldLabel(field), field.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx(FieldInput, { field: field, value: field.name ? formData[field.name] : undefined, onChange: (value) => field.name && handleFieldChange(field.name, value) }) })] }, field.name || 'layout'))), _jsxs("div", { className: "flex justify-end space-x-3 pt-6", children: [_jsx(Button, { type: "button", variant: "neutral", appearance: "outline", onClick: onCancel, children: "Cancel" }), _jsx(Button, { type: "submit", variant: "brand", appearance: "solid", disabled: isLoading, children: isLoading ? 'Saving...' : 'Save' })] })] })] }) }));
78
79
  }
79
80
  // ---------------------------------------------------------------------------
80
81
  // Array field: repeatable list of sub-fields
@@ -88,7 +89,7 @@ function ArrayFieldRenderer({ field, value, onChange, }) {
88
89
  const updated = rows.map((row, i) => (i === idx ? { ...row, [key]: val } : row));
89
90
  onChange(updated);
90
91
  };
91
- return (_jsxs("div", { className: "space-y-3", children: [rows.map((row, idx) => (_jsxs("div", { className: "border border-border rounded-md p-3 space-y-2 relative", children: [_jsx("button", { type: "button", onClick: () => removeRow(idx), className: "absolute top-2 right-2 text-red-400 hover:text-red-600 text-sm", children: "Remove" }), subFields.map((sf) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-${idx}-${sf.name}`, className: "block text-xs font-medium text-muted-foreground", children: getFieldLabel(sf) }), _jsx(FieldInput, { field: sf, value: row[sf.name ?? ''], onChange: (v) => updateRow(idx, sf.name ?? '', v) })] }, sf.name)))] }, `${field.name}-row-${idx.toString()}`))), _jsx("button", { type: "button", onClick: addRow, className: "text-sm text-primary hover:text-primary/80 font-medium", children: "+ Add item" })] }));
92
+ return (_jsxs("div", { className: "space-y-3", children: [rows.map((row, idx) => (_jsxs("div", { className: "border border-border rounded-md p-3 space-y-2 relative", children: [_jsx(Button, { type: "button", variant: "danger", appearance: "ghost", size: "sm", onClick: () => removeRow(idx), className: "absolute top-2 right-2", children: "Remove" }), subFields.map((sf) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-${idx}-${sf.name}`, className: "block text-xs font-medium text-muted-foreground", children: getFieldLabel(sf) }), _jsx(FieldInput, { field: sf, value: row[sf.name ?? ''], onChange: (v) => updateRow(idx, sf.name ?? '', v) })] }, sf.name)))] }, `${field.name}-row-${idx.toString()}`))), _jsx(Button, { type: "button", variant: "brand", appearance: "ghost", size: "sm", onClick: addRow, children: "+ Add item" })] }));
92
93
  }
93
94
  // ---------------------------------------------------------------------------
94
95
  // Group field: named group of sub-fields (single object, not repeatable)
@@ -118,8 +119,8 @@ function BlocksFieldRenderer({ field, value, onChange, }) {
118
119
  };
119
120
  return (_jsxs("div", { className: "space-y-3", children: [blocks.map((block, idx) => {
120
121
  const blockDef = blockTypes.find((bt) => bt.slug === block.blockType);
121
- return (_jsxs("div", { className: "border border-border rounded-md p-3 space-y-2 relative", children: [_jsxs("div", { className: "flex items-center justify-between mb-1", children: [_jsx("span", { className: "text-xs font-semibold text-muted-foreground uppercase", children: String(block.blockType) }), _jsx("button", { type: "button", onClick: () => removeBlock(idx), className: "text-red-400 hover:text-red-600 text-sm", children: "Remove" })] }), (blockDef?.fields ?? []).map((sf) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-${idx}-${sf.name}`, className: "block text-xs font-medium text-muted-foreground", children: getFieldLabel(sf) }), _jsx(FieldInput, { field: sf, value: block[sf.name ?? ''], onChange: (v) => updateBlock(idx, sf.name ?? '', v) })] }, sf.name)))] }, `${field.name}-block-${idx.toString()}`));
122
- }), blockTypes.length > 0 && (_jsx("div", { className: "flex gap-2 flex-wrap", children: blockTypes.map((bt) => (_jsxs("button", { type: "button", onClick: () => addBlock(bt.slug), className: "text-sm text-primary hover:text-primary/80 font-medium", children: ["+ ", bt.slug] }, bt.slug))) }))] }));
122
+ return (_jsxs("div", { className: "border border-border rounded-md p-3 space-y-2 relative", children: [_jsxs("div", { className: "flex items-center justify-between mb-1", children: [_jsx("span", { className: "text-xs font-semibold text-muted-foreground uppercase", children: String(block.blockType) }), _jsx(Button, { type: "button", variant: "danger", appearance: "ghost", size: "sm", onClick: () => removeBlock(idx), children: "Remove" })] }), (blockDef?.fields ?? []).map((sf) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-${idx}-${sf.name}`, className: "block text-xs font-medium text-muted-foreground", children: getFieldLabel(sf) }), _jsx(FieldInput, { field: sf, value: block[sf.name ?? ''], onChange: (v) => updateBlock(idx, sf.name ?? '', v) })] }, sf.name)))] }, `${field.name}-block-${idx.toString()}`));
123
+ }), blockTypes.length > 0 && (_jsx("div", { className: "flex gap-2 flex-wrap", children: blockTypes.map((bt) => (_jsxs(Button, { type: "button", variant: "brand", appearance: "ghost", size: "sm", onClick: () => addBlock(bt.slug), children: ["+ ", bt.slug] }, bt.slug))) }))] }));
123
124
  }
124
125
  // ---------------------------------------------------------------------------
125
126
  // Collapsible field: expandable section of sub-fields
@@ -131,7 +132,7 @@ function CollapsibleFieldRenderer({ field, value, onChange, }) {
131
132
  const handleChange = (key, val) => {
132
133
  onChange({ ...data, [key]: val });
133
134
  };
134
- return (_jsxs("div", { className: "border border-border rounded-md", children: [_jsxs("button", { type: "button", onClick: () => setOpen(!open), className: "w-full text-left px-3 py-2 text-sm font-medium text-foreground hover:bg-muted flex items-center justify-between", children: [getFieldLabel(field), _jsx("span", { className: "text-muted-foreground", children: open ? '\u25B2' : '\u25BC' })] }), open && (_jsx("div", { className: "px-3 pb-3 space-y-3", children: subFields.map((sf) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-${sf.name}`, className: "block text-xs font-medium text-muted-foreground", children: getFieldLabel(sf) }), _jsx(FieldInput, { field: sf, value: data[sf.name ?? ''], onChange: (v) => handleChange(sf.name ?? '', v) })] }, sf.name))) }))] }));
135
+ return (_jsxs("div", { className: "border border-border rounded-md", children: [_jsxs(Button, { type: "button", variant: "neutral", appearance: "ghost", size: "clear", onClick: () => setOpen(!open), className: "w-full text-left px-3 py-2 text-sm font-medium text-foreground hover:bg-muted flex items-center justify-between", children: [getFieldLabel(field), _jsx("span", { className: "text-muted-foreground", children: open ? '\u25B2' : '\u25BC' })] }), open && (_jsx("div", { className: "px-3 pb-3 space-y-3", children: subFields.map((sf) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-${sf.name}`, className: "block text-xs font-medium text-muted-foreground", children: getFieldLabel(sf) }), _jsx(FieldInput, { field: sf, value: data[sf.name ?? ''], onChange: (v) => handleChange(sf.name ?? '', v) })] }, sf.name))) }))] }));
135
136
  }
136
137
  // ---------------------------------------------------------------------------
137
138
  // JSON field: raw JSON editor with syntax-highlighted textarea
@@ -151,7 +152,7 @@ function JsonFieldRenderer({ field, value, onChange, }) {
151
152
  onChange(raw);
152
153
  }
153
154
  }, [onChange]);
154
- return (_jsxs("div", { children: [_jsx("textarea", { id: field.name, value: formatted, onChange: handleChange, rows: 8, className: "mt-1 block w-full border-input rounded-md shadow-sm focus:ring-ring focus:border-primary sm:text-sm font-mono text-xs", spellCheck: false }), error && _jsx("p", { className: "mt-1 text-xs text-red-500", children: error })] }));
155
+ return (_jsxs("div", { children: [_jsx(Textarea, { id: field.name, value: formatted, onChange: handleChange, rows: 8, className: "mt-1 font-mono text-xs", spellCheck: false }), error && _jsx("p", { className: "mt-1 text-xs text-red-500", children: error })] }));
155
156
  }
156
157
  // ---------------------------------------------------------------------------
157
158
  // Point field: latitude/longitude pair
@@ -159,31 +160,30 @@ function JsonFieldRenderer({ field, value, onChange, }) {
159
160
  function PointFieldRenderer({ field, value, onChange, }) {
160
161
  const point = (typeof value === 'object' && value !== null ? value : { lat: 0, lng: 0 });
161
162
  const baseClasses = 'mt-1 block w-full border-input rounded-md shadow-sm focus:ring-ring focus:border-primary sm:text-sm';
162
- return (_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-lat`, className: "block text-xs font-medium text-muted-foreground", children: "Latitude" }), _jsx("input", { type: "number", id: `${field.name}-lat`, value: point.lat, onChange: (e) => onChange({ ...point, lat: Number(e.target.value) }), className: baseClasses, step: "any", min: -90, max: 90 })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-lng`, className: "block text-xs font-medium text-muted-foreground", children: "Longitude" }), _jsx("input", { type: "number", id: `${field.name}-lng`, value: point.lng, onChange: (e) => onChange({ ...point, lng: Number(e.target.value) }), className: baseClasses, step: "any", min: -180, max: 180 })] })] }));
163
+ return (_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-lat`, className: "block text-xs font-medium text-muted-foreground", children: "Latitude" }), _jsx(Input, { type: "number", id: `${field.name}-lat`, value: point.lat, onChange: (e) => onChange({ ...point, lat: Number(e.target.value) }), className: baseClasses, step: "any", min: -90, max: 90 })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: `${field.name}-lng`, className: "block text-xs font-medium text-muted-foreground", children: "Longitude" }), _jsx(Input, { type: "number", id: `${field.name}-lng`, value: point.lng, onChange: (e) => onChange({ ...point, lng: Number(e.target.value) }), className: baseClasses, step: "any", min: -180, max: 180 })] })] }));
163
164
  }
164
165
  // ---------------------------------------------------------------------------
165
166
  // Main FieldInput - renders the appropriate control for each field type
166
167
  // ---------------------------------------------------------------------------
167
168
  function FieldInput({ field, value, onChange }) {
168
- const baseClasses = 'mt-1 block w-full border-input rounded-md shadow-sm focus:ring-ring focus:border-primary sm:text-sm';
169
+ const baseClasses = 'mt-1';
169
170
  switch (field.type) {
170
171
  case 'text':
171
- return (_jsx("input", { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
172
+ return (_jsx(Input, { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
172
173
  case 'email':
173
- return (_jsx("input", { type: "email", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, placeholder: field.admin?.placeholder }));
174
+ return (_jsx(Input, { type: "email", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, placeholder: field.admin?.placeholder }));
174
175
  case 'password':
175
- return (_jsx("input", { type: "password", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, autoComplete: "new-password" }));
176
+ return (_jsx(Input, { type: "password", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, autoComplete: "new-password" }));
176
177
  case 'code':
177
- return (_jsx("textarea", { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), rows: 8, className: `${baseClasses} font-mono text-xs`, required: field.required, spellCheck: false }));
178
+ return (_jsx(Textarea, { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), rows: 8, className: `${baseClasses} font-mono text-xs`, required: field.required, spellCheck: false }));
178
179
  case 'textarea':
179
- return (_jsx("textarea", { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), rows: 4, className: baseClasses, required: field.required }));
180
+ return (_jsx(Textarea, { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), rows: 4, className: baseClasses, required: field.required }));
180
181
  case 'number':
181
- return (_jsx("input", { type: "number", id: field.name, value: typeof value === 'number' ? value : value ? Number(value) : '', onChange: (e) => onChange(Number(e.target.value) || undefined), className: baseClasses, required: field.required, min: field.min, max: field.max }));
182
+ return (_jsx(Input, { type: "number", id: field.name, value: typeof value === 'number' ? value : value ? Number(value) : '', onChange: (e) => onChange(Number(e.target.value) || undefined), className: baseClasses, required: field.required, min: field.min, max: field.max }));
182
183
  case 'checkbox':
183
- return (_jsx("input", { type: "checkbox", id: field.name, checked: Boolean(value), onChange: (e) => onChange(e.target.checked), className: "h-4 w-4 text-primary focus:ring-ring border-input rounded" }));
184
+ return (_jsx(Checkbox, { checked: Boolean(value), onChange: (checked) => onChange(checked), name: field.name }));
184
185
  case 'select': {
185
186
  const isMulti = field.hasMany === true;
186
- const selectClasses = `${baseClasses} text-foreground bg-card`;
187
187
  const optionNodes = field.options?.map((option) => {
188
188
  const optValue = typeof option === 'string' ? option : option.value;
189
189
  const optLabel = typeof option === 'string' ? option : option.label;
@@ -191,29 +191,29 @@ function FieldInput({ field, value, onChange }) {
191
191
  });
192
192
  if (isMulti) {
193
193
  const selected = Array.isArray(value) ? value : value ? [String(value)] : [];
194
- return (_jsx("select", { id: field.name, multiple: true, value: selected, onChange: (e) => {
194
+ return (_jsx(Select, { id: field.name, multiple: true, value: selected, onChange: (e) => {
195
195
  const vals = Array.from(e.target.selectedOptions).map((o) => o.value);
196
196
  onChange(vals);
197
- }, className: `${selectClasses} h-32`, required: field.required, children: optionNodes }));
197
+ }, className: `${baseClasses} h-32`, required: field.required, children: optionNodes }));
198
198
  }
199
- return (_jsxs("select", { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: selectClasses, required: field.required, children: [_jsx("option", { value: "", children: "Select an option" }), optionNodes] }));
199
+ return (_jsxs(Select, { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, children: [_jsx("option", { value: "", children: "Select an option" }), optionNodes] }));
200
200
  }
201
201
  case 'radio':
202
- return (_jsx("div", { className: "space-y-2 mt-1", children: field.options?.map((option) => {
202
+ return (_jsx(RadioGroup, { name: field.name, value: formatTextValue(value), onChange: (next) => onChange(next), className: "mt-1", children: field.options?.map((option) => {
203
203
  const optValue = typeof option === 'string' ? option : option.value;
204
204
  const optLabel = typeof option === 'string' ? option : option.label;
205
- return (_jsxs("label", { className: "flex items-center gap-2 text-sm text-foreground cursor-pointer", children: [_jsx("input", { type: "radio", name: field.name, value: optValue, checked: formatTextValue(value) === optValue, onChange: () => onChange(optValue), className: "h-4 w-4 text-primary focus:ring-ring border-input" }), optLabel] }, optValue));
205
+ return (_jsxs(RadioField, { children: [_jsx(Radio, { value: optValue }), _jsx(FieldLabel, { children: optLabel })] }, optValue));
206
206
  }) }));
207
207
  case 'relationship':
208
- return (_jsxs("div", { children: [_jsx("input", { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, placeholder: `Enter ${field.relationTo ?? 'related'} ID` }), _jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: ["Related to: ", field.relationTo ?? 'unknown'] })] }));
208
+ return (_jsxs("div", { children: [_jsx(Input, { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, placeholder: `Enter ${field.relationTo ?? 'related'} ID` }), _jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: ["Related to: ", field.relationTo ?? 'unknown'] })] }));
209
209
  case 'upload':
210
- return (_jsxs("div", { children: [_jsx("input", { type: "file", id: field.name, onChange: (e) => {
210
+ return (_jsxs("div", { children: [_jsx(Input, { type: "file", id: field.name, onChange: (e) => {
211
211
  const file = e.target.files?.[0];
212
212
  if (file)
213
213
  onChange(file);
214
214
  }, className: "block w-full text-sm text-muted-foreground file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-medium file:bg-primary/10 file:text-primary hover:file:bg-primary/20" }), typeof value === 'string' && value !== '' && (_jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: ["Current: ", value] }))] }));
215
215
  case 'date':
216
- return (_jsx("input", { type: "datetime-local", id: field.name, value: formatDateInputValue(value), onChange: (e) => onChange(e.target.value ? new Date(e.target.value) : null), className: baseClasses, required: field.required }));
216
+ return (_jsx(Input, { type: "datetime-local", id: field.name, value: formatDateInputValue(value), onChange: (e) => onChange(e.target.value ? new Date(e.target.value) : null), className: baseClasses, required: field.required }));
217
217
  case 'richText': {
218
218
  const editorConfig = field.editor;
219
219
  return (_jsx(Suspense, { fallback: _jsx("div", { className: "border border-input rounded-md h-40 flex items-center justify-center text-sm text-muted-foreground", children: "Loading editor\u2026" }), children: _jsx(RichTextEditor, { namespace: String(field.name), editorConfig: editorConfig, initialValue: value, onSerializedChange: (json) => onChange(json), className: "border border-input rounded-md" }) }));
@@ -233,6 +233,6 @@ function FieldInput({ field, value, onChange }) {
233
233
  case 'ui':
234
234
  return (_jsxs("div", { className: "border border-dashed border-input rounded-md p-3 text-sm text-muted-foreground text-center", children: ["Custom UI field: ", field.name] }));
235
235
  default:
236
- return (_jsx("input", { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
236
+ return (_jsx(Input, { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
237
237
  }
238
238
  }
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/GlobalForm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAiB,MAAM,yBAAyB,CAAC;AAsCjG,UAAU,eAAe;IACvB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAiB,GAClB,EAAE,eAAe,qBA4DjB"}
1
+ {"version":3,"file":"GlobalForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/GlobalForm.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAiB,MAAM,yBAAyB,CAAC;AAsCjG,UAAU,eAAe;IACvB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAiB,GAClB,EAAE,eAAe,qBAoDjB"}
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
+ import { Button, Checkbox, Input, Select, Textarea } from '@revealui/presentation';
3
4
  import { useState } from 'react';
4
5
  function getFieldLabel(field) {
5
6
  const { label } = field;
@@ -47,28 +48,28 @@ export function GlobalForm({ global, document, onSave, onCancel, isLoading = fal
47
48
  const handleFieldChange = (fieldName, value) => {
48
49
  setFormData((prev) => ({ ...prev, [fieldName]: value }));
49
50
  };
50
- return (_jsx("div", { className: "bg-card shadow overflow-hidden sm:rounded-lg", children: _jsxs("div", { className: "px-4 py-5 sm:p-6", children: [_jsxs("h3", { className: "text-lg leading-6 font-medium text-foreground mb-4", children: ["Edit ", global.label || global.slug] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [visibleFields.map((field) => (_jsxs("div", { children: [_jsxs("label", { htmlFor: field.name, className: "block text-sm font-medium text-foreground", children: [getFieldLabel(field), field.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx(FieldInput, { field: field, value: field.name ? formData[field.name] : undefined, onChange: (value) => field.name && handleFieldChange(field.name, value) }) })] }, field.name || 'layout'))), _jsxs("div", { className: "flex justify-end space-x-3 pt-6", children: [_jsx("button", { type: "button", onClick: onCancel, className: "bg-card py-2 px-4 border border-input rounded-md shadow-sm text-sm font-medium text-foreground hover:bg-muted focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background focus:ring-ring", children: "Cancel" }), _jsx("button", { type: "submit", disabled: isLoading, className: "inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-primary-foreground bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-background focus:ring-ring disabled:opacity-50 disabled:cursor-not-allowed", children: isLoading ? 'Saving...' : 'Save' })] })] })] }) }));
51
+ return (_jsx("div", { className: "bg-card shadow overflow-hidden sm:rounded-lg", children: _jsxs("div", { className: "px-4 py-5 sm:p-6", children: [_jsxs("h3", { className: "text-lg leading-6 font-medium text-foreground mb-4", children: ["Edit ", global.label || global.slug] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [visibleFields.map((field) => (_jsxs("div", { children: [_jsxs("label", { htmlFor: field.name, className: "block text-sm font-medium text-foreground", children: [getFieldLabel(field), field.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), _jsx("div", { className: "mt-1", children: _jsx(FieldInput, { field: field, value: field.name ? formData[field.name] : undefined, onChange: (value) => field.name && handleFieldChange(field.name, value) }) })] }, field.name || 'layout'))), _jsxs("div", { className: "flex justify-end space-x-3 pt-6", children: [_jsx(Button, { type: "button", variant: "neutral", appearance: "outline", onClick: onCancel, children: "Cancel" }), _jsx(Button, { type: "submit", variant: "brand", appearance: "solid", disabled: isLoading, children: isLoading ? 'Saving...' : 'Save' })] })] })] }) }));
51
52
  }
52
53
  function FieldInput({ field, value, onChange }) {
53
- const baseClasses = 'mt-1 block w-full border-input rounded-md shadow-sm focus:ring-ring focus:border-primary sm:text-sm';
54
+ const baseClasses = 'mt-1';
54
55
  switch (field.type) {
55
56
  case 'text':
56
- return (_jsx("input", { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
57
+ return (_jsx(Input, { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
57
58
  case 'textarea':
58
- return (_jsx("textarea", { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), rows: 4, className: baseClasses, required: field.required }));
59
+ return (_jsx(Textarea, { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), rows: 4, className: baseClasses, required: field.required }));
59
60
  case 'number':
60
- return (_jsx("input", { type: "number", id: field.name, value: typeof value === 'number' ? value : value ? Number(value) : '', onChange: (e) => onChange(Number(e.target.value) || undefined), className: baseClasses, required: field.required, min: field.min, max: field.max }));
61
+ return (_jsx(Input, { type: "number", id: field.name, value: typeof value === 'number' ? value : value ? Number(value) : '', onChange: (e) => onChange(Number(e.target.value) || undefined), className: baseClasses, required: field.required, min: field.min, max: field.max }));
61
62
  case 'checkbox':
62
- return (_jsx("input", { type: "checkbox", id: field.name, checked: Boolean(value), onChange: (e) => onChange(e.target.checked), className: "h-4 w-4 text-primary focus:ring-ring border-input rounded" }));
63
+ return (_jsx(Checkbox, { checked: Boolean(value), onChange: (checked) => onChange(checked), name: field.name }));
63
64
  case 'select':
64
- return (_jsxs("select", { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, children: [_jsx("option", { value: "", children: "Select an option" }), field.options?.map((option) => {
65
+ return (_jsxs(Select, { id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required, children: [_jsx("option", { value: "", children: "Select an option" }), field.options?.map((option) => {
65
66
  const value = typeof option === 'string' ? option : option.value;
66
67
  const label = typeof option === 'string' ? option : option.label;
67
68
  return (_jsx("option", { value: value, children: label }, value));
68
69
  })] }));
69
70
  case 'date':
70
- return (_jsx("input", { type: "datetime-local", id: field.name, value: formatDateInputValue(value), onChange: (e) => onChange(e.target.value ? new Date(e.target.value) : null), className: baseClasses, required: field.required }));
71
+ return (_jsx(Input, { type: "datetime-local", id: field.name, value: formatDateInputValue(value), onChange: (e) => onChange(e.target.value ? new Date(e.target.value) : null), className: baseClasses, required: field.required }));
71
72
  default:
72
- return (_jsx("input", { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
73
+ return (_jsx(Input, { type: "text", id: field.name, value: formatTextValue(value), onChange: (e) => onChange(e.target.value), className: baseClasses, required: field.required }));
73
74
  }
74
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/client/admin/page.tsx"],"names":[],"mappings":"AACA,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,+BAoLjD;AAED,wBAAgB,YAAY,gCAO3B;AAED,wBAAgB,oBAAoB,IAAI,QAAQ,CAS/C"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/client/admin/page.tsx"],"names":[],"mappings":"AAGA,UAAU,QAAQ;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzC,YAAY,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,+BAsJjD;AAED,wBAAgB,YAAY,gCAO3B;AAED,wBAAgB,oBAAoB,IAAI,QAAQ,CAS/C"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconCheck, IconPrimitiveContent, IconSettings } from '@revealui/presentation';
2
3
  export function RootPage({ config }) {
3
4
  const collections = (config.collections || []);
4
5
  const globals = (config.globals || []);
@@ -6,7 +7,7 @@ export function RootPage({ config }) {
6
7
  // REVEALUI_TENANT_NAME. `||` not `??`: Compose `${VAR:-}` interpolation
7
8
  // delivers unset vars as empty strings.
8
9
  const siteName = process.env.REVEALUI_BRAND_NAME || process.env.REVEALUI_TENANT_NAME || 'RevealUI';
9
- return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-foreground", children: `${siteName} Admin` }) }), _jsx("div", { className: "flex shrink-0 items-center gap-3", children: _jsxs("span", { className: "shrink-0 text-sm tabular-nums text-muted-foreground", title: "Application version", children: ["v", process.env.NEXT_PUBLIC_APP_VERSION ?? process.env.APP_VERSION ?? '0.0.0'] }) })] }) }) }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsx("div", { className: "px-4 py-6 sm:px-0", children: _jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [_jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Collections icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Collections" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: collections.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: collections.length > 0 ? (_jsx("ul", { className: "space-y-1", children: collections.map((collection) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: collection.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", collection.fields?.length || 0, " fields)"] })] }, collection.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No collections configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Globals icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Globals" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: globals.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: globals.length > 0 ? (_jsx("ul", { className: "space-y-1", children: globals.map((global) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: global.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", global.fields?.length || 0, " fields)"] })] }, global.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No globals configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "h-8 w-8 bg-success/15 rounded-full flex items-center justify-center", children: _jsxs("svg", { className: "h-5 w-5 text-success", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "System operational" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" })] }) }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "System Status" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: "Operational" })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsxs("div", { className: "text-sm text-muted-foreground", children: [siteName, " admin is running successfully with ", collections.length, " collections and", ' ', globals.length, " globals configured."] }) })] })] }) }) })] }));
10
+ return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-foreground", children: `${siteName} Admin` }) }), _jsx("div", { className: "flex shrink-0 items-center gap-3", children: _jsxs("span", { className: "shrink-0 text-sm tabular-nums text-muted-foreground", title: "Application version", children: ["v", process.env.NEXT_PUBLIC_APP_VERSION ?? process.env.APP_VERSION ?? '0.0.0'] }) })] }) }) }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsx("div", { className: "px-4 py-6 sm:px-0", children: _jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [_jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx(IconPrimitiveContent, { size: "lg", className: "h-8 w-8 text-muted-foreground", label: "Collections" }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Collections" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: collections.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: collections.length > 0 ? (_jsx("ul", { className: "space-y-1", children: collections.map((collection) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: collection.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", collection.fields?.length || 0, " fields)"] })] }, collection.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No collections configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx(IconSettings, { size: "lg", className: "h-8 w-8 text-muted-foreground", label: "Globals" }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Globals" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: globals.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: globals.length > 0 ? (_jsx("ul", { className: "space-y-1", children: globals.map((global) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: global.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", global.fields?.length || 0, " fields)"] })] }, global.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No globals configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "h-8 w-8 bg-success/15 rounded-full flex items-center justify-center", children: _jsx(IconCheck, { size: "sm", className: "h-5 w-5 text-success", label: "System operational" }) }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "System Status" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: "Operational" })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsxs("div", { className: "text-sm text-muted-foreground", children: [siteName, " admin is running successfully with ", collections.length, " collections and", ' ', globals.length, " globals configured."] }) })] })] }) }) })] }));
10
11
  }
11
12
  export function NotFoundPage() {
12
13
  return (_jsxs("div", { children: [_jsx("h1", { children: "404 - Page Not Found" }), _jsx("p", { children: "The requested admin page could not be found." })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"ImageNodeComponent.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageNodeComponent.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CA0J9C,CAAC"}
1
+ {"version":3,"file":"ImageNodeComponent.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageNodeComponent.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CA0I9C,CAAC"}
@@ -6,6 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
6
  * React component for rendering and editing images in the editor.
7
7
  */
8
8
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
9
+ import { Button, Input } from '@revealui/presentation';
9
10
  import { $getNodeByKey } from 'lexical';
10
11
  import { useCallback, useState } from 'react';
11
12
  import { OPEN_IMAGE_UPLOAD_COMMAND } from '../nodes/ImageNode.js';
@@ -61,21 +62,7 @@ export const ImageNodeComponent = (props) => {
61
62
  opacity: showControls ? 1 : 0,
62
63
  transition: 'opacity 0.2s',
63
64
  pointerEvents: showControls ? 'auto' : 'none',
64
- }, children: [_jsx("button", { type: "button", onClick: handleEdit, className: "editor-image-btn", style: {
65
- padding: '4px 8px',
66
- background: 'white',
67
- border: `1px solid var(--rvui-border, #e2e8f0)`,
68
- borderRadius: '4px',
69
- cursor: 'pointer',
70
- fontSize: '12px',
71
- }, title: "Edit Image", "aria-label": "Edit Image", children: "\u270E" }), _jsx("button", { type: "button", onClick: removeImage, className: "editor-image-btn", style: {
72
- padding: '4px 8px',
73
- background: 'white',
74
- border: `1px solid var(--rvui-border, #e2e8f0)`,
75
- borderRadius: '4px',
76
- cursor: 'pointer',
77
- fontSize: '12px',
78
- }, title: "Remove Image", "aria-label": "Remove Image", children: "\u00D7" })] })] }), isEditing ? (_jsx("input", { type: "text", value: editAlt, onChange: (e) => setEditAlt(e.target.value), onBlur: updateAlt, onKeyDown: (e) => {
65
+ }, children: [_jsx(Button, { type: "button", variant: "neutral", appearance: "outline", size: "sm", onClick: handleEdit, className: "editor-image-btn", title: "Edit Image", "aria-label": "Edit Image", children: "\u270E" }), _jsx(Button, { type: "button", variant: "neutral", appearance: "outline", size: "sm", onClick: removeImage, className: "editor-image-btn", title: "Remove Image", "aria-label": "Remove Image", children: "\u00D7" })] })] }), isEditing ? (_jsx(Input, { type: "text", value: editAlt, onChange: (e) => setEditAlt(e.target.value), onBlur: updateAlt, onKeyDown: (e) => {
79
66
  if (e.key === 'Enter') {
80
67
  updateAlt();
81
68
  }
@@ -83,13 +70,7 @@ export const ImageNodeComponent = (props) => {
83
70
  setEditAlt(data.alt || '');
84
71
  setIsEditing(false);
85
72
  }
86
- }, placeholder: "Image alt text", style: {
87
- width: '100%',
88
- marginTop: '8px',
89
- padding: '4px 8px',
90
- border: `1px solid var(--rvui-border, #e2e8f0)`,
91
- borderRadius: '4px',
92
- } })) : (data.caption && (_jsx("figcaption", { style: {
73
+ }, placeholder: "Image alt text", className: "mt-2 w-full" })) : (data.caption && (_jsx("figcaption", { style: {
93
74
  marginTop: '8px',
94
75
  fontSize: '14px',
95
76
  color: 'var(--rvui-text-2, #64748b)',
@@ -1 +1 @@
1
- {"version":3,"file":"ImageUploadButton.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageUploadButton.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,UAAU,sBAAsB;IAC9B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAqBD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAkJ9D,CAAC"}
1
+ {"version":3,"file":"ImageUploadButton.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageUploadButton.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,UAAU,sBAAsB;IAC9B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAqBD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAkJ9D,CAAC"}