@dataverse-kit/form-runtime 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -0
  3. package/dist/businessRules-U1_MBgyG.d.cts +372 -0
  4. package/dist/businessRules-U1_MBgyG.d.ts +372 -0
  5. package/dist/context.cjs +151 -0
  6. package/dist/context.cjs.map +1 -0
  7. package/dist/context.d.cts +132 -0
  8. package/dist/context.d.ts +132 -0
  9. package/dist/context.mjs +113 -0
  10. package/dist/context.mjs.map +1 -0
  11. package/dist/control-DFOg_pc_.d.cts +1027 -0
  12. package/dist/control-DaXBm-52.d.ts +1027 -0
  13. package/dist/gridCustomizer-C0V9FAE_.d.ts +569 -0
  14. package/dist/gridCustomizer-mJO-kmQ4.d.cts +569 -0
  15. package/dist/hooks.cjs +85 -0
  16. package/dist/hooks.cjs.map +1 -0
  17. package/dist/hooks.d.cts +24 -0
  18. package/dist/hooks.d.ts +24 -0
  19. package/dist/hooks.mjs +60 -0
  20. package/dist/hooks.mjs.map +1 -0
  21. package/dist/icons.cjs +202 -0
  22. package/dist/icons.cjs.map +1 -0
  23. package/dist/icons.d.cts +130 -0
  24. package/dist/icons.d.ts +130 -0
  25. package/dist/icons.mjs +165 -0
  26. package/dist/icons.mjs.map +1 -0
  27. package/dist/index.cjs +6509 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +410 -0
  30. package/dist/index.d.ts +410 -0
  31. package/dist/index.mjs +6490 -0
  32. package/dist/index.mjs.map +1 -0
  33. package/dist/runtime-capabilities-BdGDdu0d.d.cts +119 -0
  34. package/dist/runtime-capabilities-Brfc7loJ.d.ts +119 -0
  35. package/dist/theme-BfeZIxmZ.d.cts +74 -0
  36. package/dist/theme-BfeZIxmZ.d.ts +74 -0
  37. package/dist/theme.cjs +215 -0
  38. package/dist/theme.cjs.map +1 -0
  39. package/dist/theme.d.cts +32 -0
  40. package/dist/theme.d.ts +32 -0
  41. package/dist/theme.mjs +186 -0
  42. package/dist/theme.mjs.map +1 -0
  43. package/dist/types.cjs +976 -0
  44. package/dist/types.cjs.map +1 -0
  45. package/dist/types.d.cts +813 -0
  46. package/dist/types.d.ts +813 -0
  47. package/dist/types.mjs +902 -0
  48. package/dist/types.mjs.map +1 -0
  49. package/dist/utils.cjs +250 -0
  50. package/dist/utils.cjs.map +1 -0
  51. package/dist/utils.d.cts +99 -0
  52. package/dist/utils.d.ts +99 -0
  53. package/dist/utils.mjs +220 -0
  54. package/dist/utils.mjs.map +1 -0
  55. package/dist/v8.cjs +4622 -0
  56. package/dist/v8.cjs.map +1 -0
  57. package/dist/v8.d.cts +730 -0
  58. package/dist/v8.d.ts +730 -0
  59. package/dist/v8.mjs +4622 -0
  60. package/dist/v8.mjs.map +1 -0
  61. package/dist/v9.cjs +19 -0
  62. package/dist/v9.cjs.map +1 -0
  63. package/dist/v9.d.cts +2 -0
  64. package/dist/v9.d.ts +2 -0
  65. package/dist/v9.mjs +1 -0
  66. package/dist/v9.mjs.map +1 -0
  67. package/package.json +113 -0
