@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
package/dist/v8.d.cts ADDED
@@ -0,0 +1,730 @@
1
+ import { x as ControlDefinition, z as ControlType, al as SubgridColumn, aq as TextFormat } from './control-DFOg_pc_.cjs';
2
+ import React from 'react';
3
+ import { k as GridColumnDefinition, m as GridCustomizerDefinition, w as NestedSidePanelSize, N as NestedDisplayConfig, f as FocusedViewConfig } from './gridCustomizer-mJO-kmQ4.cjs';
4
+ import { F as FormRuntimeCapabilities } from './runtime-capabilities-BdGDdu0d.cjs';
5
+ import './theme-BfeZIxmZ.cjs';
6
+
7
+ /**
8
+ * Common props every per-type control file accepts.
9
+ *
10
+ * The dispatcher (Phase 1 Task 7's `<FormRuntime>`) resolves a control's
11
+ * value once — pulling from the controlled prop, the bound record, or
12
+ * mock data — and hands the per-type component an `effectiveValue` /
13
+ * `displayValue` pair. Per-type files stay focused on rendering the
14
+ * field shell; label positioning, full-width wrapping, and dispatch all
15
+ * live in the wrapper.
16
+ *
17
+ * `interactive` replaces the form-builder editor's `designMode` boolean.
18
+ * When `false` the field is disabled and ignores input — the previous
19
+ * editor convention of `(designMode && !isInteractive)` collapses to a
20
+ * single explicit flag here, matching what a generated host (or the
21
+ * runtime.html entry) would pass.
22
+ */
23
+ interface ControlPartProps {
24
+ control: ControlDefinition;
25
+ /**
26
+ * Resolved value (controlled value wins; falls back to record-bound
27
+ * value; falls back to `undefined`). The dispatcher computes this so
28
+ * per-type files don't each repeat the precedence rule.
29
+ */
30
+ effectiveValue: unknown;
31
+ /** `String(effectiveValue ?? '')` — pre-computed for convenience. */
32
+ displayValue: string;
33
+ /** `true` when either `effectiveValue` was supplied or a record bound a value. */
34
+ hasValue: boolean;
35
+ /** `true` when the caller passed an explicit controlled value (vs. record-bound only). */
36
+ hasControlledValue: boolean;
37
+ /** When `false`, the field is disabled and ignores input. */
38
+ interactive: boolean;
39
+ /** Bubble user edits up to the caller. Per-type files normalize the FluentUI event signature. */
40
+ onChange?: (next: unknown) => void;
41
+ /** Forwarded from the dispatcher for components that emit click-handled UI (buttons, links). */
42
+ onButtonClick?: (action: unknown) => void;
43
+ }
44
+ /** Convenience helper: derive the v8 `disabled` flag from `interactive` + read-only. */
45
+ declare function isDisabled(control: ControlDefinition, interactive: boolean): boolean;
46
+
47
+ /**
48
+ * `spacer` control — empty vertical gap.
49
+ *
50
+ * Lifted from ControlRenderer.tsx case 'spacer'. The editor used
51
+ * `designMode` to draw a dashed outline that hints at the gap; the
52
+ * runtime keeps that affordance behind the dispatcher-owned
53
+ * `interactive=false` flag (design time → outline; live → transparent).
54
+ */
55
+ declare const SpacerControl: React.FC<ControlPartProps>;
56
+
57
+ declare const LabelControl: React.FC<ControlPartProps>;
58
+
59
+ /**
60
+ * `formlink` control — a link/button that opens another form or URL.
61
+ *
62
+ * Lifted from ControlRenderer.tsx case 'formlink'. Navigation modes
63
+ * (projectForm vs recordUrl) live on `control.properties`; the runtime
64
+ * stays neutral on the navigation handler — the dispatcher can supply
65
+ * an `onButtonClick(action)` callback to intercept project-form clicks
66
+ * via the editor's navigation store.
67
+ */
68
+ declare const FormLinkControl: React.FC<ControlPartProps>;
69
+
70
+ declare const UnknownControl: React.FC<ControlPartProps>;
71
+
72
+ /**
73
+ * `text` control — single-line text field with optional format
74
+ * (text/email/url/phone/password). Renders via `TextFieldWithFormat`
75
+ * which carries the action-button + password-toggle plumbing.
76
+ *
77
+ * Lifted from ControlRenderer.tsx case 'text'.
78
+ */
79
+ declare const TextControl: React.FC<ControlPartProps>;
80
+
81
+ /**
82
+ * `textarea` control — multi-line text field.
83
+ *
84
+ * Lifted from ControlRenderer.tsx line 1567 (case 'textarea'). The
85
+ * editor's branching on `designMode` collapses to the dispatcher-owned
86
+ * `interactive` prop; everything else is byte-identical.
87
+ *
88
+ * No store reads, no editor-specific sub-components — this is the
89
+ * cleanest of the 22 switch branches and serves as the proof-of-pattern
90
+ * for the rest. Follow-on extractions (text, number, date, dropdown, ...)
91
+ * share the same `ControlPartProps` shape and the same dispatcher hand-off.
92
+ */
93
+ declare const TextareaControl: React.FC<ControlPartProps>;
94
+
95
+ /**
96
+ * `number` / `decimal` / `currency` controls — share a SpinButton
97
+ * renderer with a per-type step (1 for integer `number`, 0.01 for
98
+ * decimal/currency).
99
+ *
100
+ * Lifted from ControlRenderer.tsx cases 'number'/'decimal'/'currency'.
101
+ */
102
+ declare const NumberControl: React.FC<ControlPartProps>;
103
+
104
+ /**
105
+ * `date` / `datetime` controls — Fluent UI DatePicker bound to a
106
+ * parsed Date value.
107
+ *
108
+ * Lifted from ControlRenderer.tsx cases 'date'/'datetime'.
109
+ */
110
+ declare const DateControl: React.FC<ControlPartProps>;
111
+
112
+ /**
113
+ * `checkbox` control. The dispatcher swaps the label position when
114
+ * `properties.boxSide === 'start'`; this leaf renders the box only.
115
+ *
116
+ * Lifted from ControlRenderer.tsx case 'checkbox'.
117
+ */
118
+ declare const CheckboxControl: React.FC<ControlPartProps>;
119
+
120
+ /**
121
+ * `toggle` control — Fluent UI v8 Toggle with configurable on/off labels.
122
+ *
123
+ * Lifted from ControlRenderer.tsx case 'toggle'.
124
+ */
125
+ declare const ToggleControl: React.FC<ControlPartProps>;
126
+
127
+ /**
128
+ * `slider` control — Fluent UI v8 Slider.
129
+ *
130
+ * Lifted from ControlRenderer.tsx case 'slider'. The legacy editor
131
+ * branch didn't wire `value` / `onChange` (designer-only preview), but
132
+ * the dispatcher now passes them through so generated runtimes get a
133
+ * controlled slider.
134
+ */
135
+ declare const SliderControl: React.FC<ControlPartProps>;
136
+
137
+ /**
138
+ * `rating` control — Fluent UI Rating (stars) or `EmojiRating`
139
+ * (icon-based).
140
+ *
141
+ * Lifted from ControlRenderer.tsx case 'rating'.
142
+ */
143
+ declare const RatingControl: React.FC<ControlPartProps>;
144
+
145
+ /**
146
+ * `spinbutton` control — Fluent UI SpinButton with min/max/step/precision.
147
+ *
148
+ * Lifted from ControlRenderer.tsx case 'spinbutton'.
149
+ */
150
+ declare const SpinButtonControl: React.FC<ControlPartProps>;
151
+
152
+ declare const DropdownControl: React.FC<ControlPartProps>;
153
+
154
+ declare const ComboBoxControl: React.FC<ControlPartProps>;
155
+
156
+ /**
157
+ * `choicegroup` control — radio-button group that supports custom or
158
+ * attribute-bound option-set sources. Layout (vertical/horizontal/
159
+ * icon-cards/image-cards) is forwarded to the runtime
160
+ * `ChoiceGroupControl` sub-component.
161
+ *
162
+ * Lifted from ControlRenderer.tsx case 'choicegroup'.
163
+ */
164
+ declare const ChoiceGroupBranch: React.FC<ControlPartProps>;
165
+
166
+ /**
167
+ * `lookup` control — dispatcher branch that wires the editor-controlled
168
+ * value/disabled/onChange triplet into the runtime `LookupControl`
169
+ * sub-component. Sub-component handles `searchLookup` + persona avatars
170
+ * itself via the runtime context.
171
+ *
172
+ * Lifted from ControlRenderer.tsx case 'lookup'.
173
+ */
174
+ declare const LookupBranch: React.FC<ControlPartProps>;
175
+
176
+ /**
177
+ * `webresource` control — dispatcher branch. The renderer pulls its own
178
+ * `connection`, `previewContext`, and `fetchWebResource` from the runtime
179
+ * context; there's nothing per-control to plumb. `interactive` is
180
+ * carried so the dispatcher can pass `designMode` for parity, even
181
+ * though the current renderer ignores it.
182
+ *
183
+ * Lifted from ControlRenderer.tsx case 'webresource'.
184
+ */
185
+ declare const WebResourceBranch: React.FC<ControlPartProps>;
186
+
187
+ /**
188
+ * Phase 1b — designer/preview placeholder for chart-category controls.
189
+ *
190
+ * Moved from apps/form-builder/src/components/form-designer/canvas/
191
+ * ChartRenderer.tsx in Phase 6.5b. The form-builder original is now a
192
+ * thin adapter that injects the `entry` prop from `controlMetadata` (the
193
+ * registry hasn't moved to form-runtime yet — pending follow-up).
194
+ *
195
+ * The form-builder designer is locked to Fluent UI v8 (per CLAUDE.md);
196
+ * real chart rendering belongs to the generated output. At authoring
197
+ * time we show a labelled card with the chart icon, title, and a short
198
+ * data-source summary so users can confirm the tile is configured
199
+ * correctly without us pulling in the full v8 chart library as a
200
+ * designer dependency.
201
+ *
202
+ * v9-only charts (funnel, scatter) carry an additional badge so the user
203
+ * understands they will only render in v9-export targets.
204
+ */
205
+
206
+ /**
207
+ * Minimal subset of `ControlRegistryEntry` that ChartRenderer reads.
208
+ * Decoupled here so form-runtime doesn't depend on the form-builder's
209
+ * `controlMetadata` registry. The caller (designer or runtime
210
+ * dispatcher) resolves the full entry from its own metadata source and
211
+ * passes the slice down.
212
+ */
213
+ interface ChartRendererEntry {
214
+ /** Display label shown in the card body and the aria-label fallback. */
215
+ label?: string;
216
+ /** v8 Fluent icon name (e.g. 'BarChartVertical'). */
217
+ icon?: string;
218
+ /** Marks the v9-only badge when true. */
219
+ requiresV9?: boolean;
220
+ }
221
+ interface ChartRendererProps {
222
+ control: ControlDefinition;
223
+ /**
224
+ * Optional lookup of data source id → display label. Caller (canvas or
225
+ * preview) reads from `form.settings.dataSources`. We don't import the
226
+ * form here to keep this component pure + testable.
227
+ */
228
+ dataSourceLabelById?: Record<string, string>;
229
+ /**
230
+ * Optional registry slice for the control's type (icon, label,
231
+ * v9-required flag). When omitted, ChartRenderer renders with
232
+ * defaults — defaults match the form-builder editor's behavior when
233
+ * `getControlEntry` returns undefined.
234
+ */
235
+ entry?: ChartRendererEntry;
236
+ }
237
+ declare const ChartRenderer: React.FC<ChartRendererProps>;
238
+ /** Test whether a control type belongs to the chart category. */
239
+ declare function isChartControlType(type: ControlType | string): boolean;
240
+
241
+ /**
242
+ * Chart-category controls — `barchart`, `linechart`, `areachart`,
243
+ * `piechart`, `donutchart`, `horizontalbarchart`, `gaugechart`,
244
+ * `sparkline`, `heatmapchart`, `kpicard`, `funnelchart`, `scatterchart`.
245
+ *
246
+ * The dispatcher routes all 12 chart types here. `dataSourceLabelById`
247
+ * and the registry-derived `entry` (icon/label/v9-required flag) flow
248
+ * in via optional editor-supplied props; the runtime renders sensible
249
+ * defaults when either is missing.
250
+ *
251
+ * Lifted from ControlRenderer.tsx cases 'barchart'…'scatterchart'.
252
+ */
253
+ interface ChartBranchProps extends ControlPartProps {
254
+ /**
255
+ * Optional editor-supplied lookup of data source id → display label.
256
+ * The canvas / preview reads from `form.settings.dataSources`.
257
+ */
258
+ dataSourceLabelById?: Record<string, string>;
259
+ /**
260
+ * Optional editor-supplied registry slice (icon, label, requiresV9)
261
+ * for this chart type. Forwarded as-is to `ChartRenderer`.
262
+ */
263
+ entry?: ChartRendererEntry;
264
+ }
265
+ declare const ChartBranch: React.FC<ChartBranchProps>;
266
+
267
+ declare const PersonaControl: React.FC<ControlPartProps>;
268
+
269
+ /**
270
+ * `button` control — variants: default, primary (legacy), compound,
271
+ * icon, action, command (CommandBar), split (with menu), toggle.
272
+ *
273
+ * Lifted from ControlRenderer.tsx case 'button'. Each sub-variant
274
+ * preserves its specific Fluent UI rendering. `onButtonClick(action)`
275
+ * routes click events to the dispatcher's action handler — when
276
+ * omitted (preview/no-op), clicks are inert. In design mode
277
+ * (`!interactive`) the button is force-disabled and a small variant
278
+ * badge renders in the top-right corner.
279
+ */
280
+ declare const ButtonControl: React.FC<ControlPartProps>;
281
+
282
+ /**
283
+ * `subgrid` control — standard mode renderer. The editor's branch
284
+ * additionally handles focused-view layouts, card-list views,
285
+ * grid-customizer integration, and mock-data fallbacks; those stay
286
+ * inline in `ControlRenderer.tsx` and migrate in a follow-up — the
287
+ * runtime focus here is the deployed-runtime path: a Fluent v8
288
+ * `DetailsList` rendered from records fetched via `fetchLiveData`.
289
+ *
290
+ * Lifted (partial) from ControlRenderer.tsx case 'subgrid'.
291
+ */
292
+ interface SubgridBranchProps extends ControlPartProps {
293
+ /**
294
+ * Optional pre-fetched records. When omitted, the runtime calls
295
+ * `useLiveData(control)` to source records from the surrounding
296
+ * `FormRuntimeContext`. The editor passes mock data via this prop
297
+ * during designer-time rendering.
298
+ */
299
+ records?: Record<string, unknown>[];
300
+ /**
301
+ * Optional column override. Falls back to
302
+ * `control.properties.columns` (the legacy inline definition).
303
+ */
304
+ columns?: SubgridColumn[];
305
+ }
306
+ declare const SubgridBranch: React.FC<SubgridBranchProps>;
307
+
308
+ declare const TimelineControl: React.FC<ControlPartProps>;
309
+
310
+ /**
311
+ * Enhanced TextField with format-specific features (email/url/phone/password).
312
+ *
313
+ * Moved from apps/form-builder/src/components/form-designer/canvas/
314
+ * TextFieldWithFormat.tsx in Phase 6.5b. The form-builder original is
315
+ * now a re-export shim. Per `feedback_v1_migrations`, this lives in the
316
+ * runtime so the form-builder's canvas path, the runtime's `text` control
317
+ * branch (extracted in 6.5f), and generated host code all consume the
318
+ * same implementation.
319
+ */
320
+
321
+ interface TextFieldWithFormatProps {
322
+ /** Text format type */
323
+ textFormat: TextFormat;
324
+ /** Placeholder text */
325
+ placeholder?: string;
326
+ /** Whether the field is disabled */
327
+ disabled?: boolean;
328
+ /** Current value */
329
+ value?: string;
330
+ /** Max character length */
331
+ maxLength?: number;
332
+ /** Change handler */
333
+ onChange?: (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => void;
334
+ /** Show action button for email/url/phone */
335
+ showActionButton?: boolean;
336
+ /** Allow password visibility toggle */
337
+ allowPasswordToggle?: boolean;
338
+ /** Icon name to show as prefix */
339
+ iconName?: string;
340
+ }
341
+ declare const TextFieldWithFormat: React.FC<TextFieldWithFormatProps>;
342
+
343
+ /**
344
+ * EmojiRating — sentiment-style rating using emoji icons.
345
+ *
346
+ * Extracted from the inline `EmojiRating` in
347
+ * apps/form-builder/src/components/form-designer/canvas/ControlRenderer.tsx
348
+ * in Phase 6.5b. The rating-control branch (extracted in 6.5f) will
349
+ * delegate to this implementation; the form-builder ControlRenderer
350
+ * imports it from here in the meantime.
351
+ *
352
+ * Stateless except for local hover/selection — no store reads, no
353
+ * editor-specific behavior. Safe to render in any host.
354
+ */
355
+
356
+ interface EmojiRatingProps {
357
+ /** Number of emoji buckets (2–5). Values outside the range clamp. */
358
+ max: number;
359
+ /** Icon size (small/medium/large). */
360
+ size: string;
361
+ /** When true, emoji uses the per-bucket sentiment color (red→green). */
362
+ useColor: boolean;
363
+ /** Override color for ALL buckets (takes precedence over the sentiment palette). */
364
+ customEmojiColor: string;
365
+ /** When true, the rating ignores clicks and renders muted. */
366
+ disabled: boolean;
367
+ }
368
+ declare const EmojiRating: React.FC<EmojiRatingProps>;
369
+
370
+ /**
371
+ * ChoiceGroupControl — three-layout radio group (standard / icon-cards /
372
+ * image-cards) with optional per-option colors and labels.
373
+ *
374
+ * Extracted from the inline `ChoiceGroupControl` in
375
+ * apps/form-builder/src/components/form-designer/canvas/ControlRenderer.tsx
376
+ * in Phase 6.5b. The `choicegroup` control branch (extracted in 6.5f)
377
+ * delegates to this implementation.
378
+ *
379
+ * Pure: no store reads, no editor-specific behavior. Safe in any host.
380
+ */
381
+
382
+ interface ChoiceGroupControlProps {
383
+ options: Array<{
384
+ key: number;
385
+ text: string;
386
+ color?: string;
387
+ icon?: string;
388
+ imageSrc?: string;
389
+ }>;
390
+ showColors: boolean;
391
+ showLabels: boolean;
392
+ layout: string;
393
+ disabled: boolean;
394
+ initialSelectedKey?: string;
395
+ onChange?: (value: string | number | boolean | Date | null) => void;
396
+ }
397
+ declare const ChoiceGroupControl: React.FC<ChoiceGroupControlProps>;
398
+
399
+ /**
400
+ * Grid Cell Renderers
401
+ *
402
+ * Shared cell renderer functions for grid customizer preview.
403
+ * Used by GridPreview (grid customizer mode) and ControlRenderer (form canvas subgrids).
404
+ * All renderers use Fluent UI v8.
405
+ *
406
+ * Moved from apps/form-builder/src/utils/gridCellRenderers.tsx in Phase 6.5c.
407
+ * The form-builder file is now a thin re-export shim.
408
+ */
409
+
410
+ /**
411
+ * Render a cell value using the grid customizer column definition's renderer type and config.
412
+ * @param rowData Optional full row data — used by composite renderer for cross-field slot bindings.
413
+ */
414
+ declare function renderGridCell(value: unknown, colDef: GridColumnDefinition, rowData?: Record<string, unknown>): React.ReactNode;
415
+ /**
416
+ * Signature for a function that generates mock grid rows from a set of
417
+ * grid columns. The runtime components don't compute mock data themselves
418
+ * — callers in the editor inject this so the runtime stays free of any
419
+ * editor-only dependencies (e.g. `@dataverse-kit/export-engine`). When
420
+ * the prop is omitted, the runtime renders zero rows.
421
+ */
422
+ type GridMockDataGenerator = (columns: GridColumnDefinition[], rowCount: number) => Record<string, unknown>[];
423
+
424
+ /**
425
+ * NestedRecordsSidePanel
426
+ *
427
+ * Side-panel host for a nested grid's child records. Used when a parent grid's
428
+ * `nestedDisplay.mode` is `'side-panel'` — the parent surface (focused-view
429
+ * detail pane, card-list card, or any explicit "View related" trigger) opens
430
+ * this panel with the selected parent row's children.
431
+ *
432
+ * Renders the child grid as a Fluent UI v8 DetailsList using mock data sized
433
+ * to the configured page. The export generators emit a near-identical Panel
434
+ * + DetailsList runtime so the designer preview matches the deployed UX.
435
+ *
436
+ * Moved from apps/form-builder/src/components/grid-customizer/preview/ in
437
+ * Phase 6.5c. The mock-data generator is injected via the optional
438
+ * `generateMockData` prop rather than imported from
439
+ * `@dataverse-kit/export-engine` — keeps the runtime independent of the
440
+ * editor-only export-engine package. When the prop is omitted (e.g. in a
441
+ * deployed runtime), the panel renders zero rows.
442
+ */
443
+
444
+ interface NestedRecordsSidePanelProps {
445
+ /** Whether the panel is open. */
446
+ isOpen: boolean;
447
+ /** Close handler. */
448
+ onDismiss: () => void;
449
+ /** The child grid definition whose rows should render in the panel. */
450
+ childGridDef: GridCustomizerDefinition | null;
451
+ /**
452
+ * Display name of the parent row (e.g. "Acme Corp"). Surfaced in the panel
453
+ * header so the user knows which parent these children belong to.
454
+ */
455
+ parentLabel?: string;
456
+ /** Panel size. Defaults to 'medium'. */
457
+ panelSize?: NestedSidePanelSize;
458
+ /**
459
+ * Optional override for how many child rows to render. Falls back to the
460
+ * child grid's `pageSize` so the side-panel preview matches the embedded
461
+ * grid by default.
462
+ */
463
+ rowCount?: number;
464
+ /**
465
+ * Optional mock-data generator. When provided (typically by the editor's
466
+ * shim wrapper), the panel renders a mocked DetailsList for preview. When
467
+ * omitted, the panel renders zero rows.
468
+ */
469
+ generateMockData?: GridMockDataGenerator;
470
+ }
471
+ declare const NestedRecordsSidePanel: React.FC<NestedRecordsSidePanelProps>;
472
+
473
+ /**
474
+ * NestedRecordsCallout
475
+ *
476
+ * Hover-triggered compact preview of a nested grid's child records. Used when
477
+ * a parent grid's `nestedDisplay.mode` is `'hover-callout'`. Pairs with
478
+ * `NestedRecordsSidePanel` — the callout footer escalates to the full panel.
479
+ *
480
+ * Pattern mirrors `GridCellCallout.tsx` (LookupPreviewCallout): hover delay,
481
+ * `Callout` with `DirectionalHint`, fixed width, light dismiss.
482
+ *
483
+ * Moved from apps/form-builder/src/components/grid-customizer/preview/ in
484
+ * Phase 6.5c. The mock-data generator is injected via the optional
485
+ * `generateMockData` prop rather than imported from
486
+ * `@dataverse-kit/export-engine`.
487
+ */
488
+
489
+ interface NestedRecordsCalloutProps {
490
+ /** The child grid definition whose rows should preview. */
491
+ childGridDef: GridCustomizerDefinition | null;
492
+ /** Hover delay in ms before showing. Defaults to 300. */
493
+ hoverDelay?: number;
494
+ /** Max child rows to show. Defaults to 5. */
495
+ maxRows?: number;
496
+ /**
497
+ * Click escalation handler — when present, the callout footer renders a
498
+ * "View all N →" link that opens the full side panel.
499
+ */
500
+ onViewAll?: () => void;
501
+ /** The trigger element (badge / button / icon) that owns the hover surface. */
502
+ children: React.ReactElement;
503
+ /**
504
+ * Optional mock-data generator. When omitted, the callout shows the
505
+ * "No related records to preview." empty state.
506
+ */
507
+ generateMockData?: GridMockDataGenerator;
508
+ }
509
+ declare const NestedRecordsCallout: React.FC<NestedRecordsCalloutProps>;
510
+
511
+ /**
512
+ * NestedRecordsTrigger
513
+ *
514
+ * Renders the "view related records" affordance for a parent row when the
515
+ * parent grid type can't show inline children (focused-view, card-list).
516
+ * Switches on `nestedDisplay.mode`:
517
+ * - side-panel → DefaultButton that toggles NestedRecordsSidePanel
518
+ * - hover-callout → small badge wrapped in NestedRecordsCallout (with
519
+ * "View all" escalation that opens the side panel)
520
+ * - detail-pane → renders a compact inline child grid below the parent
521
+ *
522
+ * Designed to be dropped into a focused-view card or a card-list card without
523
+ * affecting layout — wraps itself in a div with margin-top so callers can stay
524
+ * unaware of the trigger's exact shape.
525
+ *
526
+ * Moved from apps/form-builder/src/components/grid-customizer/preview/ in
527
+ * Phase 6.5c. The mock-data generator is injected via the optional
528
+ * `generateMockData` prop rather than imported from
529
+ * `@dataverse-kit/export-engine`.
530
+ */
531
+
532
+ interface NestedRecordsTriggerProps {
533
+ /** The child grid definition. */
534
+ childGridDef: GridCustomizerDefinition | null;
535
+ /** Display config from the parent grid. */
536
+ config: NestedDisplayConfig;
537
+ /** Parent record label surfaced in the side panel header. */
538
+ parentLabel?: string;
539
+ /**
540
+ * Number of related records to advertise in the trigger label and to render
541
+ * in mock previews. Falls back to the child grid's pageSize when unset.
542
+ */
543
+ childCount?: number;
544
+ /**
545
+ * When true, the component does not auto-mount any panel/callout — used by
546
+ * the focused-view mode that wants to control its own detail-pane container.
547
+ * Currently unused but reserved for future composition.
548
+ */
549
+ inlineOnly?: boolean;
550
+ /**
551
+ * Optional mock-data generator forwarded to the sub-components
552
+ * (NestedRecordsSidePanel, NestedRecordsCallout, NestedDetailPaneList).
553
+ * When omitted, all child surfaces render zero rows.
554
+ */
555
+ generateMockData?: GridMockDataGenerator;
556
+ }
557
+ declare const NestedRecordsTrigger: React.FC<NestedRecordsTriggerProps>;
558
+
559
+ /**
560
+ * FocusedViewMasterDetailPreview
561
+ *
562
+ * Designer-side preview for `gridType: 'focused-view'` with a configured
563
+ * nested grid. Mirrors the runtime layout the form-code generator emits:
564
+ * left rail of persona cards (the focused list of parent records) + right
565
+ * pane that hosts the child grid for the currently selected parent.
566
+ *
567
+ * Replaces the "left rail + per-card View N related button" preview so
568
+ * what users see in the designer matches the export.
569
+ *
570
+ * Moved from apps/form-builder/src/components/grid-customizer/preview/ in
571
+ * Phase 6.5c. The mock-data generator is injected via the optional
572
+ * `generateMockData` prop rather than imported from
573
+ * `@dataverse-kit/export-engine`.
574
+ */
575
+
576
+ interface FocusedCardRow {
577
+ primaryValue: string;
578
+ secondaryValue?: string;
579
+ iconName?: string;
580
+ isFirst: boolean;
581
+ }
582
+ interface FocusedCardData {
583
+ id: string;
584
+ rows: FocusedCardRow[];
585
+ }
586
+ interface FocusedViewMasterDetailPreviewProps {
587
+ /** Parent records rendered in the left rail. */
588
+ cards: FocusedCardData[];
589
+ /** Field configuration for the cards (used to resolve labels per row). */
590
+ focusedViewConfig: FocusedViewConfig;
591
+ /** Header text — typically the parent entity name. */
592
+ entityName: string;
593
+ /** Whether to render the "Related" pill next to the header. */
594
+ showRelatedRecords?: boolean;
595
+ /** Whether to hide the search box (controlled by the subgrid's `hideSearchBox`). */
596
+ hideSearchBox?: boolean;
597
+ /** Live-data loading state. */
598
+ liveLoading?: boolean;
599
+ /** The child grid configuration to render in the right pane. */
600
+ childGridDef: GridCustomizerDefinition;
601
+ /** Persona initials helper (matches existing focused-view rendering). */
602
+ getInitials: (name: string) => string;
603
+ /** Persona color helper (matches existing focused-view rendering). */
604
+ getPersonaColor: (name: string) => string;
605
+ /** Should the upcoming-activity row at the bottom of the rail render. */
606
+ showUpNextActivity?: boolean;
607
+ /**
608
+ * Optional mock-data generator. When provided (typically by the editor's
609
+ * shim wrapper), each card receives a stable mocked row set. When omitted,
610
+ * the right pane renders zero rows.
611
+ */
612
+ generateMockData?: GridMockDataGenerator;
613
+ }
614
+ declare const FocusedViewMasterDetailPreview: React.FC<FocusedViewMasterDetailPreviewProps>;
615
+
616
+ /**
617
+ * LookupControl — Dynamics 365-style lookup field.
618
+ *
619
+ * Moved from apps/form-builder/src/components/form-designer/canvas/
620
+ * LookupControl.tsx in Phase 6.5d.
621
+ *
622
+ * Decoupled from form-builder's Zustand stores by consuming
623
+ * `FormRuntimeCapabilities.searchLookup` from the runtime context. The
624
+ * editor's `EditorFormRuntimeProvider` translates Dataverse client calls
625
+ * to this shape; generated host code will provide its own adapter.
626
+ *
627
+ * Entity-specific knowledge (primary name attribute, secondary text
628
+ * field, person-entity set, entity icons) stays in this file — it's
629
+ * static data, not editor-specific.
630
+ *
631
+ * Avatar fetching (entityimage endpoint) and entity-set-name resolution
632
+ * sit outside the FormRuntimeCapabilities surface and are accepted as
633
+ * optional injected props. The editor shim wires both via the Dataverse
634
+ * client + metadata cache; deployed runtime callers may omit them.
635
+ *
636
+ * Features:
637
+ * - Search icon on the right that triggers search on click
638
+ * - Selected value shows persona icon, linked text, and X to clear
639
+ * - Type-to-search with debouncing
640
+ * - Dropdown with "+ New" and "Advanced" options
641
+ * - Respects lookupViewId and lookupFetchXml configuration
642
+ */
643
+
644
+ type LookupSearchCapability = FormRuntimeCapabilities['searchLookup'];
645
+ interface LookupControlProps {
646
+ control: ControlDefinition;
647
+ disabled?: boolean;
648
+ value?: string;
649
+ onChange?: (value: string) => void;
650
+ /**
651
+ * Optional override for the runtime context's `searchLookup`. When
652
+ * omitted, the component reads from `useOptionalFormRuntimeContext()`.
653
+ * When neither path supplies it, the "not connected" fallback renders.
654
+ */
655
+ searchLookup?: LookupSearchCapability;
656
+ /**
657
+ * Optional override for the runtime context's connection state.
658
+ * Drives the "not connected" branch. When omitted, reads from
659
+ * `useOptionalFormRuntimeContext()`.
660
+ */
661
+ isConnectedOverride?: boolean;
662
+ /**
663
+ * Optional avatar fetcher used for person-entity lookups. When
664
+ * omitted, person personas render with initials only.
665
+ */
666
+ fetchEntityImage?: (recordId: string) => Promise<string | null>;
667
+ /**
668
+ * Optional entity logical name → plural set name resolver. Defaults
669
+ * to appending 's'. The editor adapter wires this to the metadata
670
+ * cache so virtual entities and irregular plurals resolve correctly.
671
+ */
672
+ resolveEntitySetName?: (entityLogicalName: string) => string;
673
+ }
674
+ declare function getPrimaryNameAttribute(entityLogicalName: string): string;
675
+ declare function getInitials(name: string): string;
676
+ declare function getEntityIcon(entityLogicalName: string): string;
677
+ declare function isPersonEntity(entityLogicalName: string | null): boolean;
678
+ declare function getSecondaryTextField(entityLogicalName: string): string | null;
679
+ declare const LookupControl: React.FC<LookupControlProps>;
680
+ declare const lookupEntityHelpers: {
681
+ getPrimaryNameAttribute: typeof getPrimaryNameAttribute;
682
+ getSecondaryTextField: typeof getSecondaryTextField;
683
+ isPersonEntity: typeof isPersonEntity;
684
+ getEntityIcon: typeof getEntityIcon;
685
+ getInitials: typeof getInitials;
686
+ };
687
+
688
+ /**
689
+ * WebResourceRenderer — preview surface for Dynamics web-resource controls.
690
+ *
691
+ * Moved from apps/form-builder/src/components/form-designer/canvas/
692
+ * ControlRenderer.tsx in Phase 6.5e. The component now reads
693
+ * `connection`, `previewContext`, and `fetchWebResource` from
694
+ * `useOptionalFormRuntimeContext()` so the editor's
695
+ * `useWebResourceContent` hook can be retired (Decision C in the Task
696
+ * 6.5 sub-plan).
697
+ *
698
+ * Behaviour preserved:
699
+ * - HTML web resources render via URL into a sandboxed iframe.
700
+ * - Image (PNG/JPG/GIF/ICO/SVG) and code (CSS/JS/XML/XSL/RESX) types
701
+ * render the fetched content directly.
702
+ * - "Not connected" / "no resource configured" / "loading" / "error"
703
+ * states map to the same placeholders the editor surfaced.
704
+ *
705
+ * The embedded-entity-browser special case (`/embedded/entity-browser/
706
+ * index.html` + WR_INIT postMessage) is editor-specific and stays in
707
+ * the form-builder shim — see
708
+ * `apps/form-builder/src/components/form-designer/canvas/
709
+ * WebResourceRenderer.tsx`. The runtime version is the same shape
710
+ * generated host code will eventually mount.
711
+ */
712
+
713
+ interface WebResourceRendererProps {
714
+ control: ControlDefinition;
715
+ /**
716
+ * Designer / preview flag. Carried for parity with the legacy editor
717
+ * component — not currently used but reserved for future read-only
718
+ * overlays at design time.
719
+ */
720
+ designMode?: boolean;
721
+ }
722
+ declare const WebResourceRenderer: React.FC<WebResourceRendererProps>;
723
+
724
+ /**
725
+ * Check if a web resource name matches embedded entity browser patterns.
726
+ * Matches `kh_/entitybrowser`, `kh_entitybrowser`, `entitybrowser`, etc.
727
+ */
728
+ declare function isEmbeddedEntityBrowser(webResourceName: string): boolean;
729
+
730
+ export { ButtonControl, ChartBranch, type ChartBranchProps, ChartRenderer, type ChartRendererEntry, type ChartRendererProps, CheckboxControl, ChoiceGroupBranch, ChoiceGroupControl, type ChoiceGroupControlProps, ComboBoxControl, type ControlPartProps, DateControl, DropdownControl, EmojiRating, type EmojiRatingProps, type FocusedCardData, type FocusedCardRow, FocusedViewMasterDetailPreview, type FocusedViewMasterDetailPreviewProps, FormLinkControl, type GridMockDataGenerator, LabelControl, LookupBranch, LookupControl, type LookupControlProps, type LookupSearchCapability, NestedRecordsCallout, type NestedRecordsCalloutProps, NestedRecordsSidePanel, type NestedRecordsSidePanelProps, NestedRecordsTrigger, type NestedRecordsTriggerProps, NumberControl, PersonaControl, RatingControl, SliderControl, SpacerControl, SpinButtonControl, SubgridBranch, type SubgridBranchProps, TextControl, TextFieldWithFormat, type TextFieldWithFormatProps, TextareaControl, TimelineControl, ToggleControl, UnknownControl, WebResourceBranch, WebResourceRenderer, type WebResourceRendererProps, isChartControlType, isDisabled, isEmbeddedEntityBrowser, lookupEntityHelpers, renderGridCell };