@@ -0,0 +1,119 @@
1
+ import { x as ControlDefinition } from './control-DFOg_pc_.cjs';
2
+
3
+ /**
4
+ * Async capability shapes exposed by FormRuntimeContext.
5
+ *
6
+ * Form-runtime defines what it NEEDS to render. The editor and the
7
+ * generated host code each provide an implementation:
8
+ *
9
+ * - Editor (`apps/form-builder/src/contexts/EditorFormRuntimeProvider.tsx`)
10
+ * wires these to the form-builder's Zustand stores + Dataverse client.
11
+ * - Generated host code wires these to `IApiService` from
12
+ * `@dataverse-kit/api-service`.
13
+ *
14
+ * The capability returns RAW DATA (no loading/error state). Form-runtime
15
+ * provides hooks (`useLiveData`, `useWebResource`, `useLookupSearch`) that
16
+ * wrap each capability and manage the React-state choreography.
17
+ */
18
+
19
+ /** Result of `fetchLiveData(control)` — successful fetch. */
20
+ interface LiveDataResult {
21
+ records: Record<string, unknown>[];
22
+ /** Attribute names extracted from FetchXML (for auto-generating columns). */
23
+ fetchXmlAttributes: string[];
24
+ /** Timeline items — populated only for timeline controls; null otherwise. */
25
+ timelineItems: TimelineItem[] | null;
26
+ }
27
+ /** Result of `fetchWebResource(name, type?)` — successful fetch. */
28
+ interface WebResourceData {
29
+ /** Decoded text content (HTML, CSS, JS, etc.) or base64-encoded binary. */
30
+ content: string;
31
+ /** MIME type derived from the Dataverse web-resource type code. */
32
+ contentType: string;
33
+ /** Display name from the Dataverse record. */
34
+ displayName: string;
35
+ }
36
+ /** Result of `searchLookup(entitySetName, term, options)` — successful fetch. */
37
+ interface LookupResult {
38
+ /** Primary-key GUID of the record. */
39
+ id: string;
40
+ /** Display label — typically the entity's primary-name attribute. */
41
+ primaryName: string;
42
+ /** Raw record fields, for callers that need secondary display (subtitles, avatars). */
43
+ record: Record<string, unknown>;
44
+ }
45
+ /**
46
+ * Timeline item rendered by the `timeline` control. Lifted from
47
+ * `apps/form-builder/src/utils/timelineFetchXml.ts` — the runtime owns
48
+ * the shape; the editor's timelineFetchXml utility will re-import it
49
+ * once the util moves into form-runtime (deferred follow-up).
50
+ */
51
+ interface TimelineItem {
52
+ id: string;
53
+ type: 'email' | 'phonecall' | 'task' | 'note' | 'appointment' | 'other';
54
+ icon: string;
55
+ title: string;
56
+ description: string;
57
+ time: string;
58
+ color: string;
59
+ createdon: Date;
60
+ }
61
+ /** Dataverse connection state — surfaced to controls that need it (WebResourceRenderer). */
62
+ interface FormRuntimeConnection {
63
+ status: 'connected' | 'connecting' | 'disconnected' | 'error';
64
+ /** Root URL (`https://<org>.crm.dynamics.com`) when connected; undefined otherwise. */
65
+ dynamicsUrl?: string;
66
+ }
67
+ /** Preview-context state — surfaced to controls that need it for postMessage / parameter passing. */
68
+ interface FormRuntimePreviewContext {
69
+ recordId?: string;
70
+ entityLogicalName?: string;
71
+ }
72
+ /** Options for `searchLookup`. */
73
+ interface LookupSearchOptions {
74
+ /** OData $filter to narrow the search domain (e.g. statecode-active). */
75
+ filter?: string;
76
+ /** Max rows to return — defaults to 10 if omitted. */
77
+ top?: number;
78
+ /** Specific FetchXML view to run instead of an OData $select; mutually exclusive with filter. */
79
+ fetchXml?: string;
80
+ /** AbortSignal so React effect cleanup can cancel in-flight requests. */
81
+ signal?: AbortSignal;
82
+ }
83
+ /**
84
+ * Async capabilities the runtime needs but doesn't own.
85
+ *
86
+ * Every method returns a Promise of raw data (or rejects with an Error).
87
+ * No React-state fields here — runtime hooks layer on top.
88
+ */
89
+ interface FormRuntimeCapabilities {
90
+ /** Dataverse connection snapshot. Re-renders the runtime when status changes. */
91
+ connection: FormRuntimeConnection;
92
+ /** Preview-record snapshot (record being shown in the editor's preview pane). */
93
+ previewContext: FormRuntimePreviewContext;
94
+ /**
95
+ * Fetch live data for a bound control (subgrid records, timeline items).
96
+ * Implementation may early-return empty when not connected or when the
97
+ * editor's live-preview toggle is off — that's a successful fetch with
98
+ * zero records, NOT an error.
99
+ */
100
+ fetchLiveData(control: ControlDefinition, options?: {
101
+ signal?: AbortSignal;
102
+ }): Promise<LiveDataResult>;
103
+ /**
104
+ * Fetch a web resource by name. `type` is the Dataverse type code
105
+ * (1=HTML, 2=CSS, 3=JS, ...) — when provided it short-circuits the
106
+ * metadata lookup.
107
+ */
108
+ fetchWebResource(name: string, type?: string, options?: {
109
+ signal?: AbortSignal;
110
+ }): Promise<WebResourceData>;
111
+ /**
112
+ * Search a lookup target entity. `entitySetName` is the plural set name
113
+ * (e.g. "accounts"). `term` is the user-typed search string; empty
114
+ * string means "return top recent records".
115
+ */
116
+ searchLookup(entitySetName: string, term: string, options?: LookupSearchOptions): Promise<LookupResult[]>;
117
+ }
118
+
119
+ export type { FormRuntimeCapabilities as F, LiveDataResult as L, TimelineItem as T, WebResourceData as W, FormRuntimeConnection as a, FormRuntimePreviewContext as b, LookupResult as c, LookupSearchOptions as d };
@@ -0,0 +1,119 @@
1
+ import { x as ControlDefinition } from './control-DaXBm-52.js';
2
+
3
+ /**
4
+ * Async capability shapes exposed by FormRuntimeContext.
5
+ *
6
+ * Form-runtime defines what it NEEDS to render. The editor and the
7
+ * generated host code each provide an implementation:
8
+ *
9
+ * - Editor (`apps/form-builder/src/contexts/EditorFormRuntimeProvider.tsx`)
10
+ * wires these to the form-builder's Zustand stores + Dataverse client.
11
+ * - Generated host code wires these to `IApiService` from
12
+ * `@dataverse-kit/api-service`.
13
+ *
14
+ * The capability returns RAW DATA (no loading/error state). Form-runtime
15
+ * provides hooks (`useLiveData`, `useWebResource`, `useLookupSearch`) that
16
+ * wrap each capability and manage the React-state choreography.
17
+ */
18
+
19
+ /** Result of `fetchLiveData(control)` — successful fetch. */
20
+ interface LiveDataResult {
21
+ records: Record<string, unknown>[];
22
+ /** Attribute names extracted from FetchXML (for auto-generating columns). */
23
+ fetchXmlAttributes: string[];
24
+ /** Timeline items — populated only for timeline controls; null otherwise. */
25
+ timelineItems: TimelineItem[] | null;
26
+ }
27
+ /** Result of `fetchWebResource(name, type?)` — successful fetch. */
28
+ interface WebResourceData {
29
+ /** Decoded text content (HTML, CSS, JS, etc.) or base64-encoded binary. */
30
+ content: string;
31
+ /** MIME type derived from the Dataverse web-resource type code. */
32
+ contentType: string;
33
+ /** Display name from the Dataverse record. */
34
+ displayName: string;
35
+ }
36
+ /** Result of `searchLookup(entitySetName, term, options)` — successful fetch. */
37
+ interface LookupResult {
38
+ /** Primary-key GUID of the record. */
39
+ id: string;
40
+ /** Display label — typically the entity's primary-name attribute. */
41
+ primaryName: string;
42
+ /** Raw record fields, for callers that need secondary display (subtitles, avatars). */
43
+ record: Record<string, unknown>;
44
+ }
45
+ /**
46
+ * Timeline item rendered by the `timeline` control. Lifted from
47
+ * `apps/form-builder/src/utils/timelineFetchXml.ts` — the runtime owns
48
+ * the shape; the editor's timelineFetchXml utility will re-import it
49
+ * once the util moves into form-runtime (deferred follow-up).
50
+ */
51
+ interface TimelineItem {
52
+ id: string;
53
+ type: 'email' | 'phonecall' | 'task' | 'note' | 'appointment' | 'other';
54
+ icon: string;
55
+ title: string;
56
+ description: string;
57
+ time: string;
58
+ color: string;
59
+ createdon: Date;
60
+ }
61
+ /** Dataverse connection state — surfaced to controls that need it (WebResourceRenderer). */
62
+ interface FormRuntimeConnection {
63
+ status: 'connected' | 'connecting' | 'disconnected' | 'error';
64
+ /** Root URL (`https://<org>.crm.dynamics.com`) when connected; undefined otherwise. */
65
+ dynamicsUrl?: string;
66
+ }
67
+ /** Preview-context state — surfaced to controls that need it for postMessage / parameter passing. */
68
+ interface FormRuntimePreviewContext {
69
+ recordId?: string;
70
+ entityLogicalName?: string;
71
+ }
72
+ /** Options for `searchLookup`. */
73
+ interface LookupSearchOptions {
74
+ /** OData $filter to narrow the search domain (e.g. statecode-active). */
75
+ filter?: string;
76
+ /** Max rows to return — defaults to 10 if omitted. */
77
+ top?: number;
78
+ /** Specific FetchXML view to run instead of an OData $select; mutually exclusive with filter. */
79
+ fetchXml?: string;
80
+ /** AbortSignal so React effect cleanup can cancel in-flight requests. */
81
+ signal?: AbortSignal;
82
+ }
83
+ /**
84
+ * Async capabilities the runtime needs but doesn't own.
85
+ *
86
+ * Every method returns a Promise of raw data (or rejects with an Error).
87
+ * No React-state fields here — runtime hooks layer on top.
88
+ */
89
+ interface FormRuntimeCapabilities {
90
+ /** Dataverse connection snapshot. Re-renders the runtime when status changes. */
91
+ connection: FormRuntimeConnection;
92
+ /** Preview-record snapshot (record being shown in the editor's preview pane). */
93
+ previewContext: FormRuntimePreviewContext;
94
+ /**
95
+ * Fetch live data for a bound control (subgrid records, timeline items).
96
+ * Implementation may early-return empty when not connected or when the
97
+ * editor's live-preview toggle is off — that's a successful fetch with
98
+ * zero records, NOT an error.
99
+ */
100
+ fetchLiveData(control: ControlDefinition, options?: {
101
+ signal?: AbortSignal;
102
+ }): Promise<LiveDataResult>;
103
+ /**
104
+ * Fetch a web resource by name. `type` is the Dataverse type code
105
+ * (1=HTML, 2=CSS, 3=JS, ...) — when provided it short-circuits the
106
+ * metadata lookup.
107
+ */
108
+ fetchWebResource(name: string, type?: string, options?: {
109
+ signal?: AbortSignal;
110
+ }): Promise<WebResourceData>;
111
+ /**
112
+ * Search a lookup target entity. `entitySetName` is the plural set name
113
+ * (e.g. "accounts"). `term` is the user-typed search string; empty
114
+ * string means "return top recent records".
115
+ */
116
+ searchLookup(entitySetName: string, term: string, options?: LookupSearchOptions): Promise<LookupResult[]>;
117
+ }
118
+
119
+ export type { FormRuntimeCapabilities as F, LiveDataResult as L, TimelineItem as T, WebResourceData as W, FormRuntimeConnection as a, FormRuntimePreviewContext as b, LookupResult as c, LookupSearchOptions as d };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Theme configuration for Form Builder
3
+ * Provides Canvas-app-style theming with 9 preset themes
4
+ */
5
+ interface FormThemeColors {
6
+ /** Main accent color for buttons, links, focus rings */
7
+ primary: string;
8
+ /** Darker variant of primary */
9
+ primaryDark: string;
10
+ /** Form header bar background */
11
+ headerBackground: string;
12
+ /** Section card background */
13
+ sectionBackground: string;
14
+ /** Canvas/page background */
15
+ canvasBackground: string;
16
+ /** Main text color */
17
+ textPrimary: string;
18
+ /** Muted/secondary text color */
19
+ textSecondary: string;
20
+ /** Section and component borders */
21
+ border: string;
22
+ /** Input field background */
23
+ inputBackground: string;
24
+ /** Input field borders */
25
+ inputBorder: string;
26
+ }
27
+ interface FormTheme {
28
+ id: string;
29
+ name: string;
30
+ colors: FormThemeColors;
31
+ }
32
+ interface GradientStop {
33
+ color: string;
34
+ position: number;
35
+ }
36
+ type BackgroundConfig = {
37
+ type: 'color';
38
+ color: string;
39
+ } | {
40
+ type: 'image';
41
+ src: string;
42
+ size: 'cover' | 'contain' | 'auto';
43
+ position: string;
44
+ repeat: 'no-repeat' | 'repeat' | 'repeat-x' | 'repeat-y';
45
+ opacity?: number;
46
+ } | {
47
+ type: 'gradient';
48
+ direction: number;
49
+ stops: GradientStop[];
50
+ };
51
+ interface FormThemeSettings {
52
+ /** The preset theme ID (e.g., 'blue', 'coral') */
53
+ presetId: string;
54
+ /** Optional custom background color that overrides theme's canvasBackground */
55
+ customBackgroundColor?: string;
56
+ /** Enhanced canvas background (color, image, or gradient) */
57
+ canvasBackground?: BackgroundConfig;
58
+ /** Enhanced header background (color, image, or gradient). When undefined, uses theme's headerBackground. */
59
+ headerBackground?: BackgroundConfig;
60
+ }
61
+ /**
62
+ * 9 preset themes matching Canvas app styling
63
+ */
64
+ declare const THEME_PRESETS: FormTheme[];
65
+ /** Default theme (Soft blue) */
66
+ declare const DEFAULT_THEME: FormTheme;
67
+ /** Standard color palette for the color picker (like Canvas app) */
68
+ declare const STANDARD_COLORS: string[];
69
+ /** Get theme by ID, falls back to default */
70
+ declare function getThemeById(id: string): FormTheme;
71
+ /** Get theme colors for a form, applying custom background if set */
72
+ declare function getResolvedThemeColors(themeSettings?: FormThemeSettings): FormThemeColors;
73
+
74
+ export { type BackgroundConfig as B, DEFAULT_THEME as D, type FormTheme as F, type GradientStop as G, STANDARD_COLORS as S, THEME_PRESETS as T, type FormThemeColors as a, type FormThemeSettings as b, getThemeById as c, getResolvedThemeColors as g };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Theme configuration for Form Builder
3
+ * Provides Canvas-app-style theming with 9 preset themes
4
+ */
5
+ interface FormThemeColors {
6
+ /** Main accent color for buttons, links, focus rings */
7
+ primary: string;
8
+ /** Darker variant of primary */
9
+ primaryDark: string;
10
+ /** Form header bar background */
11
+ headerBackground: string;
12
+ /** Section card background */
13
+ sectionBackground: string;
14
+ /** Canvas/page background */
15
+ canvasBackground: string;
16
+ /** Main text color */
17
+ textPrimary: string;
18
+ /** Muted/secondary text color */
19
+ textSecondary: string;
20
+ /** Section and component borders */
21
+ border: string;
22
+ /** Input field background */
23
+ inputBackground: string;
24
+ /** Input field borders */
25
+ inputBorder: string;
26
+ }
27
+ interface FormTheme {
28
+ id: string;
29
+ name: string;
30
+ colors: FormThemeColors;
31
+ }
32
+ interface GradientStop {
33
+ color: string;
34
+ position: number;
35
+ }
36
+ type BackgroundConfig = {
37
+ type: 'color';
38
+ color: string;
39
+ } | {
40
+ type: 'image';
41
+ src: string;
42
+ size: 'cover' | 'contain' | 'auto';
43
+ position: string;
44
+ repeat: 'no-repeat' | 'repeat' | 'repeat-x' | 'repeat-y';
45
+ opacity?: number;
46
+ } | {
47
+ type: 'gradient';
48
+ direction: number;
49
+ stops: GradientStop[];
50
+ };
51
+ interface FormThemeSettings {
52
+ /** The preset theme ID (e.g., 'blue', 'coral') */
53
+ presetId: string;
54
+ /** Optional custom background color that overrides theme's canvasBackground */
55
+ customBackgroundColor?: string;
56
+ /** Enhanced canvas background (color, image, or gradient) */
57
+ canvasBackground?: BackgroundConfig;
58
+ /** Enhanced header background (color, image, or gradient). When undefined, uses theme's headerBackground. */
59
+ headerBackground?: BackgroundConfig;
60
+ }
61
+ /**
62
+ * 9 preset themes matching Canvas app styling
63
+ */
64
+ declare const THEME_PRESETS: FormTheme[];
65
+ /** Default theme (Soft blue) */
66
+ declare const DEFAULT_THEME: FormTheme;
67
+ /** Standard color palette for the color picker (like Canvas app) */
68
+ declare const STANDARD_COLORS: string[];
69
+ /** Get theme by ID, falls back to default */
70
+ declare function getThemeById(id: string): FormTheme;
71
+ /** Get theme colors for a form, applying custom background if set */
72
+ declare function getResolvedThemeColors(themeSettings?: FormThemeSettings): FormThemeColors;
73
+
74
+ export { type BackgroundConfig as B, DEFAULT_THEME as D, type FormTheme as F, type GradientStop as G, STANDARD_COLORS as S, THEME_PRESETS as T, type FormThemeColors as a, type FormThemeSettings as b, getThemeById as c, getResolvedThemeColors as g };
package/dist/theme.cjs ADDED
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/theme/index.ts
21
+ var theme_exports = {};
22
+ __export(theme_exports, {
23
+ FormThemeProvider: () => FormThemeProvider,
24
+ ThemeContext: () => ThemeContext,
25
+ useFormTheme: () => useFormTheme
26
+ });
27
+ module.exports = __toCommonJS(theme_exports);
28
+
29
+ // src/theme/FormThemeContext.tsx
30
+ var import_react = require("react");
31
+
32
+ // src/types/theme.ts
33
+ var THEME_PRESETS = [
34
+ {
35
+ id: "soft-blue",
36
+ name: "Soft blue",
37
+ colors: {
38
+ primary: "#0078d4",
39
+ primaryDark: "#005a9e",
40
+ headerBackground: "#ffffff",
41
+ sectionBackground: "#ffffff",
42
+ canvasBackground: "#f3f2f1",
43
+ textPrimary: "#323130",
44
+ textSecondary: "#605e5c",
45
+ border: "#edebe9",
46
+ inputBackground: "#ffffff",
47
+ inputBorder: "#8a8886"
48
+ }
49
+ },
50
+ {
51
+ id: "blue",
52
+ name: "Blue",
53
+ colors: {
54
+ primary: "#0078d4",
55
+ primaryDark: "#005a9e",
56
+ headerBackground: "#0078d4",
57
+ sectionBackground: "#e6f2ff",
58
+ canvasBackground: "#e6f2ff",
59
+ textPrimary: "#323130",
60
+ textSecondary: "#605e5c",
61
+ border: "#c7e0f4",
62
+ inputBackground: "#ffffff",
63
+ inputBorder: "#0078d4"
64
+ }
65
+ },
66
+ {
67
+ id: "light",
68
+ name: "Light",
69
+ colors: {
70
+ primary: "#605e5c",
71
+ primaryDark: "#3b3a39",
72
+ headerBackground: "#f5f5f5",
73
+ sectionBackground: "#ffffff",
74
+ canvasBackground: "#fafafa",
75
+ textPrimary: "#323130",
76
+ textSecondary: "#605e5c",
77
+ border: "#e1dfdd",
78
+ inputBackground: "#ffffff",
79
+ inputBorder: "#8a8886"
80
+ }
81
+ },
82
+ {
83
+ id: "coral",
84
+ name: "Coral",
85
+ colors: {
86
+ primary: "#d83b01",
87
+ primaryDark: "#a52a00",
88
+ headerBackground: "#d83b01",
89
+ sectionBackground: "#fff4f0",
90
+ canvasBackground: "#fff4f0",
91
+ textPrimary: "#323130",
92
+ textSecondary: "#605e5c",
93
+ border: "#f3d6cd",
94
+ inputBackground: "#ffffff",
95
+ inputBorder: "#d83b01"
96
+ }
97
+ },
98
+ {
99
+ id: "red",
100
+ name: "Red",
101
+ colors: {
102
+ primary: "#a4262c",
103
+ primaryDark: "#7e1e23",
104
+ headerBackground: "#a4262c",
105
+ sectionBackground: "#fdf3f4",
106
+ canvasBackground: "#fdf3f4",
107
+ textPrimary: "#323130",
108
+ textSecondary: "#605e5c",
109
+ border: "#f1d3d5",
110
+ inputBackground: "#ffffff",
111
+ inputBorder: "#a4262c"
112
+ }
113
+ },
114
+ {
115
+ id: "steel",
116
+ name: "Steel",
117
+ colors: {
118
+ primary: "#004578",
119
+ primaryDark: "#002d4e",
120
+ headerBackground: "#004578",
121
+ sectionBackground: "#f0f4f7",
122
+ canvasBackground: "#e8eef2",
123
+ textPrimary: "#323130",
124
+ textSecondary: "#605e5c",
125
+ border: "#c8d4dc",
126
+ inputBackground: "#ffffff",
127
+ inputBorder: "#004578"
128
+ }
129
+ },
130
+ {
131
+ id: "dune",
132
+ name: "Dune",
133
+ colors: {
134
+ primary: "#7a6855",
135
+ primaryDark: "#5c4f3f",
136
+ headerBackground: "#7a6855",
137
+ sectionBackground: "#f5f3f0",
138
+ canvasBackground: "#e8e4df",
139
+ textPrimary: "#323130",
140
+ textSecondary: "#605e5c",
141
+ border: "#d6d0c8",
142
+ inputBackground: "#ffffff",
143
+ inputBorder: "#7a6855"
144
+ }
145
+ },
146
+ {
147
+ id: "lavender",
148
+ name: "Lavender",
149
+ colors: {
150
+ primary: "#5c2d91",
151
+ primaryDark: "#472270",
152
+ headerBackground: "#5c2d91",
153
+ sectionBackground: "#f9f5ff",
154
+ canvasBackground: "#f5f0fa",
155
+ textPrimary: "#323130",
156
+ textSecondary: "#605e5c",
157
+ border: "#e1d4f0",
158
+ inputBackground: "#ffffff",
159
+ inputBorder: "#5c2d91"
160
+ }
161
+ },
162
+ {
163
+ id: "brown",
164
+ name: "Brown",
165
+ colors: {
166
+ primary: "#6d4c41",
167
+ primaryDark: "#4e362e",
168
+ headerBackground: "#6d4c41",
169
+ sectionBackground: "#f5f0ed",
170
+ canvasBackground: "#ebe5e1",
171
+ textPrimary: "#323130",
172
+ textSecondary: "#605e5c",
173
+ border: "#d4ccc7",
174
+ inputBackground: "#ffffff",
175
+ inputBorder: "#6d4c41"
176
+ }
177
+ }
178
+ ];
179
+ var DEFAULT_THEME = THEME_PRESETS[0];
180
+ function getThemeById(id) {
181
+ return THEME_PRESETS.find((t) => t.id === id) ?? DEFAULT_THEME;
182
+ }
183
+ function getResolvedThemeColors(themeSettings) {
184
+ const theme = getThemeById(themeSettings?.presetId ?? "soft-blue");
185
+ if (themeSettings?.customBackgroundColor) {
186
+ return {
187
+ ...theme.colors,
188
+ canvasBackground: themeSettings.customBackgroundColor
189
+ };
190
+ }
191
+ return theme.colors;
192
+ }
193
+
194
+ // src/theme/FormThemeContext.tsx
195
+ var import_jsx_runtime = require("react/jsx-runtime");
196
+ var ThemeContext = (0, import_react.createContext)(DEFAULT_THEME.colors);
197
+ function useFormTheme() {
198
+ return (0, import_react.useContext)(ThemeContext);
199
+ }
200
+ var FormThemeProvider = ({
201
+ themeSettings,
202
+ children
203
+ }) => {
204
+ const themeColors = (0, import_react.useMemo)(() => {
205
+ return getResolvedThemeColors(themeSettings);
206
+ }, [themeSettings]);
207
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value: themeColors, children });
208
+ };
209
+ // Annotate the CommonJS export names for ESM import in node:
210
+ 0 && (module.exports = {
211
+ FormThemeProvider,
212
+ ThemeContext,
213
+ useFormTheme
214
+ });
215
+ //# sourceMappingURL=theme.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme/index.ts","../src/theme/FormThemeContext.tsx","../src/types/theme.ts"],"sourcesContent":["// Theme context + provider hook. See ./FormThemeContext.tsx for the\n// inversion-of-control note (provider takes themeSettings as a prop).\n\nexport {\n ThemeContext,\n FormThemeProvider,\n useFormTheme,\n type FormThemeProviderProps,\n} from './FormThemeContext';\n","import React, { createContext, useContext, useMemo } from 'react';\nimport {\n FormThemeColors,\n FormThemeSettings,\n DEFAULT_THEME,\n getResolvedThemeColors,\n} from '../types';\n\n/**\n * Theme context provides resolved theme colors to runtime components.\n *\n * Lifted from apps/form-builder/src/contexts/ThemeContext.tsx in Phase 1a\n * of the WYSIWYG-canvas refactor. Note the inversion: this provider takes\n * `themeSettings` as a prop rather than reading the editor's Zustand store.\n * The form-builder app supplies a thin wrapper that subscribes to its\n * `useDesignerStore` selector and passes the value down — that keeps\n * form-runtime free of editor-state dependencies and reusable by any host\n * (designer canvas, preview, generated form code, the runtime.html entry).\n */\nexport const ThemeContext = createContext<FormThemeColors>(DEFAULT_THEME.colors);\n\n/** Hook to access the current form theme colors. */\nexport function useFormTheme(): FormThemeColors {\n return useContext(ThemeContext);\n}\n\nexport interface FormThemeProviderProps {\n /**\n * Theme settings to resolve. Pass `form.settings.theme` from your form\n * definition. When `undefined`, the resolver returns the DEFAULT_THEME\n * colors — same fallback the form-builder editor relied on.\n */\n themeSettings: FormThemeSettings | undefined;\n children: React.ReactNode;\n}\n\n/**\n * Theme provider that resolves theme from caller-supplied settings.\n */\nexport const FormThemeProvider: React.FC<FormThemeProviderProps> = ({\n themeSettings,\n children,\n}) => {\n const themeColors = useMemo(() => {\n return getResolvedThemeColors(themeSettings);\n }, [themeSettings]);\n\n return <ThemeContext.Provider value={themeColors}>{children}</ThemeContext.Provider>;\n};\n","/**\n * Theme configuration for Form Builder\n * Provides Canvas-app-style theming with 9 preset themes\n */\n\nexport interface FormThemeColors {\n /** Main accent color for buttons, links, focus rings */\n primary: string;\n /** Darker variant of primary */\n primaryDark: string;\n /** Form header bar background */\n headerBackground: string;\n /** Section card background */\n sectionBackground: string;\n /** Canvas/page background */\n canvasBackground: string;\n /** Main text color */\n textPrimary: string;\n /** Muted/secondary text color */\n textSecondary: string;\n /** Section and component borders */\n border: string;\n /** Input field background */\n inputBackground: string;\n /** Input field borders */\n inputBorder: string;\n}\n\nexport interface FormTheme {\n id: string;\n name: string;\n colors: FormThemeColors;\n}\n\nexport interface GradientStop {\n color: string;\n position: number; // 0-100\n}\n\nexport type BackgroundConfig =\n | { type: 'color'; color: string }\n | { type: 'image'; src: string; size: 'cover' | 'contain' | 'auto'; position: string;\n repeat: 'no-repeat' | 'repeat' | 'repeat-x' | 'repeat-y'; opacity?: number }\n | { type: 'gradient'; direction: number; stops: GradientStop[] };\n\nexport interface FormThemeSettings {\n /** The preset theme ID (e.g., 'blue', 'coral') */\n presetId: string;\n /** Optional custom background color that overrides theme's canvasBackground */\n customBackgroundColor?: string;\n /** Enhanced canvas background (color, image, or gradient) */\n canvasBackground?: BackgroundConfig;\n /** Enhanced header background (color, image, or gradient). When undefined, uses theme's headerBackground. */\n headerBackground?: BackgroundConfig;\n}\n\n/**\n * 9 preset themes matching Canvas app styling\n */\nexport const THEME_PRESETS: FormTheme[] = [\n {\n id: 'soft-blue',\n name: 'Soft blue',\n colors: {\n primary: '#0078d4',\n primaryDark: '#005a9e',\n headerBackground: '#ffffff',\n sectionBackground: '#ffffff',\n canvasBackground: '#f3f2f1',\n textPrimary: '#323130',\n textSecondary: '#605e5c',\n border: '#edebe9',\n inputBackground: '#ffffff',\n inputBorder: '#8a8886',\n },\n },\n {\n id: 'blue',\n name: 'Blue',\n colors: {\n primary: '#0078d4',\n primaryDark: '#005a9e',\n headerBackground: '#0078d4',\n sectionBackground: '#e6f2ff',\n canvasBackground: '#e6f2ff',\n textPrimary: '#323130',\n textSecondary: '#605e5c',\n border: '#c7e0f4',\n inputBackground: '#ffffff',\n inputBorder: '#0078d4',\n },\n },\n {\n id: 'light',\n name: 'Light',\n colors: {\n primary: '#605e5c',\n primaryDark: '#3b3a39',\n headerBackground: '#f5f5f5',\n sectionBackground: '#ffffff',\n canvasBackground: '#fafafa',\n textPrimary: '#323130',\n textSecondary: '#605e5c',\n border: '#e1dfdd',\n inputBackground: '#ffffff',\n inputBorder: '#8a8886',\n },\n },\n {\n id: 'coral',\n name: 'Coral',\n colors: {\n primary: '#d83b01',\n primaryDark: '#a52a00',\n headerBackground: '#d83b01',\n sectionBackground: '#fff4f0',\n canvasBackground: '#fff4f0',\n textPrimary: '#323130',\n textSecondary: '#605e5c',\n border: '#f3d6cd',\n inputBackground: '#ffffff',\n inputBorder: '#d83b01',\n },\n },\n {\n id: 'red',\n name: 'Red',\n colors: {\n primary: '#a4262c',\n primaryDark: '#7e1e23',\n headerBackground: '#a4262c',\n sectionBackground: '#fdf3f4',\n canvasBackground: '#fdf3f4',\n textPrimary: '#323130',\n textSecondary: '#605e5c',\n border: '#f1d3d5',\n inputBackground: '#ffffff',\n inputBorder: '#a4262c',\n },\n },\n {\n id: 'steel',\n name: 'Steel',\n colors: {\n primary: '#004578',\n primaryDark: '#002d4e',\n headerBackground: '#004578',\n sectionBackground: '#f0f4f7',\n canvasBackground: '#e8eef2',\n textPrimary: '#323130',\n textSecondary: '#605e5c',\n border: '#c8d4dc',\n inputBackground: '#ffffff',\n inputBorder: '#004578',\n },\n },\n {\n id: 'dune',\n name: 'Dune',\n colors: {\n primary: '#7a6855',\n primaryDark: '#5c4f3f',\n headerBackground: '#7a6855',\n sectionBackground: '#f5f3f0',\n canvasBackground: '#e8e4df',\n textPrimary: '#323130',\n textSecondary: '#605e5c',\n border: '#d6d0c8',\n inputBackground: '#ffffff',\n inputBorder: '#7a6855',\n },\n },\n {\n id: 'lavender',\n name: 'Lavender',\n colors: {\n primary: '#5c2d91',\n primaryDark: '#472270',\n headerBackground: '#5c2d91',\n sectionBackground: '#f9f5ff',\n canvasBackground: '#f5f0fa',\n textPrimary: '#323130',\n textSecondary: '#605e5c',\n border: '#e1d4f0',\n inputBackground: '#ffffff',\n inputBorder: '#5c2d91',\n },\n },\n {\n id: 'brown',\n name: 'Brown',\n colors: {\n primary: '#6d4c41',\n primaryDark: '#4e362e',\n headerBackground: '#6d4c41',\n sectionBackground: '#f5f0ed',\n canvasBackground: '#ebe5e1',\n textPrimary: '#323130',\n textSecondary: '#605e5c',\n border: '#d4ccc7',\n inputBackground: '#ffffff',\n inputBorder: '#6d4c41',\n },\n },\n];\n\n/** Default theme (Soft blue) */\nexport const DEFAULT_THEME = THEME_PRESETS[0];\n\n/** Standard color palette for the color picker (like Canvas app) */\nexport const STANDARD_COLORS = [\n '#ffffff', '#000000', '#1a1a1a', '#333333', '#4d4d4d',\n '#666666', '#808080', '#999999', '#b3b3b3', '#cccccc',\n '#a4262c', '#d83b01', '#ff8c00', '#ffb900', '#fff100',\n '#bad80a', '#107c10', '#00b294', '#0078d4', '#5c2d91',\n];\n\n/** Get theme by ID, falls back to default */\nexport function getThemeById(id: string): FormTheme {\n return THEME_PRESETS.find((t) => t.id === id) ?? DEFAULT_THEME;\n}\n\n/** Get theme colors for a form, applying custom background if set */\nexport function getResolvedThemeColors(\n themeSettings?: FormThemeSettings\n): FormThemeColors {\n const theme = getThemeById(themeSettings?.presetId ?? 'soft-blue');\n\n if (themeSettings?.customBackgroundColor) {\n return {\n ...theme.colors,\n canvasBackground: themeSettings.customBackgroundColor,\n };\n }\n\n return theme.colors;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { b as FormThemeSettings, a as FormThemeColors } from './theme-BfeZIxmZ.cjs';
3
+
4
+ /**
5
+ * Theme context provides resolved theme colors to runtime components.
6
+ *
7
+ * Lifted from apps/form-builder/src/contexts/ThemeContext.tsx in Phase 1a
8
+ * of the WYSIWYG-canvas refactor. Note the inversion: this provider takes
9
+ * `themeSettings` as a prop rather than reading the editor's Zustand store.
10
+ * The form-builder app supplies a thin wrapper that subscribes to its
11
+ * `useDesignerStore` selector and passes the value down — that keeps
12
+ * form-runtime free of editor-state dependencies and reusable by any host
13
+ * (designer canvas, preview, generated form code, the runtime.html entry).
14
+ */
15
+ declare const ThemeContext: React.Context<FormThemeColors>;
16
+ /** Hook to access the current form theme colors. */
17
+ declare function useFormTheme(): FormThemeColors;
18
+ interface FormThemeProviderProps {
19
+ /**
20
+ * Theme settings to resolve. Pass `form.settings.theme` from your form
21
+ * definition. When `undefined`, the resolver returns the DEFAULT_THEME
22
+ * colors — same fallback the form-builder editor relied on.
23
+ */
24
+ themeSettings: FormThemeSettings | undefined;
25
+ children: React.ReactNode;
26
+ }
27
+ /**
28
+ * Theme provider that resolves theme from caller-supplied settings.
29
+ */
30
+ declare const FormThemeProvider: React.FC<FormThemeProviderProps>;
31
+
32
+ export { FormThemeProvider, type FormThemeProviderProps, ThemeContext, useFormTheme };