@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 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/v8/controls/types.ts","../src/v8/controls/spacer.tsx","../src/v8/controls/label.tsx","../src/v8/controls/formlink.tsx","../src/v8/controls/unknown.tsx","../src/v8/controls/internals/TextFieldWithFormat.tsx","../src/v8/controls/text.tsx","../src/v8/controls/textarea.tsx","../src/v8/controls/number.tsx","../src/v8/controls/date.tsx","../src/v8/controls/checkbox.tsx","../src/v8/controls/toggle.tsx","../src/v8/controls/slider.tsx","../src/v8/controls/rating.tsx","../src/v8/controls/internals/EmojiRating.tsx","../src/v8/controls/spinbutton.tsx","../src/v8/controls/dropdown.tsx","../src/v8/controls/combobox.tsx","../src/v8/controls/internals/ChoiceGroupControl.tsx","../src/v8/controls/choicegroup.tsx","../src/v8/controls/internals/LookupControl.tsx","../src/context/FormRuntimeContext.tsx","../src/v8/controls/lookup.tsx","../src/v8/controls/internals/WebResourceRenderer.tsx","../src/v8/controls/webresource.tsx","../src/v8/controls/internals/ChartRenderer.tsx","../src/v8/controls/chart.tsx","../src/v8/controls/persona.tsx","../src/v8/shared/helpers.ts","../src/v8/controls/button.tsx","../src/v8/controls/subgrid.tsx","../src/hooks.ts","../src/v8/controls/timeline.tsx","../src/v8/controls/internals/NestedRecordsSidePanel.tsx","../src/v8/shared/gridCellRenderers.tsx","../src/v8/controls/internals/NestedRecordsCallout.tsx","../src/v8/controls/internals/NestedRecordsTrigger.tsx","../src/v8/controls/internals/FocusedViewMasterDetailPreview.tsx","../src/FormRuntime.tsx","../src/shell/HeaderShell.tsx","../src/v8/controls/dispatcher.tsx","../src/instrumentation.ts","../src/shell/CommandBarShell.tsx","../src/shell/BpfShell.tsx","../src/shell/TabsShell.tsx","../src/types/form.ts","../src/types/theme.ts","../src/shell/SectionShell.tsx","../src/utils/backgroundUtils.ts","../src/shell/CalloutAnchor.tsx","../src/shell/CalloutShell.tsx","../src/context/CalloutsContext.tsx","../src/context/RuleStatesContext.tsx","../src/context/TabContentSlotsContext.tsx","../src/utils/gridLayoutUtils.ts","../src/shell/GridShell.tsx","../src/shell/FooterShell.tsx"],"sourcesContent":["// @dataverse-kit/form-runtime — v8 default entry.\n//\n// Renders Dynamics 365 forms using Fluent UI v8. Mounted by the form-builder\n// designer canvas (with overlay chrome), preview, and generated host code so\n// all three paths render from the same React tree.\n//\n// Sibling entries:\n// - ./v9 — Fluent UI v9 variant (canvas always mounts v8; generators\n// emit v9 imports for v9-target projects)\n// - ./hooks — FluentUI-agnostic hooks (useSubgridData, useChartData, ...)\n// - ./utils — gridLayoutUtils and helpers shared with the generator\n// - ./theme — FormThemeContext (FormThemeProvider + useFormTheme)\n//\n// All consumed `@dataverse-kit/runtime` and `@dataverse-kit/api-service`\n// imports flow through DIRECTLY — no re-exports, no wrappers. Per the\n// dynamics-toolkit v1.0 migration preference (full eradication of\n// duplicated logic).\n\n// v8 surface: per-type controls + their internals + the shared types.\n// Re-exported here so the default entry is the v8 surface — the v9\n// sibling (Phase 4) gets its own `./v9` entrypoint.\nexport * from './v8';\n\n// Public mount point — Phase 1 Task 7.\nexport { FormRuntime, type FormRuntimeProps } from './FormRuntime';\n\n// Context layer — re-exported from the default entry so consumers\n// don't need to reach for `/context`. `<FormRuntime>` requires a\n// surrounding `<FormRuntimeProvider>` that supplies the async\n// capabilities (fetchLiveData / fetchWebResource / searchLookup).\nexport {\n FormRuntimeProvider,\n useFormRuntimeContext,\n useOptionalFormRuntimeContext,\n type FormRuntimeProviderProps,\n} from './context/FormRuntimeContext';\n\n// Callouts context — FormRuntime auto-wraps with the form's\n// `callouts` array; lifted to the public surface so hosts can wrap\n// custom mounts of subordinate shells (CalloutShell, SectionShell)\n// without remounting the whole runtime.\nexport {\n CalloutsProvider,\n useCallout,\n type CalloutsProviderProps,\n} from './context/CalloutsContext';\n\n// Rule-states context — host (form-builder or generated app) feeds\n// the runtime pre-computed business-rule outputs. FormRuntime auto-\n// wraps with its `ruleStates` prop; this re-export lets hosts read\n// the same maps from custom shells.\nexport {\n RuleStatesProvider,\n useRuleStates,\n useFieldState,\n useSectionState,\n useTabState,\n type RuleStatesProviderProps,\n type RuleStatesContextValue,\n} from './context/RuleStatesContext';\n\n// Tab-content slot context — non-main tabs (related-records, audit-\n// history) need host-side data fetchers; the runtime ships a\n// placeholder by default. Hosts wrap with TabContentSlotsProvider to\n// plug in render functions.\nexport {\n TabContentSlotsProvider,\n useTabContentSlots,\n type TabContentSlots,\n type TabContentSlotsProviderProps,\n} from './context/TabContentSlotsContext';\n\n// `useLiveData` — public so generated host code can mirror the\n// loading/error state machine inside its own widgets.\nexport { useLiveData, type UseLiveDataResult } from './hooks';\n\n// Dispatcher helpers — exposed so generators (Phase 3) + tests can\n// drive the resolver directly without re-implementing the registry.\nexport {\n DispatchedControl,\n buildControlPartProps,\n resolveControlComponent,\n type DispatchControlInputs,\n} from './v8/controls/dispatcher';\n\n// Shell pieces — composable at a finer granularity than `<FormRuntime>`.\nexport { HeaderShell, type HeaderShellProps } from './shell/HeaderShell';\nexport { CommandBarShell, type CommandBarShellProps } from './shell/CommandBarShell';\nexport { BpfShell, type BpfShellProps } from './shell/BpfShell';\nexport { TabsShell, type TabsShellProps } from './shell/TabsShell';\nexport { GridShell, type GridShellProps } from './shell/GridShell';\nexport { SectionShell, type SectionShellProps } from './shell/SectionShell';\nexport { FooterShell, type FooterShellProps } from './shell/FooterShell';\nexport { CalloutShell, type CalloutShellProps, mapCalloutDirectionalHint } from './shell/CalloutShell';\nexport { CalloutAnchor, type CalloutAnchorProps } from './shell/CalloutAnchor';\n\n// Instrumentation helpers — Phase 2 overlay reads these to address\n// elements; Phase 3 generated host code emits the attrs at build time.\nexport {\n instrumentAttrs,\n paths as instrumentationPaths,\n type InstrumentationMode,\n type ElementType,\n type InstrumentationAttrs,\n} from './instrumentation';\n","import type { ControlDefinition } from '../../types';\n\n/**\n * Common props every per-type control file accepts.\n *\n * The dispatcher (Phase 1 Task 7's `<FormRuntime>`) resolves a control's\n * value once — pulling from the controlled prop, the bound record, or\n * mock data — and hands the per-type component an `effectiveValue` /\n * `displayValue` pair. Per-type files stay focused on rendering the\n * field shell; label positioning, full-width wrapping, and dispatch all\n * live in the wrapper.\n *\n * `interactive` replaces the form-builder editor's `designMode` boolean.\n * When `false` the field is disabled and ignores input — the previous\n * editor convention of `(designMode && !isInteractive)` collapses to a\n * single explicit flag here, matching what a generated host (or the\n * runtime.html entry) would pass.\n */\nexport interface ControlPartProps {\n control: ControlDefinition;\n /**\n * Resolved value (controlled value wins; falls back to record-bound\n * value; falls back to `undefined`). The dispatcher computes this so\n * per-type files don't each repeat the precedence rule.\n */\n effectiveValue: unknown;\n /** `String(effectiveValue ?? '')` — pre-computed for convenience. */\n displayValue: string;\n /** `true` when either `effectiveValue` was supplied or a record bound a value. */\n hasValue: boolean;\n /** `true` when the caller passed an explicit controlled value (vs. record-bound only). */\n hasControlledValue: boolean;\n /** When `false`, the field is disabled and ignores input. */\n interactive: boolean;\n /** Bubble user edits up to the caller. Per-type files normalize the FluentUI event signature. */\n onChange?: (next: unknown) => void;\n /** Forwarded from the dispatcher for components that emit click-handled UI (buttons, links). */\n onButtonClick?: (action: unknown) => void;\n}\n\n/** Convenience helper: derive the v8 `disabled` flag from `interactive` + read-only. */\nexport function isDisabled(control: ControlDefinition, interactive: boolean): boolean {\n return !interactive || control.readOnly === true;\n}\n","import React from 'react';\nimport type { ControlPartProps } from './types';\n\n/**\n * `spacer` control — empty vertical gap.\n *\n * Lifted from ControlRenderer.tsx case 'spacer'. The editor used\n * `designMode` to draw a dashed outline that hints at the gap; the\n * runtime keeps that affordance behind the dispatcher-owned\n * `interactive=false` flag (design time → outline; live → transparent).\n */\nexport const SpacerControl: React.FC<ControlPartProps> = ({ control, interactive }) => {\n const designOutline = !interactive;\n return (\n <div\n style={{\n height: (control.properties.height as number) ?? 16,\n backgroundColor: designOutline ? '#f3f2f1' : 'transparent',\n border: designOutline ? '1px dashed #c8c6c4' : 'none',\n borderRadius: 2,\n }}\n />\n );\n};\n","import React from 'react';\nimport DOMPurify, { type Config as PurifyConfig } from 'dompurify';\nimport type { ControlPartProps } from './types';\n\n/**\n * `label` control — static text snippet with optional HTML body.\n *\n * Lifted from ControlRenderer.tsx case 'label'. The dashed-outline\n * empty-state affordance is gated on the dispatcher's `interactive`\n * flag — `false` in the designer (matching legacy `designMode`), `true`\n * in deployed runtime where the empty state should remain hidden.\n *\n * **XSS:** When the label text contains HTML tags we render it via\n * `dangerouslySetInnerHTML` so users can compose rich labels (bold,\n * links, line breaks). DOMPurify strips active content (scripts, event\n * handlers, `javascript:` URIs) and we additionally forbid form-like\n * elements (phishing surface) and `target` attributes on anchors\n * (reverse-tabnabbing). Inputs without tags take the safe `children`\n * path with no sanitization invoked.\n */\n\n// Module-scope detection so we can fall back gracefully on the server.\n// DOMPurify requires `window.document`; under Node-without-jsdom it\n// returns a factory stub whose `sanitize` throws. Any SSR consumer\n// (Next.js, Astro, generated web-resource bundles statically rendered\n// for crawlers) needs the regex-strip fallback rather than a runtime\n// crash. The fallback is lossy (drops all formatting) but safe; the\n// \"rich label\" feature only matters in the browser anyway.\nconst IS_BROWSER = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst PURIFY_CONFIG: PurifyConfig = {\n // Block phishing-shaped elements. DOMPurify 3.x defaults permit\n // <form>, <input>, <button>, <select>, <textarea>, <option> — an\n // attacker-controlled label could render a fake login form\n // indistinguishable from the host app's chrome.\n FORBID_TAGS: ['form', 'input', 'button', 'select', 'textarea', 'option'],\n // Drop `target` outright. Reverse-tabnabbing (`target=\"_blank\"`\n // without `rel=\"noopener noreferrer\"`) is the cousin bypass to\n // `javascript:` URIs and DOMPurify doesn't auto-rel-noopener.\n // Labels have no legitimate need to escape the current frame.\n FORBID_ATTR: ['target'],\n};\n\nfunction sanitizeLabelHtml(text: string): string {\n if (!IS_BROWSER) {\n // Strip every tag-like sequence. Conservative: keep text content,\n // drop everything else. Mirrors what the browser path would\n // produce for a maximally hostile input.\n return text.replace(/<[^>]*>/g, '');\n }\n // DOMPurify.sanitize returns `string | TrustedHTML` in its type\n // overloads; the runtime value is always a string under our config\n // (default RETURN_TRUSTED_TYPE=false, no RETURN_DOM*). Coerce\n // explicitly so the call site stays string-typed.\n return String(DOMPurify.sanitize(text, PURIFY_CONFIG));\n}\n\nexport const LabelControl: React.FC<ControlPartProps> = ({ control, interactive }) => {\n // Coerce defensively. `control.properties.text` is typed `unknown`\n // upstream and may be a number, boolean, object, etc. A non-string\n // would slip past `as string` (a cast, not a runtime coercion) and\n // crash `.test()` / `.replace()` later.\n const text = String(control.properties.text ?? '');\n const variant = (control.properties.variant as string) ?? 'medium';\n const fontWeight = (control.properties.fontWeight as string) ?? 'normal';\n const color = (control.properties.color as string) ?? '#323130';\n const alignment = (control.properties.alignment as string) ?? 'left';\n\n const fontSizeMap: Record<string, number> = { small: 12, medium: 14, large: 16, xLarge: 20 };\n const fontSize = fontSizeMap[variant] ?? 14;\n\n const hasHtml = !!text && /<[^>]+>/.test(text);\n // Memoize so we don't re-sanitize on every parent re-render\n // (dirty-tracker, rule engine, BPF tick all cause cascading\n // re-renders of cell trees).\n const safeHtml = React.useMemo(() => (hasHtml ? sanitizeLabelHtml(text) : ''), [hasHtml, text]);\n\n // `isEmpty` decides whether to show the design-mode placeholder.\n // Compute from the post-sanitize result so a label that contained\n // only active content (e.g. `<script>x</script>`) — now empty after\n // sanitization — collapses to the placeholder instead of an empty\n // dangerouslySetInnerHTML div.\n const renderableHtml = hasHtml ? safeHtml.trim() : '';\n const strippedText = text ? text.replace(/<[^>]*>/g, '').trim() : '';\n const isEmpty = !strippedText && !renderableHtml;\n const designMode = !interactive;\n\n // Use the sanitized HTML branch only when there's something left\n // after the scrub. Otherwise fall through to the children path so\n // empty-after-scrub doesn't render an empty div.\n const useHtmlBranch = hasHtml && !!renderableHtml;\n\n // No `React.CSSProperties` annotation — the cross-package `csstype`\n // mismatch (see shared/gridCellRenderers note) means casting pins\n // the type to one package's csstype tree. Inline literal so each\n // consumer's tsc resolves it under its own `style` prop type.\n return (\n <div\n style={{\n fontSize,\n fontWeight: fontWeight as 'normal' | 'bold' | 'bolder' | 'lighter' | number,\n color,\n textAlign: alignment as 'left' | 'right' | 'center' | 'justify',\n padding: '4px 0',\n border: designMode && isEmpty ? '1px dashed #c8c6c4' : 'none',\n borderRadius: 2,\n minHeight: designMode ? 24 : 'auto',\n }}\n {...(useHtmlBranch\n ? { dangerouslySetInnerHTML: { __html: safeHtml } }\n : {\n // When `hasHtml` was true but sanitize emptied the string,\n // show the design-mode placeholder rather than the raw\n // pre-sanitize text — leaking literal `<script>...</script>`\n // chars into the label would be confusing.\n children: hasHtml\n ? designMode\n ? '(Enter label text)'\n : ''\n : text || (designMode ? '(Enter label text)' : ''),\n })}\n />\n );\n};\n","import React from 'react';\nimport { Icon, Link } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `formlink` control — a link/button that opens another form or URL.\n *\n * Lifted from ControlRenderer.tsx case 'formlink'. Navigation modes\n * (projectForm vs recordUrl) live on `control.properties`; the runtime\n * stays neutral on the navigation handler — the dispatcher can supply\n * an `onButtonClick(action)` callback to intercept project-form clicks\n * via the editor's navigation store.\n */\nexport const FormLinkControl: React.FC<ControlPartProps> = ({\n control,\n interactive,\n onButtonClick,\n}) => {\n const linkText = (control.properties.linkText as string) || 'Open form';\n const iconName = (control.properties.iconName as string) || 'OpenInNewWindow';\n const showIcon = (control.properties.showIcon as boolean) ?? true;\n const linkMode = (control.properties.linkMode as string) || 'projectForm';\n const openInNewTab = (control.properties.openInNewTab as boolean) ?? true;\n const recordUrl = (control.properties.recordUrl as string) || '';\n const disabled = isDisabled(control, interactive);\n\n return (\n <Link\n href={linkMode === 'recordUrl' && recordUrl ? recordUrl : undefined}\n target={openInNewTab ? '_blank' : undefined}\n disabled={disabled}\n onClick={onButtonClick ? () => onButtonClick({ control }) : undefined}\n styles={{ root: { display: 'inline-flex', alignItems: 'center', gap: 4 } }}\n >\n {showIcon && <Icon iconName={iconName} styles={{ root: { fontSize: 14 } }} />}\n {linkText}\n </Link>\n );\n};\n","import React from 'react';\nimport { TextField } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\nimport { TextFieldWithFormat } from './internals/TextFieldWithFormat';\nimport type { TextFormat } from '../../types';\n\n/**\n * Default-fallback control — renders an unknown control type as a plain\n * text input. Also handles the legacy `phone`/`email`/`url` control\n * types that were collapsed into `text` with `textFormat`: when the\n * dispatcher routes them here (they aren't in the canonical type union),\n * we infer the format from the type name and delegate to\n * `TextFieldWithFormat`.\n *\n * Lifted from ControlRenderer.tsx's default branch.\n */\nconst LEGACY_FORMAT_MAP: Record<string, TextFormat> = {\n phone: 'phone',\n email: 'email',\n url: 'url',\n};\n\nexport const UnknownControl: React.FC<ControlPartProps> = ({\n control,\n displayValue,\n hasValue,\n hasControlledValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n const inferredFormat = LEGACY_FORMAT_MAP[control.type as unknown as string] ?? 'text';\n const isLegacyTextType = inferredFormat !== 'text';\n\n if (isLegacyTextType) {\n const showPlaceholder = (control.properties.showPlaceholder as boolean) ?? false;\n const customPlaceholder = control.properties.placeholder as string | undefined;\n const placeholderMap: Record<TextFormat, string> = {\n text: control.label,\n email: 'email@example.com',\n url: 'https://example.com',\n phone: '+1 (555) 000-0000',\n password: '••••••••',\n };\n const placeholder = showPlaceholder\n ? customPlaceholder ?? placeholderMap[inferredFormat]\n : undefined;\n const iconMap: Record<TextFormat, string | undefined> = {\n text: undefined,\n email: 'Mail',\n url: 'Link',\n phone: 'Phone',\n password: 'Lock',\n };\n\n return (\n <TextFieldWithFormat\n textFormat={inferredFormat}\n placeholder={placeholder}\n disabled={disabled}\n value={hasControlledValue ? displayValue : hasValue ? displayValue : undefined}\n maxLength={control.properties.maxLength as number | undefined}\n onChange={onChange ? (_, newValue) => onChange(newValue ?? '') : undefined}\n showActionButton={(control.properties.showActionButton as boolean) ?? true}\n allowPasswordToggle\n iconName={iconMap[inferredFormat]}\n />\n );\n }\n\n return (\n <TextField\n placeholder={control.label}\n disabled={disabled}\n value={hasValue ? displayValue : undefined}\n onChange={onChange ? (_, newValue) => onChange(newValue ?? '') : undefined}\n />\n );\n};\n","/**\n * Enhanced TextField with format-specific features (email/url/phone/password).\n *\n * Moved from apps/form-builder/src/components/form-designer/canvas/\n * TextFieldWithFormat.tsx in Phase 6.5b. The form-builder original is\n * now a re-export shim. Per `feedback_v1_migrations`, this lives in the\n * runtime so the form-builder's canvas path, the runtime's `text` control\n * branch (extracted in 6.5f), and generated host code all consume the\n * same implementation.\n */\n\nimport React, { useState, useMemo } from 'react';\nimport { TextField, IconButton, mergeStyles, Icon } from '@fluentui/react';\nimport type { TextFormat } from '../../../types';\n\nexport interface TextFieldWithFormatProps {\n /** Text format type */\n textFormat: TextFormat;\n /** Placeholder text */\n placeholder?: string;\n /** Whether the field is disabled */\n disabled?: boolean;\n /** Current value */\n value?: string;\n /** Max character length */\n maxLength?: number;\n /** Change handler */\n onChange?: (\n event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,\n newValue?: string,\n ) => void;\n /** Show action button for email/url/phone */\n showActionButton?: boolean;\n /** Allow password visibility toggle */\n allowPasswordToggle?: boolean;\n /** Icon name to show as prefix */\n iconName?: string;\n}\n\nconst containerClass = mergeStyles({\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n width: '100%',\n});\n\nconst textFieldWrapperClass = mergeStyles({\n flex: 1,\n position: 'relative',\n});\n\nconst prefixIconContainerClass = mergeStyles({\n position: 'absolute',\n left: 8,\n top: '50%',\n transform: 'translateY(-50%)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n pointerEvents: 'none',\n zIndex: 1,\n});\n\nconst actionButtonClass = mergeStyles({\n flexShrink: 0,\n});\n\nfunction getInputType(format: TextFormat, showPassword: boolean): string {\n switch (format) {\n case 'email':\n return 'email';\n case 'url':\n return 'url';\n case 'phone':\n return 'tel';\n case 'password':\n return showPassword ? 'text' : 'password';\n default:\n return 'text';\n }\n}\n\nfunction getIconColor(format: TextFormat): string {\n switch (format) {\n case 'email':\n case 'url':\n return '#0078d4';\n case 'phone':\n return '#107c10';\n case 'password':\n default:\n return '#605e5c';\n }\n}\n\nfunction getActionConfig(\n format: TextFormat,\n value: string | undefined,\n): { iconName: string; title: string; href: string | null; ariaLabel: string } | null {\n if (!value) return null;\n switch (format) {\n case 'email':\n return {\n iconName: 'Mail',\n title: 'Send email',\n href: `mailto:${value}`,\n ariaLabel: 'Send email',\n };\n case 'url': {\n const urlWithProtocol =\n value.startsWith('http://') || value.startsWith('https://') ? value : `https://${value}`;\n return {\n iconName: 'OpenInNewWindow',\n title: 'Open link',\n href: urlWithProtocol,\n ariaLabel: 'Open link in new tab',\n };\n }\n case 'phone':\n return {\n iconName: 'Phone',\n title: 'Call',\n href: `tel:${value.replace(/[^\\d+]/g, '')}`,\n ariaLabel: 'Make phone call',\n };\n default:\n return null;\n }\n}\n\nexport const TextFieldWithFormat: React.FC<TextFieldWithFormatProps> = ({\n textFormat,\n placeholder,\n disabled = false,\n value,\n maxLength,\n onChange,\n showActionButton = false,\n allowPasswordToggle = true,\n iconName,\n}) => {\n const [showPassword, setShowPassword] = useState(false);\n\n const showIconPrefix = !!iconName && textFormat !== 'text';\n\n const inputType = useMemo(\n () => getInputType(textFormat, showPassword),\n [textFormat, showPassword],\n );\n\n const actionConfig = useMemo(\n () => (showActionButton ? getActionConfig(textFormat, value) : null),\n [showActionButton, textFormat, value],\n );\n\n const handleActionClick = () => {\n if (actionConfig?.href) {\n if (textFormat === 'url') {\n window.open(actionConfig.href, '_blank', 'noopener,noreferrer');\n } else {\n window.location.href = actionConfig.href;\n }\n }\n };\n\n const handlePasswordToggle = () => setShowPassword(!showPassword);\n\n const textFieldStyles = useMemo(\n () => ({\n root: { width: '100%' },\n fieldGroup: showIconPrefix ? { paddingLeft: 28 } : undefined,\n }),\n [showIconPrefix],\n );\n\n return (\n <div className={containerClass}>\n <div className={textFieldWrapperClass}>\n {showIconPrefix && (\n <div className={prefixIconContainerClass}>\n <Icon\n iconName={iconName}\n styles={{\n root: {\n fontSize: 14,\n color: disabled ? '#a19f9d' : getIconColor(textFormat),\n },\n }}\n />\n </div>\n )}\n <TextField\n type={inputType}\n placeholder={placeholder}\n disabled={disabled}\n value={value}\n maxLength={maxLength}\n onChange={onChange}\n styles={textFieldStyles}\n />\n </div>\n\n {textFormat === 'password' && allowPasswordToggle && (\n <IconButton\n iconProps={{ iconName: showPassword ? 'Hide' : 'View' }}\n title={showPassword ? 'Hide password' : 'Show password'}\n ariaLabel={showPassword ? 'Hide password' : 'Show password'}\n onClick={handlePasswordToggle}\n disabled={disabled}\n className={actionButtonClass}\n styles={{\n root: { height: 32, width: 32 },\n icon: { fontSize: 14, color: '#605e5c' },\n }}\n />\n )}\n\n {actionConfig && !disabled && (\n <IconButton\n iconProps={{ iconName: actionConfig.iconName }}\n title={actionConfig.title}\n ariaLabel={actionConfig.ariaLabel}\n onClick={handleActionClick}\n className={actionButtonClass}\n styles={{\n root: { height: 32, width: 32 },\n icon: { fontSize: 14, color: getIconColor(textFormat) },\n }}\n />\n )}\n </div>\n );\n};\n","import React from 'react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\nimport { TextFieldWithFormat } from './internals/TextFieldWithFormat';\nimport type { TextFormat } from '../../types';\n\n/**\n * `text` control — single-line text field with optional format\n * (text/email/url/phone/password). Renders via `TextFieldWithFormat`\n * which carries the action-button + password-toggle plumbing.\n *\n * Lifted from ControlRenderer.tsx case 'text'.\n */\nexport const TextControl: React.FC<ControlPartProps> = ({\n control,\n displayValue,\n hasValue,\n hasControlledValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n const textFormat = (control.properties.textFormat as TextFormat) ?? 'text';\n const showPlaceholder = (control.properties.showPlaceholder as boolean) ?? false;\n const customPlaceholder = control.properties.placeholder as string | undefined;\n const showActionButton = (control.properties.showActionButton as boolean) ?? false;\n const allowPasswordToggle = (control.properties.allowPasswordToggle as boolean) ?? true;\n\n const placeholderMap: Record<TextFormat, string> = {\n text: control.label,\n email: 'email@example.com',\n url: 'https://example.com',\n phone: '+1 (555) 000-0000',\n password: '••••••••',\n };\n const placeholder = showPlaceholder\n ? customPlaceholder ?? placeholderMap[textFormat]\n : undefined;\n\n const iconMap: Record<TextFormat, string | undefined> = {\n text: undefined,\n email: 'Mail',\n url: 'Link',\n phone: 'Phone',\n password: 'Lock',\n };\n\n return (\n <TextFieldWithFormat\n textFormat={textFormat}\n placeholder={placeholder}\n disabled={disabled}\n value={hasControlledValue ? displayValue : hasValue ? displayValue : undefined}\n maxLength={control.properties.maxLength as number | undefined}\n onChange={onChange ? (_, newValue) => onChange(newValue ?? '') : undefined}\n showActionButton={showActionButton}\n allowPasswordToggle={allowPasswordToggle}\n iconName={iconMap[textFormat]}\n />\n );\n};\n","import React from 'react';\nimport { TextField } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `textarea` control — multi-line text field.\n *\n * Lifted from ControlRenderer.tsx line 1567 (case 'textarea'). The\n * editor's branching on `designMode` collapses to the dispatcher-owned\n * `interactive` prop; everything else is byte-identical.\n *\n * No store reads, no editor-specific sub-components — this is the\n * cleanest of the 22 switch branches and serves as the proof-of-pattern\n * for the rest. Follow-on extractions (text, number, date, dropdown, ...)\n * share the same `ControlPartProps` shape and the same dispatcher hand-off.\n */\nexport const TextareaControl: React.FC<ControlPartProps> = ({\n control,\n displayValue,\n hasValue,\n hasControlledValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n return (\n <TextField\n multiline\n rows={(control.properties.rows as number) ?? 3}\n disabled={disabled}\n value={hasControlledValue ? displayValue : hasValue ? displayValue : undefined}\n defaultValue={hasControlledValue || hasValue ? undefined : ''}\n onChange={onChange ? (_, newValue) => onChange(newValue ?? '') : undefined}\n styles={\n control.properties.resizable === false ? { field: { resize: 'none' } } : undefined\n }\n />\n );\n};\n","import React from 'react';\nimport { SpinButton } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `number` / `decimal` / `currency` controls — share a SpinButton\n * renderer with a per-type step (1 for integer `number`, 0.01 for\n * decimal/currency).\n *\n * Lifted from ControlRenderer.tsx cases 'number'/'decimal'/'currency'.\n */\nexport const NumberControl: React.FC<ControlPartProps> = ({\n control,\n displayValue,\n hasValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n const step = control.type === 'number' ? 1 : 0.01;\n return (\n <SpinButton\n disabled={disabled}\n step={step}\n value={hasValue ? displayValue : ''}\n incrementButtonAriaLabel=\"Increase\"\n decrementButtonAriaLabel=\"Decrease\"\n onChange={onChange ? (_, newValue) => onChange(newValue ?? '') : undefined}\n />\n );\n};\n","import React from 'react';\nimport { DatePicker } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `date` / `datetime` controls — Fluent UI DatePicker bound to a\n * parsed Date value.\n *\n * Lifted from ControlRenderer.tsx cases 'date'/'datetime'.\n */\nexport const DateControl: React.FC<ControlPartProps> = ({\n control,\n effectiveValue,\n hasValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n\n let dateValue: Date | undefined;\n if (hasValue && effectiveValue) {\n const parsed = effectiveValue instanceof Date ? effectiveValue : new Date(String(effectiveValue));\n if (!isNaN(parsed.getTime())) {\n dateValue = parsed;\n }\n }\n\n const showPlaceholder = (control.properties.showPlaceholder as boolean) ?? false;\n const customPlaceholder = control.properties.placeholder as string | undefined;\n const placeholder = showPlaceholder\n ? customPlaceholder ??\n (control.type === 'datetime' ? 'Select date and time' : 'Select date')\n : undefined;\n\n return (\n <DatePicker\n placeholder={placeholder}\n disabled={disabled}\n ariaLabel={control.label}\n value={dateValue}\n onSelectDate={onChange ? (date) => onChange(date ?? null) : undefined}\n />\n );\n};\n","import React from 'react';\nimport { Checkbox } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `checkbox` control. The dispatcher swaps the label position when\n * `properties.boxSide === 'start'`; this leaf renders the box only.\n *\n * Lifted from ControlRenderer.tsx case 'checkbox'.\n */\nexport const CheckboxControl: React.FC<ControlPartProps> = ({\n control,\n effectiveValue,\n hasValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n const checked = hasValue ? Boolean(effectiveValue) : undefined;\n const boxSide = (control.properties.boxSide as 'start' | 'end') ?? 'end';\n return (\n <Checkbox\n label=\"\"\n boxSide={boxSide}\n disabled={disabled}\n checked={checked}\n onChange={onChange ? (_, isChecked) => onChange(!!isChecked) : undefined}\n />\n );\n};\n","import React from 'react';\nimport { Toggle } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `toggle` control — Fluent UI v8 Toggle with configurable on/off labels.\n *\n * Lifted from ControlRenderer.tsx case 'toggle'.\n */\nexport const ToggleControl: React.FC<ControlPartProps> = ({\n control,\n effectiveValue,\n hasValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n const checked = hasValue ? Boolean(effectiveValue) : undefined;\n return (\n <Toggle\n onText={(control.properties.onText as string) ?? 'Yes'}\n offText={(control.properties.offText as string) ?? 'No'}\n disabled={disabled}\n checked={checked}\n onChange={onChange ? (_, isChecked) => onChange(!!isChecked) : undefined}\n />\n );\n};\n","import React from 'react';\nimport { Slider } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `slider` control — Fluent UI v8 Slider.\n *\n * Lifted from ControlRenderer.tsx case 'slider'. The legacy editor\n * branch didn't wire `value` / `onChange` (designer-only preview), but\n * the dispatcher now passes them through so generated runtimes get a\n * controlled slider.\n */\nexport const SliderControl: React.FC<ControlPartProps> = ({\n control,\n effectiveValue,\n hasValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n const min = (control.properties.min as number) ?? 0;\n const max = (control.properties.max as number) ?? 100;\n const step = (control.properties.step as number) ?? 1;\n const showValue = (control.properties.showValue as boolean) ?? true;\n const vertical = (control.properties.vertical as boolean) ?? false;\n const originFromZero = (control.properties.originFromZero as boolean) ?? false;\n const snapToStep = (control.properties.snapToStep as boolean) ?? true;\n\n const value = hasValue\n ? typeof effectiveValue === 'number'\n ? effectiveValue\n : parseFloat(String(effectiveValue))\n : undefined;\n\n return (\n <Slider\n min={min}\n max={max}\n step={step}\n showValue={showValue}\n vertical={vertical}\n originFromZero={originFromZero}\n snapToStep={snapToStep}\n disabled={disabled}\n value={typeof value === 'number' && !isNaN(value) ? value : undefined}\n onChange={onChange ? (next) => onChange(next) : undefined}\n styles={{ root: { width: '100%' } }}\n />\n );\n};\n","import React from 'react';\nimport { Rating, RatingSize } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\nimport { EmojiRating } from './internals/EmojiRating';\n\n/**\n * `rating` control — Fluent UI Rating (stars) or `EmojiRating`\n * (icon-based).\n *\n * Lifted from ControlRenderer.tsx case 'rating'.\n */\nexport const RatingControl: React.FC<ControlPartProps> = ({ control, interactive }) => {\n const disabled = isDisabled(control, interactive);\n const max = (control.properties.max as number) ?? 5;\n const allowZeroStars = (control.properties.allowZeroStars as boolean) ?? false;\n const size = (control.properties.size as string) ?? 'medium';\n const ratingStyle = (control.properties.ratingStyle as string) ?? 'stars';\n const useColor = (control.properties.useColor as boolean) ?? false;\n const starColor = (control.properties.starColor as string) ?? '#ffc83d';\n const customEmojiColor = (control.properties.emojiColor as string) || '';\n\n if (ratingStyle === 'stars') {\n const sizeMap: Record<string, typeof RatingSize[keyof typeof RatingSize]> = {\n small: RatingSize.Small,\n medium: RatingSize.Small,\n large: RatingSize.Large,\n };\n return (\n <Rating\n max={max}\n allowZeroStars={allowZeroStars}\n size={sizeMap[size] ?? RatingSize.Small}\n disabled={disabled}\n styles={\n useColor\n ? {\n ratingStarFront: { color: starColor },\n ratingStarBack: { color: '#c8c6c4' },\n }\n : undefined\n }\n />\n );\n }\n\n return (\n <EmojiRating\n max={max}\n size={size}\n useColor={useColor}\n customEmojiColor={customEmojiColor}\n disabled={disabled}\n />\n );\n};\n","/**\n * EmojiRating — sentiment-style rating using emoji icons.\n *\n * Extracted from the inline `EmojiRating` in\n * apps/form-builder/src/components/form-designer/canvas/ControlRenderer.tsx\n * in Phase 6.5b. The rating-control branch (extracted in 6.5f) will\n * delegate to this implementation; the form-builder ControlRenderer\n * imports it from here in the meantime.\n *\n * Stateless except for local hover/selection — no store reads, no\n * editor-specific behavior. Safe to render in any host.\n */\n\nimport React, { useState } from 'react';\nimport { Icon } from '@fluentui/react';\n\nexport interface EmojiRatingProps {\n /** Number of emoji buckets (2–5). Values outside the range clamp. */\n max: number;\n /** Icon size (small/medium/large). */\n size: string;\n /** When true, emoji uses the per-bucket sentiment color (red→green). */\n useColor: boolean;\n /** Override color for ALL buckets (takes precedence over the sentiment palette). */\n customEmojiColor: string;\n /** When true, the rating ignores clicks and renders muted. */\n disabled: boolean;\n}\n\n/** Curated emoji sets by bucket count — evenly spread across the sentiment range. */\nconst EMOJI_SETS: Record<\n number,\n { icons: string[]; colors: string[]; selectedColors: string[]; labels: string[] }\n> = {\n 2: {\n icons: ['EmojiDisappointed', 'Emoji'],\n colors: ['#d13438', '#107c10'],\n selectedColors: ['#a4262c', '#0b6a0b'],\n labels: ['Unhappy', 'Happy'],\n },\n 3: {\n icons: ['EmojiDisappointed', 'EmojiNeutral', 'Emoji'],\n colors: ['#d13438', '#c8c820', '#107c10'],\n selectedColors: ['#a4262c', '#8f7b0e', '#0b6a0b'],\n labels: ['Unhappy', 'Neutral', 'Happy'],\n },\n 4: {\n icons: ['EmojiDisappointed', 'Sad', 'Emoji2', 'Emoji'],\n colors: ['#d13438', '#ca5010', '#498205', '#107c10'],\n selectedColors: ['#a4262c', '#8e3900', '#2d5702', '#0b6a0b'],\n labels: ['Very Unhappy', 'Unhappy', 'Happy', 'Very Happy'],\n },\n 5: {\n icons: ['EmojiDisappointed', 'Sad', 'EmojiNeutral', 'Emoji2', 'Emoji'],\n colors: ['#d13438', '#ca5010', '#c8c820', '#498205', '#107c10'],\n selectedColors: ['#a4262c', '#8e3900', '#8f7b0e', '#2d5702', '#0b6a0b'],\n labels: ['Very Unhappy', 'Unhappy', 'Neutral', 'Happy', 'Very Happy'],\n },\n};\n\nfunction getEmojiSet(count: number) {\n const clamped = Math.max(2, Math.min(count, 5));\n return EMOJI_SETS[clamped];\n}\n\nexport const EmojiRating: React.FC<EmojiRatingProps> = ({\n max,\n size,\n useColor,\n customEmojiColor,\n disabled,\n}) => {\n const [selectedIndex, setSelectedIndex] = useState<number | null>(null);\n const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);\n\n const iconSizeMap: Record<string, number> = { small: 20, medium: 28, large: 36 };\n const baseSize = iconSizeMap[size] ?? 28;\n const emojiSet = getEmojiSet(max);\n const gap = size === 'small' ? 4 : 8;\n\n return (\n <div\n style={{ display: 'flex', gap, alignItems: 'center' }}\n onMouseLeave={() => !disabled && setHoveredIndex(null)}\n >\n {emojiSet.icons.map((iconName, idx) => {\n const isSelected = selectedIndex === idx;\n const isHovered = hoveredIndex === idx;\n const isActive = isSelected || isHovered;\n\n const outlineColor = useColor ? customEmojiColor || emojiSet.colors[idx] : '#605e5c';\n const fillColor = useColor\n ? customEmojiColor || emojiSet.selectedColors[idx]\n : '#323130';\n\n const activeSize = Math.round(baseSize * 1.15);\n const circleSize = isActive ? activeSize + 12 : undefined;\n\n return (\n <div\n key={iconName}\n onClick={() => !disabled && setSelectedIndex(isSelected ? null : idx)}\n onMouseEnter={() => !disabled && setHoveredIndex(idx)}\n title={emojiSet.labels[idx]}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: circleSize,\n height: circleSize,\n borderRadius: '50%',\n backgroundColor: isActive ? fillColor : 'transparent',\n cursor: disabled ? 'default' : 'pointer',\n transition: 'all 0.15s ease',\n flexShrink: 0,\n }}\n >\n <Icon\n iconName={iconName}\n styles={{\n root: {\n fontSize: isActive ? activeSize : baseSize,\n color: isActive ? '#ffffff' : outlineColor,\n opacity: disabled ? 0.4 : selectedIndex !== null && !isActive ? 0.4 : 1,\n transition: 'all 0.15s ease',\n display: 'flex',\n },\n }}\n />\n </div>\n );\n })}\n </div>\n );\n};\n","import React from 'react';\nimport { SpinButton } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `spinbutton` control — Fluent UI SpinButton with min/max/step/precision.\n *\n * Lifted from ControlRenderer.tsx case 'spinbutton'.\n */\nexport const SpinButtonControl: React.FC<ControlPartProps> = ({ control, interactive }) => {\n const disabled = isDisabled(control, interactive);\n const min = (control.properties.min as number) ?? 0;\n const max = (control.properties.max as number) ?? 100;\n const step = (control.properties.step as number) ?? 1;\n const precision = (control.properties.precision as number) ?? 0;\n return (\n <SpinButton\n min={min}\n max={max}\n step={step}\n precision={precision}\n disabled={disabled}\n styles={{ root: { width: '100%' } }}\n />\n );\n};\n","import React from 'react';\nimport {\n Dropdown,\n ComboBox,\n Icon,\n type IDropdownOption,\n type IComboBoxOption,\n type ISelectableOption,\n type IRenderFunction,\n} from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `dropdown` / `optionset` controls — option-set picker with custom\n * options or attribute-bound option-set metadata. Multi-select renders\n * via ComboBox; single-select via Dropdown.\n *\n * Lifted from ControlRenderer.tsx cases 'dropdown'/'optionset'. Reads\n * options from `control.properties.options` (custom mode) or\n * `control.dataBinding.optionSetOptions` (attribute/global mode).\n */\n\ninterface RawOption {\n key: number;\n text: string;\n color?: string;\n icon?: string;\n}\n\nfunction resolveRawOptions(\n optionSourceMode: string,\n customOptions: RawOption[] | undefined,\n metadataOptions: Array<{ value: number; label: string; color?: string }> | undefined,\n): RawOption[] {\n if (optionSourceMode === 'custom' && customOptions && customOptions.length > 0) {\n return customOptions;\n }\n if (metadataOptions && metadataOptions.length > 0) {\n return metadataOptions.map((opt) => ({ key: opt.value, text: opt.label, color: opt.color }));\n }\n return customOptions ?? [];\n}\n\nexport const DropdownControl: React.FC<ControlPartProps> = ({\n control,\n effectiveValue,\n displayValue,\n hasValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n const optionSourceMode = (control.properties.optionSourceMode as string) ?? 'custom';\n const metadataOptions = control.dataBinding?.optionSetOptions;\n const customOptions = control.properties.options as RawOption[] | undefined;\n const isMultiSelect = (control.properties.multiSelect as boolean) ?? false;\n const showOptionColors = (control.properties.showOptionColors as boolean) ?? false;\n const showPlaceholder = (control.properties.showPlaceholder as boolean) ?? false;\n const customPlaceholder = control.properties.placeholder as string | undefined;\n\n const placeholder = showPlaceholder\n ? customPlaceholder ?? (isMultiSelect ? 'Select options' : 'Select an option')\n : undefined;\n\n const rawOptions = resolveRawOptions(optionSourceMode, customOptions, metadataOptions);\n const options: IDropdownOption[] = rawOptions.map((opt) => ({\n key: opt.key,\n text: opt.text,\n data: { color: opt.color, icon: opt.icon },\n }));\n\n let selectedKey: string | number | undefined;\n let selectedKeys: (string | number)[] = [];\n if (hasValue) {\n if (isMultiSelect && Array.isArray(effectiveValue)) {\n selectedKeys = effectiveValue;\n } else if (typeof effectiveValue === 'number') {\n selectedKey = effectiveValue;\n selectedKeys = [effectiveValue];\n } else if (typeof effectiveValue === 'string') {\n const matchByText = options.find((opt) => opt.text.toLowerCase() === displayValue.toLowerCase());\n selectedKey = matchByText?.key ?? effectiveValue;\n selectedKeys = matchByText ? [matchByText.key] : [];\n }\n }\n\n const renderOption: IRenderFunction<ISelectableOption> = (optProps) => {\n if (!optProps) return null;\n const optColor = optProps.data?.color;\n const optIcon = optProps.data?.icon;\n const iconColor = showOptionColors && optColor ? optColor : '#605e5c';\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {optIcon ? (\n <Icon iconName={optIcon} styles={{ root: { fontSize: 14, color: iconColor, flexShrink: 0 } }} />\n ) : (\n showOptionColors && optColor && (\n <div\n style={{\n width: 12,\n height: 12,\n borderRadius: 2,\n backgroundColor: optColor,\n flexShrink: 0,\n }}\n />\n )\n )}\n <span>{optProps.text}</span>\n </div>\n );\n };\n\n const renderTitle: IRenderFunction<IDropdownOption[]> = (titleOptions) => {\n if (!titleOptions || titleOptions.length === 0) return null;\n if (isMultiSelect) {\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexWrap: 'wrap' }}>\n {titleOptions.map((opt) => {\n const optIcon = opt.data?.icon;\n const optColor = opt.data?.color;\n const iconColor = showOptionColors && optColor ? optColor : '#605e5c';\n return (\n <span\n key={opt.key}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n backgroundColor: '#f3f2f1',\n padding: '2px 6px',\n borderRadius: 3,\n fontSize: 12,\n }}\n >\n {optIcon ? (\n <Icon iconName={optIcon} styles={{ root: { fontSize: 12, color: iconColor } }} />\n ) : (\n showOptionColors && optColor && (\n <div\n style={{\n width: 8,\n height: 8,\n borderRadius: 2,\n backgroundColor: optColor,\n }}\n />\n )\n )}\n {opt.text}\n </span>\n );\n })}\n </div>\n );\n }\n const opt = titleOptions[0];\n const optIcon = opt.data?.icon;\n const optColor = opt.data?.color;\n const iconColor = showOptionColors && optColor ? optColor : '#605e5c';\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {optIcon ? (\n <Icon iconName={optIcon} styles={{ root: { fontSize: 14, color: iconColor } }} />\n ) : (\n showOptionColors && optColor && (\n <div\n style={{\n width: 12,\n height: 12,\n borderRadius: 2,\n backgroundColor: optColor,\n }}\n />\n )\n )}\n <span>{opt.text}</span>\n </div>\n );\n };\n\n if (isMultiSelect) {\n const comboOptions: IComboBoxOption[] = options.map((opt) => ({\n ...opt,\n selected: selectedKeys.includes(opt.key as number),\n }));\n return (\n <ComboBox\n placeholder={placeholder}\n options={comboOptions}\n disabled={disabled}\n multiSelect\n selectedKey={selectedKeys as number[]}\n onRenderOption={renderOption}\n onChange={\n onChange\n ? (_, option) => {\n if (!option) return;\n const key = option.key as number;\n const newKeys: number[] = option.selected\n ? [...(selectedKeys as number[]), key]\n : (selectedKeys as number[]).filter((k) => k !== key);\n onChange(newKeys.join(','));\n }\n : undefined\n }\n />\n );\n }\n\n return (\n <Dropdown\n placeholder={placeholder}\n options={options}\n disabled={disabled}\n selectedKey={selectedKey}\n onRenderOption={renderOption}\n onRenderTitle={renderTitle}\n onChange={onChange ? (_, option) => onChange(option?.key ?? '') : undefined}\n />\n );\n};\n","import React from 'react';\nimport {\n ComboBox,\n Icon,\n type IComboBoxOption,\n type ISelectableOption,\n type IRenderFunction,\n} from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\n\n/**\n * `combobox` control — ComboBox with text input, supports free-form and\n * auto-complete. Multi-select renders an optional \"Select All\" header.\n *\n * Lifted from ControlRenderer.tsx case 'combobox'.\n */\n\ninterface RawComboOption {\n key: number;\n text: string;\n color?: string;\n icon?: string;\n itemType?: string;\n}\n\nfunction resolveRawOptions(\n mode: string,\n customOptions: RawComboOption[] | undefined,\n metadataOptions: Array<{ value: number; label: string; color?: string }> | undefined,\n): RawComboOption[] {\n if (mode === 'custom' && customOptions && customOptions.length > 0) {\n return customOptions;\n }\n if (metadataOptions && metadataOptions.length > 0) {\n return metadataOptions.map((opt) => ({ key: opt.value, text: opt.label, color: opt.color }));\n }\n return customOptions ?? [];\n}\n\nexport const ComboBoxControl: React.FC<ControlPartProps> = ({\n control,\n effectiveValue,\n displayValue,\n hasValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n const sourceMode = (control.properties.optionSourceMode as string) ?? 'custom';\n const metadataOptions = control.dataBinding?.optionSetOptions;\n const customOptions = control.properties.options as RawComboOption[] | undefined;\n const multiSelect = (control.properties.multiSelect as boolean) ?? false;\n const allowFreeform = (control.properties.allowFreeform as boolean) ?? true;\n const autoComplete = ((control.properties.autoComplete as 'on' | 'off') ?? 'on');\n const showOptionColors = (control.properties.showOptionColors as boolean) ?? false;\n const showPlaceholder = (control.properties.showPlaceholder as boolean) ?? false;\n const customPlaceholder = control.properties.placeholder as string | undefined;\n\n const placeholder = showPlaceholder\n ? customPlaceholder ?? (multiSelect ? 'Select options' : 'Search or select an option')\n : undefined;\n\n const rawOptions = resolveRawOptions(sourceMode, customOptions, metadataOptions);\n const options: IComboBoxOption[] = rawOptions.map((opt) => ({\n key: opt.key,\n text: opt.text,\n data: { color: opt.color, icon: opt.icon },\n ...(opt.itemType === 'header' ? { itemType: 2 } : {}),\n ...(opt.itemType === 'divider' ? { itemType: 1 } : {}),\n }));\n\n let selectedKey: string | number | undefined;\n let selectedKeys: (string | number)[] = [];\n if (hasValue) {\n if (multiSelect && Array.isArray(effectiveValue)) {\n selectedKeys = effectiveValue;\n } else if (typeof effectiveValue === 'number') {\n selectedKey = effectiveValue;\n selectedKeys = [effectiveValue];\n } else if (typeof effectiveValue === 'string') {\n const matchByText = options.find((opt) => opt.text.toLowerCase() === displayValue.toLowerCase());\n selectedKey = matchByText?.key ?? effectiveValue;\n selectedKeys = matchByText ? [matchByText.key] : [];\n }\n }\n\n const renderOption: IRenderFunction<ISelectableOption> = (optProps) => {\n if (!optProps) return null;\n const optColor = optProps.data?.color;\n const optIcon = optProps.data?.icon;\n const iconColor = showOptionColors && optColor ? optColor : '#605e5c';\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {optIcon ? (\n <Icon iconName={optIcon} styles={{ root: { fontSize: 14, color: iconColor, flexShrink: 0 } }} />\n ) : (\n showOptionColors && optColor && (\n <div\n style={{\n width: 12,\n height: 12,\n borderRadius: 2,\n backgroundColor: optColor,\n flexShrink: 0,\n }}\n />\n )\n )}\n <span>{optProps.text}</span>\n </div>\n );\n };\n\n if (multiSelect) {\n const showSelectAll = (control.properties.showSelectAll as boolean) ?? false;\n const selectableOptions = options.filter((opt) => opt.itemType !== 2 && opt.itemType !== 1);\n const multiOptions: IComboBoxOption[] = options.map((opt) => ({\n ...opt,\n selected: selectedKeys.includes(opt.key as number),\n }));\n const allSelectableKeys = selectableOptions.map((opt) => opt.key as number);\n const allSelected =\n allSelectableKeys.length > 0 && allSelectableKeys.every((k) => selectedKeys.includes(k));\n\n if (showSelectAll) {\n multiOptions.unshift({\n key: 'selectAll',\n text: 'Select All',\n styles: { optionText: { fontWeight: 600 } },\n selected: allSelected,\n });\n }\n\n // Multi-select ComboBox needs a non-null onChange to keep its\n // internal checkbox state interactive — pass a no-op when the\n // caller didn't supply one (mirrors editor preview behaviour).\n const multiOnChange = onChange\n ? (_: unknown, option?: IComboBoxOption) => {\n if (!option) return;\n if (option.key === 'selectAll') {\n const newKeys = option.selected ? allSelectableKeys : [];\n onChange(newKeys.join(','));\n return;\n }\n const key = option.key as number;\n const newKeys: number[] = option.selected\n ? [...(selectedKeys as number[]), key]\n : (selectedKeys as number[]).filter((k) => k !== key);\n onChange(newKeys.join(','));\n }\n : () => {};\n\n return (\n <ComboBox\n placeholder={placeholder}\n options={multiOptions}\n disabled={disabled}\n multiSelect\n allowFreeform={allowFreeform}\n autoComplete={autoComplete}\n onRenderOption={renderOption}\n onChange={multiOnChange}\n />\n );\n }\n\n return (\n <ComboBox\n placeholder={placeholder}\n options={options}\n disabled={disabled}\n allowFreeform={allowFreeform}\n autoComplete={autoComplete}\n selectedKey={selectedKey}\n onRenderOption={renderOption}\n onChange={onChange ? (_, option) => onChange(option?.key ?? '') : undefined}\n />\n );\n};\n","/**\n * ChoiceGroupControl — three-layout radio group (standard / icon-cards /\n * image-cards) with optional per-option colors and labels.\n *\n * Extracted from the inline `ChoiceGroupControl` in\n * apps/form-builder/src/components/form-designer/canvas/ControlRenderer.tsx\n * in Phase 6.5b. The `choicegroup` control branch (extracted in 6.5f)\n * delegates to this implementation.\n *\n * Pure: no store reads, no editor-specific behavior. Safe in any host.\n */\n\nimport React, { useState } from 'react';\nimport { ChoiceGroup, Icon, type IChoiceGroupOption } from '@fluentui/react';\n\nexport interface ChoiceGroupControlProps {\n options: Array<{\n key: number;\n text: string;\n color?: string;\n icon?: string;\n imageSrc?: string;\n }>;\n showColors: boolean;\n showLabels: boolean;\n layout: string;\n disabled: boolean;\n initialSelectedKey?: string;\n onChange?: (value: string | number | boolean | Date | null) => void;\n}\n\nexport const ChoiceGroupControl: React.FC<ChoiceGroupControlProps> = ({\n options: rawOptions,\n showColors,\n showLabels,\n layout,\n disabled,\n initialSelectedKey,\n onChange,\n}) => {\n const [selectedKey, setSelectedKey] = useState<string | undefined>(initialSelectedKey);\n\n const handleSelect = (key: number) => {\n if (disabled) return;\n const keyStr = String(key);\n setSelectedKey(keyStr);\n if (onChange) onChange(key);\n };\n\n // ── Icon Cards layout ──\n if (layout === 'icon-cards') {\n return (\n <div role=\"radiogroup\" style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>\n {rawOptions.map((opt) => {\n const optKey = String(opt.key);\n const isSelected = selectedKey === optKey;\n return (\n <div\n key={optKey}\n role=\"radio\"\n aria-checked={isSelected}\n tabIndex={0}\n onClick={() => handleSelect(opt.key)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleSelect(opt.key);\n }\n }}\n style={{\n minWidth: 100,\n border: isSelected ? '2px solid #0078d4' : '1px solid #edebe9',\n borderRadius: 4,\n padding: 12,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 8,\n cursor: disabled ? 'default' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n backgroundColor: isSelected ? '#f0f6ff' : '#ffffff',\n position: 'relative',\n transition: 'background-color 0.15s, border-color 0.15s',\n }}\n onMouseEnter={(e) => {\n if (!disabled && !isSelected) e.currentTarget.style.backgroundColor = '#f3f2f1';\n }}\n onMouseLeave={(e) => {\n if (!isSelected) e.currentTarget.style.backgroundColor = '#ffffff';\n }}\n >\n <div\n style={{\n position: 'absolute',\n top: 8,\n left: 8,\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: `1px solid ${isSelected ? '#0078d4' : '#605e5c'}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {isSelected && (\n <div\n style={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: '#0078d4',\n }}\n />\n )}\n </div>\n <Icon\n iconName={opt.icon || 'RadioBtnOn'}\n styles={{\n root: {\n fontSize: 32,\n color:\n showColors && opt.color\n ? opt.color\n : isSelected\n ? '#0078d4'\n : '#605e5c',\n marginTop: 8,\n },\n }}\n />\n {showLabels && (\n <span style={{ fontSize: 12, color: '#323130', textAlign: 'center' }}>\n {opt.text}\n </span>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n\n // ── Image Cards layout ──\n if (layout === 'image-cards') {\n return (\n <div role=\"radiogroup\" style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>\n {rawOptions.map((opt) => {\n const optKey = String(opt.key);\n const isSelected = selectedKey === optKey;\n return (\n <div\n key={optKey}\n role=\"radio\"\n aria-checked={isSelected}\n tabIndex={0}\n onClick={() => handleSelect(opt.key)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleSelect(opt.key);\n }\n }}\n style={{\n minWidth: 100,\n border: isSelected ? '2px solid #0078d4' : '1px solid #edebe9',\n borderRadius: 4,\n padding: 12,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 8,\n cursor: disabled ? 'default' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n backgroundColor: isSelected ? '#f0f6ff' : '#ffffff',\n position: 'relative',\n transition: 'background-color 0.15s, border-color 0.15s',\n }}\n onMouseEnter={(e) => {\n if (!disabled && !isSelected) e.currentTarget.style.backgroundColor = '#f3f2f1';\n }}\n onMouseLeave={(e) => {\n if (!isSelected) e.currentTarget.style.backgroundColor = '#ffffff';\n }}\n >\n <div\n style={{\n position: 'absolute',\n top: 8,\n left: 8,\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: `1px solid ${isSelected ? '#0078d4' : '#605e5c'}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {isSelected && (\n <div\n style={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: '#0078d4',\n }}\n />\n )}\n </div>\n {opt.imageSrc ? (\n <img\n src={opt.imageSrc}\n alt={opt.text}\n style={{ width: 60, height: 60, objectFit: 'contain', marginTop: 8 }}\n />\n ) : (\n <Icon\n iconName=\"Photo2\"\n styles={{ root: { fontSize: 32, color: '#a19f9d', marginTop: 8 } }}\n />\n )}\n {showLabels && (\n <span style={{ fontSize: 12, color: '#323130', textAlign: 'center' }}>\n {opt.text}\n </span>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n\n const hasDecorations =\n !showLabels || rawOptions.some((opt) => opt.icon || (showColors && opt.color));\n\n if (hasDecorations) {\n return (\n <div\n role=\"radiogroup\"\n style={{\n display: 'flex',\n flexDirection: layout === 'horizontal' ? 'row' : 'column',\n gap: layout === 'horizontal' ? 16 : 0,\n }}\n >\n {rawOptions.map((opt) => {\n const optKey = String(opt.key);\n const isSelected = selectedKey === optKey;\n const optIcon = opt.icon;\n const optColor = showColors ? opt.color : undefined;\n\n return (\n <div\n key={optKey}\n role=\"radio\"\n aria-checked={isSelected}\n tabIndex={0}\n onClick={() => handleSelect(opt.key)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleSelect(opt.key);\n }\n }}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '4px 0',\n cursor: disabled ? 'default' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n }}\n >\n <div\n style={{\n width: 20,\n height: 20,\n borderRadius: '50%',\n border: `1px solid ${isSelected ? '#0078d4' : '#605e5c'}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n >\n {isSelected && (\n <div\n style={{\n width: 10,\n height: 10,\n borderRadius: '50%',\n backgroundColor: '#0078d4',\n }}\n />\n )}\n </div>\n {optIcon && (\n <Icon\n iconName={optIcon}\n styles={{\n root: {\n fontSize: 14,\n color: optColor || '#605e5c',\n flexShrink: 0,\n },\n }}\n />\n )}\n {!optIcon && optColor && (\n <div\n style={{\n width: 12,\n height: 12,\n borderRadius: 2,\n backgroundColor: optColor,\n flexShrink: 0,\n }}\n />\n )}\n {showLabels && opt.text && (\n <span style={{ fontSize: 14, color: '#323130' }}>{opt.text}</span>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n\n // No decorations — use standard ChoiceGroup\n const cgOptions: IChoiceGroupOption[] = rawOptions.map((opt) => ({\n key: String(opt.key),\n text: opt.text,\n }));\n\n return (\n <ChoiceGroup\n options={cgOptions}\n selectedKey={selectedKey}\n disabled={disabled}\n onChange={(_, option) => {\n if (option) handleSelect(Number(option.key));\n }}\n styles={\n layout === 'horizontal'\n ? {\n flexContainer: { display: 'flex', flexDirection: 'row', gap: 16 },\n }\n : undefined\n }\n />\n );\n};\n","import React from 'react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\nimport { ChoiceGroupControl as InnerChoiceGroup } from './internals/ChoiceGroupControl';\n\n/**\n * `choicegroup` control — radio-button group that supports custom or\n * attribute-bound option-set sources. Layout (vertical/horizontal/\n * icon-cards/image-cards) is forwarded to the runtime\n * `ChoiceGroupControl` sub-component.\n *\n * Lifted from ControlRenderer.tsx case 'choicegroup'.\n */\nexport const ChoiceGroupBranch: React.FC<ControlPartProps> = ({\n control,\n effectiveValue,\n hasValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n const sourceMode = (control.properties.optionSourceMode as string) ?? 'custom';\n const metadataOptions = control.dataBinding?.optionSetOptions;\n const customOptions = control.properties.options as\n | Array<{ key: number; text: string; color?: string; icon?: string; imageSrc?: string }>\n | undefined;\n\n let rawOptions: Array<{ key: number; text: string; color?: string; icon?: string; imageSrc?: string }>;\n if (sourceMode === 'custom' && customOptions && customOptions.length > 0) {\n rawOptions = customOptions;\n } else if (metadataOptions && metadataOptions.length > 0) {\n rawOptions = metadataOptions.map((opt) => ({ key: opt.value, text: opt.label, color: opt.color }));\n } else {\n rawOptions = customOptions ?? [];\n }\n\n let selectedKey: string | undefined;\n if (hasValue) {\n if (typeof effectiveValue === 'number') {\n selectedKey = String(effectiveValue);\n } else if (typeof effectiveValue === 'string') {\n selectedKey = effectiveValue;\n }\n }\n\n return (\n <InnerChoiceGroup\n options={rawOptions}\n showColors={(control.properties.showOptionColors as boolean) ?? false}\n showLabels={(control.properties.showLabels as boolean) ?? true}\n layout={(control.properties.layout as string) ?? 'vertical'}\n disabled={disabled}\n initialSelectedKey={selectedKey}\n onChange={onChange}\n />\n );\n};\n\n","/**\n * LookupControl — Dynamics 365-style lookup field.\n *\n * Moved from apps/form-builder/src/components/form-designer/canvas/\n * LookupControl.tsx in Phase 6.5d.\n *\n * Decoupled from form-builder's Zustand stores by consuming\n * `FormRuntimeCapabilities.searchLookup` from the runtime context. The\n * editor's `EditorFormRuntimeProvider` translates Dataverse client calls\n * to this shape; generated host code will provide its own adapter.\n *\n * Entity-specific knowledge (primary name attribute, secondary text\n * field, person-entity set, entity icons) stays in this file — it's\n * static data, not editor-specific.\n *\n * Avatar fetching (entityimage endpoint) and entity-set-name resolution\n * sit outside the FormRuntimeCapabilities surface and are accepted as\n * optional injected props. The editor shim wires both via the Dataverse\n * client + metadata cache; deployed runtime callers may omit them.\n *\n * Features:\n * - Search icon on the right that triggers search on click\n * - Selected value shows persona icon, linked text, and X to clear\n * - Type-to-search with debouncing\n * - Dropdown with \"+ New\" and \"Advanced\" options\n * - Respects lookupViewId and lookupFetchXml configuration\n */\n\nimport React, { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport {\n Callout,\n DirectionalHint,\n Icon,\n Spinner,\n SpinnerSize,\n Persona,\n PersonaSize,\n PersonaPresence,\n mergeStyles,\n FocusZone,\n FocusZoneDirection,\n Link,\n} from '@fluentui/react';\nimport type { ControlDefinition } from '../../../types';\nimport { useOptionalFormRuntimeContext } from '../../../context/FormRuntimeContext';\nimport type { FormRuntimeCapabilities } from '../../../types/runtime-capabilities';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface LookupRecord {\n id: string;\n name: string;\n entityType?: string;\n secondaryText?: string;\n isDisabled?: boolean;\n imageUrl?: string;\n}\n\nexport type LookupSearchCapability = FormRuntimeCapabilities['searchLookup'];\n\nexport interface LookupControlProps {\n control: ControlDefinition;\n disabled?: boolean;\n value?: string;\n onChange?: (value: string) => void;\n /**\n * Optional override for the runtime context's `searchLookup`. When\n * omitted, the component reads from `useOptionalFormRuntimeContext()`.\n * When neither path supplies it, the \"not connected\" fallback renders.\n */\n searchLookup?: LookupSearchCapability;\n /**\n * Optional override for the runtime context's connection state.\n * Drives the \"not connected\" branch. When omitted, reads from\n * `useOptionalFormRuntimeContext()`.\n */\n isConnectedOverride?: boolean;\n /**\n * Optional avatar fetcher used for person-entity lookups. When\n * omitted, person personas render with initials only.\n */\n fetchEntityImage?: (recordId: string) => Promise<string | null>;\n /**\n * Optional entity logical name → plural set name resolver. Defaults\n * to appending 's'. The editor adapter wires this to the metadata\n * cache so virtual entities and irregular plurals resolve correctly.\n */\n resolveEntitySetName?: (entityLogicalName: string) => string;\n}\n\n// ============================================================================\n// Styles\n// ============================================================================\n\nconst containerClass = mergeStyles({\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n border: '1px solid #8a8886',\n borderRadius: 2,\n backgroundColor: '#ffffff',\n minHeight: 32,\n ':hover': {\n borderColor: '#323130',\n },\n ':focus-within': {\n borderColor: '#0078d4',\n borderWidth: 2,\n },\n});\n\nconst containerDisabledClass = mergeStyles({\n backgroundColor: '#f3f2f1',\n borderColor: '#c8c6c4',\n ':hover': {\n borderColor: '#c8c6c4',\n },\n});\n\nconst inputWrapperClass = mergeStyles({\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n minWidth: 0,\n padding: '0 8px',\n gap: 6,\n});\n\nconst inputClass = mergeStyles({\n flex: 1,\n border: 'none',\n outline: 'none',\n backgroundColor: 'transparent',\n fontSize: 14,\n color: '#323130',\n padding: '6px 0',\n minWidth: 0,\n '::placeholder': {\n color: '#605e5c',\n },\n});\n\nconst searchButtonClass = mergeStyles({\n borderLeft: '1px solid #edebe9',\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 8px',\n cursor: 'pointer',\n backgroundColor: 'transparent',\n ':hover': {\n backgroundColor: '#f3f2f1',\n },\n});\n\nconst selectedValueClass = mergeStyles({\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n flex: 1,\n minWidth: 0,\n padding: '4px 0',\n});\n\nconst selectedLinkClass = mergeStyles({\n flex: 1,\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontSize: 14,\n color: '#0078d4',\n textDecoration: 'underline',\n cursor: 'pointer',\n ':hover': {\n color: '#004578',\n },\n});\n\nconst clearButtonClass = mergeStyles({\n padding: 4,\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n ':hover': {\n backgroundColor: '#f3f2f1',\n borderRadius: 2,\n },\n});\n\nconst calloutClass = mergeStyles({\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: '#ffffff',\n boxShadow: 'rgba(0, 0, 0, 0.12) 0px 0px 2px, rgba(0, 0, 0, 0.14) 0px 2px 4px',\n borderRadius: 2,\n overflow: 'hidden',\n});\n\nconst searchHeaderClass = mergeStyles({\n padding: '8px 12px',\n borderBottom: '1px solid #edebe9',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n});\n\nconst searchInputClass = mergeStyles({\n flex: 1,\n border: 'none',\n outline: 'none',\n fontSize: 14,\n color: '#323130',\n '::placeholder': {\n color: '#605e5c',\n },\n});\n\nconst resultsFromClass = mergeStyles({\n padding: '8px 12px',\n borderBottom: '1px solid #edebe9',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 12,\n color: '#605e5c',\n});\n\nconst filterTabClass = mergeStyles({\n padding: '4px 10px',\n border: '1px solid #8a8886',\n borderRadius: 2,\n backgroundColor: '#ffffff',\n fontSize: 12,\n cursor: 'pointer',\n ':hover': {\n backgroundColor: '#f3f2f1',\n },\n});\n\nconst filterTabActiveClass = mergeStyles({\n backgroundColor: '#f3f2f1',\n borderColor: '#0078d4',\n});\n\nconst listContainerClass = mergeStyles({\n flex: 1,\n overflowY: 'auto',\n maxHeight: 200,\n});\n\nconst recordItemClass = mergeStyles({\n display: 'flex',\n alignItems: 'center',\n padding: '8px 12px',\n cursor: 'pointer',\n backgroundColor: 'transparent',\n border: 'none',\n width: '100%',\n textAlign: 'left',\n gap: 10,\n ':hover': {\n backgroundColor: '#f3f2f1',\n },\n ':focus': {\n backgroundColor: '#f3f2f1',\n outline: 'none',\n },\n});\n\nconst entityIconClass = mergeStyles({\n fontSize: 16,\n color: '#605e5c',\n width: 20,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n});\n\nconst recordNameClass = mergeStyles({\n fontSize: 14,\n color: '#323130',\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nconst noResultsClass = mergeStyles({\n padding: 16,\n textAlign: 'center',\n color: '#605e5c',\n fontSize: 13,\n});\n\nconst loadingClass = mergeStyles({\n padding: 16,\n textAlign: 'center',\n});\n\nconst footerClass = mergeStyles({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 12px',\n borderTop: '1px solid #edebe9',\n backgroundColor: '#faf9f8',\n});\n\nconst footerButtonClass = mergeStyles({\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '4px 8px',\n border: 'none',\n backgroundColor: 'transparent',\n cursor: 'pointer',\n fontSize: 13,\n color: '#323130',\n ':hover': {\n backgroundColor: '#edebe9',\n borderRadius: 2,\n },\n});\n\nconst emptyValueClass = mergeStyles({\n color: '#605e5c',\n fontSize: 14,\n padding: '6px 0',\n});\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction defaultResolveEntitySetName(entityLogicalName: string): string {\n return entityLogicalName + 's';\n}\n\nfunction getPrimaryNameAttribute(entityLogicalName: string): string {\n const knownPrimaryNames: Record<string, string> = {\n account: 'name',\n contact: 'fullname',\n lead: 'fullname',\n opportunity: 'name',\n incident: 'title',\n systemuser: 'fullname',\n team: 'name',\n };\n return knownPrimaryNames[entityLogicalName] || 'name';\n}\n\nfunction getInitials(name: string): string {\n if (!name) return '?';\n const words = name.trim().split(/\\s+/);\n if (words.length >= 2) {\n return (words[0][0] + words[1][0]).toUpperCase();\n }\n return words[0].substring(0, 2).toUpperCase();\n}\n\nfunction getEntityIcon(entityLogicalName: string): string {\n const iconMap: Record<string, string> = {\n account: 'CityNext',\n contact: 'Contact',\n lead: 'People',\n opportunity: 'Money',\n incident: 'Ticket',\n systemuser: 'Contact',\n team: 'Group',\n };\n return iconMap[entityLogicalName] || 'Database';\n}\n\n/** Entities that represent people and should show persona avatars with presence */\nconst PERSON_ENTITIES = new Set(['systemuser', 'contact', 'lead']);\n\nfunction isPersonEntity(entityLogicalName: string | null): boolean {\n return !!entityLogicalName && PERSON_ENTITIES.has(entityLogicalName);\n}\n\nfunction getSecondaryTextField(entityLogicalName: string): string | null {\n const map: Record<string, string> = {\n systemuser: 'jobtitle',\n contact: 'jobtitle',\n account: 'description',\n team: 'description',\n lead: 'jobtitle',\n };\n return map[entityLogicalName] || null;\n}\n\nfunction derivePresence(record: LookupRecord): PersonaPresence {\n if (record.entityType === 'systemuser') {\n return record.isDisabled ? PersonaPresence.offline : PersonaPresence.online;\n }\n if (isPersonEntity(record.entityType || null)) {\n return PersonaPresence.none;\n }\n return PersonaPresence.none;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const LookupControl: React.FC<LookupControlProps> = ({\n control,\n disabled = false,\n value,\n onChange,\n searchLookup: searchLookupProp,\n isConnectedOverride,\n fetchEntityImage,\n resolveEntitySetName = defaultResolveEntitySetName,\n}) => {\n const [selectedRecord, setSelectedRecord] = useState<LookupRecord | null>(null);\n const [searchText, setSearchText] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n const [records, setRecords] = useState<LookupRecord[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const searchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Image cache: record id → data URL\n const [imageCache, setImageCache] = useState<Record<string, string | null>>({});\n const imageFetchedRef = useRef<Set<string>>(new Set());\n\n // Resolve the search capability + connection state from props or context.\n // Reading via the optional variant means we never throw when no provider\n // is wrapping us — the component degrades to its \"not connected\" branch.\n const ctx = useOptionalFormRuntimeContext();\n const searchLookup = searchLookupProp ?? ctx?.searchLookup;\n const isConnected = isConnectedOverride ?? ctx?.connection?.status === 'connected';\n\n // Extract lookup configuration\n const targetEntity = (control.properties.targetEntity as string) || null;\n\n const primaryNameAttr = useMemo(() => {\n if (!targetEntity) return 'name';\n return getPrimaryNameAttribute(targetEntity);\n }, [targetEntity]);\n\n // Initialize selected record from value prop\n useEffect(() => {\n if (value && !selectedRecord) {\n setSelectedRecord({ id: '', name: value, entityType: targetEntity || undefined });\n } else if (!value && selectedRecord) {\n setSelectedRecord(null);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value]);\n\n // Search function — calls the runtime capability with a pre-built filter.\n // The capability handles the rest of the OData query construction (top,\n // $select) and the actual transport.\n const performSearch = useCallback(\n async (query: string = '') => {\n if (!searchLookup || !targetEntity) {\n setRecords([]);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const entitySetName = resolveEntitySetName(targetEntity);\n const secondaryField = getSecondaryTextField(targetEntity);\n\n const filter = query.trim()\n ? `contains(${primaryNameAttr},'${query.replace(/'/g, \"''\")}')`\n : undefined;\n\n const results = await searchLookup(entitySetName, query, { filter, top: 15 });\n\n const mappedRecords: LookupRecord[] = results.map((r) => {\n const secondaryText = secondaryField\n ? (r.record[secondaryField] as string | undefined)\n : undefined;\n const isDisabled =\n targetEntity === 'systemuser'\n ? ((r.record['isdisabled'] as boolean | undefined) ?? false)\n : undefined;\n return {\n id: r.id,\n name: r.primaryName || 'Unknown',\n entityType: targetEntity,\n secondaryText: secondaryText || undefined,\n isDisabled,\n };\n });\n\n setRecords(mappedRecords);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Search failed');\n setRecords([]);\n } finally {\n setLoading(false);\n }\n },\n [searchLookup, targetEntity, primaryNameAttr, resolveEntitySetName],\n );\n\n // Debounced search on typing\n const handleSearchInput = useCallback(\n (newValue: string) => {\n setSearchText(newValue);\n\n if (searchTimeoutRef.current) {\n clearTimeout(searchTimeoutRef.current);\n }\n\n searchTimeoutRef.current = setTimeout(() => {\n performSearch(newValue);\n }, 300);\n },\n [performSearch],\n );\n\n // Fetch entity image for a record via the injected callback. Skipped when\n // the prop is omitted (deployed runtime can choose to render initials).\n const fetchAndCacheImage = useCallback(\n async (recordId: string): Promise<string | null> => {\n if (!recordId || !fetchEntityImage) return null;\n if (imageFetchedRef.current.has(recordId)) return imageCache[recordId] ?? null;\n imageFetchedRef.current.add(recordId);\n\n try {\n const dataUrl = await fetchEntityImage(recordId);\n setImageCache((prev) => ({ ...prev, [recordId]: dataUrl }));\n return dataUrl;\n } catch {\n setImageCache((prev) => ({ ...prev, [recordId]: null }));\n return null;\n }\n },\n [fetchEntityImage, imageCache],\n );\n\n // Fetch images for search results (person entities only)\n useEffect(() => {\n if (!isPersonEntity(targetEntity) || records.length === 0 || !fetchEntityImage) return;\n\n records.forEach((record) => {\n if (record.id && !imageFetchedRef.current.has(record.id)) {\n fetchAndCacheImage(record.id);\n }\n });\n }, [records, targetEntity, fetchEntityImage, fetchAndCacheImage]);\n\n // Open dropdown and trigger search\n const handleOpenDropdown = useCallback(() => {\n if (disabled || !isConnected || !targetEntity || !searchLookup) return;\n\n setIsOpen(true);\n setSearchText('');\n performSearch('');\n\n // Focus search input after dropdown opens\n setTimeout(() => {\n searchInputRef.current?.focus();\n }, 100);\n }, [disabled, isConnected, targetEntity, searchLookup, performSearch]);\n\n // Handle record selection\n const handleRecordSelect = useCallback(\n (record: LookupRecord) => {\n // Attach cached image if available\n const cachedImage = record.id ? imageCache[record.id] : undefined;\n const recordWithImage = cachedImage ? { ...record, imageUrl: cachedImage } : record;\n setSelectedRecord(recordWithImage);\n setIsOpen(false);\n setSearchText('');\n if (onChange) {\n onChange(record.name);\n }\n\n // Fetch image async if not yet cached (for the selected record display)\n if (record.id && !cachedImage && isPersonEntity(targetEntity)) {\n fetchAndCacheImage(record.id).then((dataUrl) => {\n if (dataUrl) {\n setSelectedRecord((prev) =>\n prev && prev.id === record.id ? { ...prev, imageUrl: dataUrl } : prev,\n );\n }\n });\n }\n },\n [onChange, imageCache, targetEntity, fetchAndCacheImage],\n );\n\n // Handle clear\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n setSelectedRecord(null);\n setSearchText('');\n setRecords([]);\n if (onChange) {\n onChange('');\n }\n },\n [onChange],\n );\n\n // Handle dismiss\n const handleDismiss = useCallback(() => {\n setIsOpen(false);\n setSearchText('');\n }, []);\n\n // Cleanup timeout on unmount\n useEffect(() => {\n return () => {\n if (searchTimeoutRef.current) {\n clearTimeout(searchTimeoutRef.current);\n }\n };\n }, []);\n\n // Clear image cache when target entity changes\n useEffect(() => {\n setImageCache({});\n imageFetchedRef.current.clear();\n }, [targetEntity]);\n\n // Not connected — fall back to a plain text input. Same shape whether the\n // caller never provided a context, the connection is offline, or the\n // search capability is missing entirely.\n if (!isConnected || !searchLookup) {\n return (\n <div className={`${containerClass} ${disabled ? containerDisabledClass : ''}`}>\n <div className={inputWrapperClass}>\n <input\n type=\"text\"\n className={inputClass}\n placeholder={targetEntity ? `Search ${targetEntity}...` : 'Search...'}\n disabled={disabled}\n value={value || ''}\n onChange={(e) => onChange?.(e.target.value)}\n />\n </div>\n <div className={searchButtonClass}>\n <Icon iconName=\"Search\" styles={{ root: { fontSize: 16, color: '#605e5c' } }} />\n </div>\n </div>\n );\n }\n\n // No target entity configured\n if (!targetEntity) {\n return (\n <div className={`${containerClass} ${containerDisabledClass}`}>\n <div className={inputWrapperClass}>\n <span className={emptyValueClass}>Configure target table...</span>\n </div>\n <div className={searchButtonClass}>\n <Icon iconName=\"Search\" styles={{ root: { fontSize: 16, color: '#c8c6c4' } }} />\n </div>\n </div>\n );\n }\n\n return (\n <>\n <div\n ref={containerRef}\n className={`${containerClass} ${disabled ? containerDisabledClass : ''}`}\n >\n <div className={inputWrapperClass}>\n {selectedRecord ? (\n // Selected value display with Persona\n <div className={selectedValueClass}>\n <Persona\n text={selectedRecord.name}\n secondaryText={selectedRecord.secondaryText}\n imageUrl={selectedRecord.imageUrl || undefined}\n size={PersonaSize.size24}\n presence={\n isPersonEntity(targetEntity) ? derivePresence(selectedRecord) : PersonaPresence.none\n }\n hidePersonaDetails\n styles={{\n root: { flexShrink: 0 },\n }}\n />\n <Link\n className={selectedLinkClass}\n onClick={(e) => {\n e.preventDefault();\n // Could open record in new tab/panel\n }}\n title={selectedRecord.name}\n >\n {selectedRecord.name}\n </Link>\n {!disabled && (\n <div\n className={clearButtonClass}\n onClick={handleClear}\n role=\"button\"\n tabIndex={0}\n title=\"Clear selection\"\n >\n <Icon iconName=\"Cancel\" styles={{ root: { fontSize: 12, color: '#605e5c' } }} />\n </div>\n )}\n </div>\n ) : (\n // Empty state\n <span className={emptyValueClass}>---</span>\n )}\n </div>\n\n {/* Search button */}\n <div\n className={searchButtonClass}\n onClick={handleOpenDropdown}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n title=\"Look for records\"\n style={{ cursor: disabled ? 'default' : 'pointer' }}\n >\n <Icon\n iconName=\"Search\"\n styles={{ root: { fontSize: 16, color: disabled ? '#c8c6c4' : '#605e5c' } }}\n />\n </div>\n </div>\n\n {/* Dropdown Callout */}\n {isOpen && containerRef.current && (\n <Callout\n target={containerRef.current}\n isBeakVisible={false}\n directionalHint={DirectionalHint.bottomLeftEdge}\n onDismiss={handleDismiss}\n gapSpace={2}\n calloutWidth={Math.max(containerRef.current.offsetWidth, 300)}\n >\n <div\n className={calloutClass}\n style={{ width: Math.max(containerRef.current.offsetWidth, 300) }}\n >\n {/* Search header */}\n <div className={searchHeaderClass}>\n <input\n ref={searchInputRef}\n type=\"text\"\n className={searchInputClass}\n placeholder=\"Look for records\"\n value={searchText}\n onChange={(e) => handleSearchInput(e.target.value)}\n />\n <Icon iconName=\"Search\" styles={{ root: { fontSize: 16, color: '#605e5c' } }} />\n </div>\n\n {/* Results from filter tabs */}\n <div className={resultsFromClass}>\n <span>Results from:</span>\n <button className={`${filterTabClass} ${filterTabActiveClass}`}>\n {targetEntity.charAt(0).toUpperCase() + targetEntity.slice(1)}s\n </button>\n <button className={filterTabClass}>Recent records</button>\n </div>\n\n {/* Results list */}\n <div className={listContainerClass}>\n {loading && (\n <div className={loadingClass}>\n <Spinner size={SpinnerSize.small} label=\"Searching...\" />\n </div>\n )}\n\n {!loading && error && (\n <div className={noResultsClass} style={{ color: '#a80000' }}>\n <Icon iconName=\"Warning\" styles={{ root: { marginRight: 4 } }} />\n {error}\n </div>\n )}\n\n {!loading && !error && records.length === 0 && (\n <div className={noResultsClass}>No records found</div>\n )}\n\n {!loading && !error && records.length > 0 && (\n <FocusZone direction={FocusZoneDirection.vertical}>\n {records.map((record) => (\n <button\n key={record.id || record.name}\n className={recordItemClass}\n onClick={() => handleRecordSelect(record)}\n >\n {isPersonEntity(targetEntity) ? (\n <Persona\n text={record.name}\n secondaryText={record.secondaryText}\n imageUrl={record.id ? imageCache[record.id] || undefined : undefined}\n size={PersonaSize.size32}\n presence={derivePresence(record)}\n hidePersonaDetails\n styles={{ root: { flexShrink: 0 } }}\n />\n ) : (\n <div className={entityIconClass}>\n <Icon iconName={getEntityIcon(targetEntity)} />\n </div>\n )}\n <div style={{ flex: 1, minWidth: 0, overflow: 'hidden' }}>\n <span className={recordNameClass}>{record.name}</span>\n {record.secondaryText && (\n <div\n style={{\n fontSize: 12,\n color: '#605e5c',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {record.secondaryText}\n </div>\n )}\n </div>\n </button>\n ))}\n </FocusZone>\n )}\n </div>\n\n {/* Footer with New and Advanced */}\n <div className={footerClass}>\n <button\n className={footerButtonClass}\n onClick={() => {\n /* future: open creation flow */\n }}\n >\n <Icon iconName=\"Add\" styles={{ root: { fontSize: 14 } }} />\n <span>New</span>\n </button>\n <button\n className={footerButtonClass}\n onClick={() => {\n /* future: open advanced lookup */\n }}\n >\n <Icon iconName=\"Search\" styles={{ root: { fontSize: 14 } }} />\n <span>Advanced</span>\n </button>\n </div>\n </div>\n </Callout>\n )}\n </>\n );\n};\n\n// Hoisted helpers exported so the editor adapter and tests can reuse the\n// canonical entity-name maps without duplicating them.\nexport const lookupEntityHelpers = {\n getPrimaryNameAttribute,\n getSecondaryTextField,\n isPersonEntity,\n getEntityIcon,\n getInitials,\n};\n","import React, { createContext, useContext } from 'react';\nimport type { FormRuntimeCapabilities } from '../types/runtime-capabilities';\n\n/**\n * Context that exposes editor- or host-supplied async capabilities to\n * the runtime's controls.\n *\n * Two implementations exist (Phase 1 Task 6.5 onwards):\n * - `EditorFormRuntimeProvider` in `apps/form-builder/src/contexts/` —\n * wires capabilities to the form-builder's Zustand stores (designer,\n * dataverse, previewRecord, gridCustomizer).\n * - Generated host code's provider (Phase 3) — wires capabilities to\n * `IApiService` from `@dataverse-kit/api-service`.\n *\n * Per `feedback_v1_migrations`, the runtime DOES NOT define a default\n * mock or no-op provider. Controls that depend on capabilities throw if\n * the consumer hasn't wrapped them in a provider — the error names the\n * provider that's expected, so the failure points at the integration\n * gap rather than masking it with silent no-ops.\n */\nconst FormRuntimeContext = createContext<FormRuntimeCapabilities | null>(null);\n\nFormRuntimeContext.displayName = 'FormRuntimeContext';\n\nexport interface FormRuntimeProviderProps {\n capabilities: FormRuntimeCapabilities;\n children: React.ReactNode;\n}\n\n/**\n * Provider wrapper. Caller supplies a `FormRuntimeCapabilities` value;\n * descendants read it via `useFormRuntimeContext()`. Wrap the runtime's\n * mount point (`<FormRuntime>`) with this; failing to do so causes\n * capability-consuming controls to throw on first render.\n */\nexport const FormRuntimeProvider: React.FC<FormRuntimeProviderProps> = ({\n capabilities,\n children,\n}) => <FormRuntimeContext.Provider value={capabilities}>{children}</FormRuntimeContext.Provider>;\n\n/**\n * Hook for runtime-internal callers that REQUIRE capabilities. Throws\n * with a directed error message if no provider is present so the\n * integration gap is visible at the call site (rather than a vague\n * \"Cannot read properties of null\" that points at the consumer).\n */\nexport function useFormRuntimeContext(): FormRuntimeCapabilities {\n const value = useContext(FormRuntimeContext);\n if (value === null) {\n throw new Error(\n '[@dataverse-kit/form-runtime] useFormRuntimeContext was called outside of a ' +\n '<FormRuntimeProvider>. Wrap your <FormRuntime> mount with a provider that ' +\n 'supplies FormRuntimeCapabilities (the editor app uses ' +\n 'EditorFormRuntimeProvider; generated host code uses ServiceFactory-backed ' +\n 'capabilities). See packages/form-runtime/src/context/FormRuntimeContext.tsx.',\n );\n }\n return value;\n}\n\n/**\n * Same as `useFormRuntimeContext()` but returns `null` when no provider\n * is present. Use for OPTIONAL capability access — controls that have a\n * sensible offline rendering (e.g. timeline, which renders a placeholder\n * when not connected) prefer this over the throwing variant.\n */\nexport function useOptionalFormRuntimeContext(): FormRuntimeCapabilities | null {\n return useContext(FormRuntimeContext);\n}\n","import React from 'react';\nimport type { ControlPartProps } from './types';\nimport { isDisabled } from './types';\nimport { LookupControl } from './internals/LookupControl';\n\n/**\n * `lookup` control — dispatcher branch that wires the editor-controlled\n * value/disabled/onChange triplet into the runtime `LookupControl`\n * sub-component. Sub-component handles `searchLookup` + persona avatars\n * itself via the runtime context.\n *\n * Lifted from ControlRenderer.tsx case 'lookup'.\n */\nexport const LookupBranch: React.FC<ControlPartProps> = ({\n control,\n displayValue,\n hasValue,\n interactive,\n onChange,\n}) => {\n const disabled = isDisabled(control, interactive);\n return (\n <LookupControl\n control={control}\n disabled={disabled}\n value={hasValue ? displayValue : undefined}\n onChange={onChange ? (next) => onChange(next) : undefined}\n />\n );\n};\n","/**\n * WebResourceRenderer — preview surface for Dynamics web-resource controls.\n *\n * Moved from apps/form-builder/src/components/form-designer/canvas/\n * ControlRenderer.tsx in Phase 6.5e. The component now reads\n * `connection`, `previewContext`, and `fetchWebResource` from\n * `useOptionalFormRuntimeContext()` so the editor's\n * `useWebResourceContent` hook can be retired (Decision C in the Task\n * 6.5 sub-plan).\n *\n * Behaviour preserved:\n * - HTML web resources render via URL into a sandboxed iframe.\n * - Image (PNG/JPG/GIF/ICO/SVG) and code (CSS/JS/XML/XSL/RESX) types\n * render the fetched content directly.\n * - \"Not connected\" / \"no resource configured\" / \"loading\" / \"error\"\n * states map to the same placeholders the editor surfaced.\n *\n * The embedded-entity-browser special case (`/embedded/entity-browser/\n * index.html` + WR_INIT postMessage) is editor-specific and stays in\n * the form-builder shim — see\n * `apps/form-builder/src/components/form-designer/canvas/\n * WebResourceRenderer.tsx`. The runtime version is the same shape\n * generated host code will eventually mount.\n */\n\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { Icon, Spinner, SpinnerSize } from '@fluentui/react';\nimport type { ControlDefinition } from '../../../types';\nimport { useOptionalFormRuntimeContext } from '../../../context/FormRuntimeContext';\n\nexport interface WebResourceRendererProps {\n control: ControlDefinition;\n /**\n * Designer / preview flag. Carried for parity with the legacy editor\n * component — not currently used but reserved for future read-only\n * overlays at design time.\n */\n designMode?: boolean;\n}\n\ninterface WebResourceFetchState {\n content: string | null;\n loading: boolean;\n error: string | null;\n}\n\nconst TYPE_CONFIG: Record<string, { icon: string; color: string; label: string }> = {\n HTML: { icon: 'FileHTML', color: '#e44d26', label: 'HTML Web Page' },\n CSS: { icon: 'FileCSS', color: '#264de4', label: 'Style Sheet (CSS)' },\n JS: { icon: 'JavaScriptLanguage', color: '#f7df1e', label: 'Script (JScript)' },\n PNG: { icon: 'FileImage', color: '#0078d4', label: 'PNG Image' },\n JPG: { icon: 'FileImage', color: '#0078d4', label: 'JPG Image' },\n GIF: { icon: 'FileImage', color: '#0078d4', label: 'GIF Image' },\n SVG: { icon: 'FileImage', color: '#ffb13b', label: 'Vector (SVG)' },\n ICO: { icon: 'FileImage', color: '#0078d4', label: 'ICO Image' },\n XML: { icon: 'FileCode', color: '#f26522', label: 'Data (XML)' },\n XSL: { icon: 'FileCode', color: '#68217a', label: 'Style Sheet (XSL)' },\n RESX: { icon: 'LocaleLanguage', color: '#107c10', label: 'String (RESX)' },\n};\n\nconst IMAGE_TYPES = new Set(['PNG', 'JPG', 'GIF', 'SVG', 'ICO']);\nconst CODE_TYPES = new Set(['CSS', 'JS', 'XML', 'XSL', 'RESX']);\n\nexport const WebResourceRenderer: React.FC<WebResourceRendererProps> = ({ control }) => {\n const webResourceName = (control.properties.webResourceName as string) || '';\n const webResourceType = (control.properties.webResourceType as string) || 'HTML';\n const height = (control.properties.height as number) ?? 200;\n const passRecordId = (control.properties.passRecordId as boolean) ?? false;\n\n const ctx = useOptionalFormRuntimeContext();\n const isConnected = ctx?.connection.status === 'connected';\n const environmentUrl = ctx?.connection.dynamicsUrl ?? null;\n const previewRecordId = ctx?.previewContext.recordId ?? null;\n\n const isHtml = webResourceType === 'HTML';\n const isImage = IMAGE_TYPES.has(webResourceType);\n const isCode = CODE_TYPES.has(webResourceType);\n\n const [fetchState, setFetchState] = useState<WebResourceFetchState>({\n content: null,\n loading: false,\n error: null,\n });\n\n // Resolve typeConfig with HTML fallback so unknown type codes still\n // render a coherent header.\n const typeConfig = TYPE_CONFIG[webResourceType] ?? TYPE_CONFIG.HTML;\n\n // Fetch the resource content for non-HTML types. HTML loads via URL\n // and never touches `fetchWebResource`. Trigger on inputs that change\n // the fetch identity — `ctx?.fetchWebResource` is stable across\n // renders when the surrounding provider is.\n useEffect(() => {\n if (!ctx?.fetchWebResource || !webResourceName || isHtml || !isConnected) {\n setFetchState({ content: null, loading: false, error: null });\n return;\n }\n\n let cancelled = false;\n const controller = new AbortController();\n\n setFetchState({ content: null, loading: true, error: null });\n\n ctx\n .fetchWebResource(webResourceName, undefined, { signal: controller.signal })\n .then((data) => {\n if (cancelled) return;\n const { content, contentType } = data;\n // The capability returns `content` as decoded text (for\n // HTML/CSS/JS/XML) or base64-encoded bytes (for images).\n // Image branches re-wrap as a data URI so <img src> works.\n const rendered = contentType.startsWith('image/')\n ? `data:${contentType};base64,${content}`\n : content;\n setFetchState({ content: rendered, loading: false, error: null });\n })\n .catch((err: unknown) => {\n if (cancelled) return;\n setFetchState({\n content: null,\n loading: false,\n error: err instanceof Error ? err.message : 'Failed to fetch web resource',\n });\n });\n\n return () => {\n cancelled = true;\n controller.abort();\n };\n }, [ctx, webResourceName, isHtml, isConnected]);\n\n const webResourceUrl = useMemo(() => {\n if (!isHtml || !environmentUrl || !webResourceName) return null;\n let url = `${environmentUrl}/WebResources/${webResourceName}`;\n if (passRecordId && previewRecordId) {\n url += `?id=${previewRecordId}`;\n }\n return url;\n }, [isHtml, environmentUrl, webResourceName, passRecordId, previewRecordId]);\n\n const hasImageContent = isImage && fetchState.content && !fetchState.loading && !fetchState.error;\n const hasCodeContent = isCode && fetchState.content && !fetchState.loading && !fetchState.error;\n const hasUrlContent = isHtml && isConnected && webResourceUrl;\n const hasLiveContent = hasUrlContent || hasImageContent || hasCodeContent;\n\n const renderLiveContent = () => {\n if (isHtml) {\n if (!isConnected) {\n return (\n <div\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: '#deecf9',\n gap: 8,\n padding: 16,\n }}\n >\n <Icon iconName=\"PlugDisconnected\" styles={{ root: { fontSize: 32, color: '#0078d4' } }} />\n <div style={{ fontSize: 12, color: '#0078d4', textAlign: 'center' }}>\n Connect to Dataverse to preview web resource\n </div>\n </div>\n );\n }\n\n if (!webResourceName) {\n return (\n <div\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: '#faf9f8',\n gap: 8,\n }}\n >\n <div\n style={{\n width: 48,\n height: 48,\n borderRadius: 8,\n backgroundColor: typeConfig.color,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Icon iconName={typeConfig.icon} styles={{ root: { fontSize: 24, color: '#fff' } }} />\n </div>\n <div style={{ fontSize: 13, color: '#605e5c' }}>No web resource selected</div>\n <div style={{ fontSize: 11, color: '#a19f9d' }}>Configure in Properties panel</div>\n </div>\n );\n }\n\n return (\n <iframe\n src={webResourceUrl!}\n title={webResourceName}\n sandbox=\"allow-scripts allow-same-origin allow-forms\"\n style={{\n flex: 1,\n width: '100%',\n border: 'none',\n backgroundColor: '#fff',\n }}\n />\n );\n }\n\n if (isImage && hasImageContent) {\n return (\n <div\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 8,\n overflow: 'hidden',\n }}\n >\n <img\n src={fetchState.content!}\n alt={webResourceName}\n style={{\n maxWidth: '100%',\n maxHeight: '100%',\n objectFit: 'contain',\n }}\n />\n </div>\n );\n }\n\n if (isCode && hasCodeContent) {\n return (\n <div\n style={{\n flex: 1,\n overflow: 'auto',\n padding: 8,\n backgroundColor: '#1e1e1e',\n }}\n >\n <pre\n style={{\n margin: 0,\n fontSize: 11,\n fontFamily: 'Consolas, monospace',\n color: '#d4d4d4',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n }}\n >\n {fetchState.content!.substring(0, 2000)}\n {fetchState.content!.length > 2000 ? '\\n\\n... (truncated)' : ''}\n </pre>\n </div>\n );\n }\n\n return null;\n };\n\n const renderPlaceholder = () => {\n if (fetchState.loading) {\n return (\n <div\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n }}\n >\n <Spinner size={SpinnerSize.medium} label=\"Loading web resource...\" />\n </div>\n );\n }\n\n if (fetchState.error) {\n return (\n <div\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: '#fef0f0',\n gap: 8,\n padding: 16,\n }}\n >\n <Icon iconName=\"Warning\" styles={{ root: { fontSize: 32, color: '#d13438' } }} />\n <div style={{ fontSize: 12, color: '#a80000', textAlign: 'center' }}>{fetchState.error}</div>\n </div>\n );\n }\n\n return (\n <div\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: '#faf9f8',\n gap: 8,\n }}\n >\n <div\n style={{\n width: 48,\n height: 48,\n borderRadius: 8,\n backgroundColor: typeConfig.color,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Icon iconName={typeConfig.icon} styles={{ root: { fontSize: 24, color: '#fff' } }} />\n </div>\n {webResourceName ? (\n <>\n <div style={{ fontSize: 13, fontWeight: 600, color: '#323130' }}>{webResourceName}</div>\n <div style={{ fontSize: 11, color: '#605e5c' }}>{typeConfig.label}</div>\n {passRecordId && (\n <div\n style={{\n fontSize: 10,\n color: '#605e5c',\n backgroundColor: '#f3f2f1',\n padding: '4px 8px',\n borderRadius: 4,\n fontFamily: 'monospace',\n }}\n >\n ?id={'{recordid}'}\n </div>\n )}\n {!isConnected && (\n <div\n style={{\n fontSize: 10,\n color: '#0078d4',\n backgroundColor: '#deecf9',\n padding: '4px 8px',\n borderRadius: 4,\n marginTop: 4,\n }}\n >\n Connect to Dataverse for live preview\n </div>\n )}\n </>\n ) : (\n <>\n <div style={{ fontSize: 13, color: '#605e5c' }}>No web resource selected</div>\n <div style={{ fontSize: 11, color: '#a19f9d' }}>Configure in Properties panel</div>\n </>\n )}\n </div>\n );\n };\n\n const renderContent = () => {\n if (isHtml) return renderLiveContent();\n if (hasLiveContent) return renderLiveContent();\n return renderPlaceholder();\n };\n\n return (\n <div\n style={{\n height,\n border: '1px solid #edebe9',\n borderRadius: 2,\n overflow: 'hidden',\n backgroundColor: '#fff',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n padding: '6px 12px',\n borderBottom: '1px solid #edebe9',\n backgroundColor: '#faf9f8',\n gap: 8,\n flexShrink: 0,\n }}\n >\n <Icon iconName=\"Globe\" styles={{ root: { fontSize: 14, color: '#0078d4' } }} />\n <span style={{ fontSize: 12, fontWeight: 600, color: '#323130' }}>Web Resource</span>\n {isHtml && isConnected && webResourceName && (\n <span\n style={{\n fontSize: 10,\n color: '#0078d4',\n backgroundColor: '#deecf9',\n padding: '2px 6px',\n borderRadius: 2,\n }}\n >\n URL\n </span>\n )}\n {!isHtml && hasLiveContent && (\n <span\n style={{\n fontSize: 10,\n color: '#107c10',\n backgroundColor: '#dff6dd',\n padding: '2px 6px',\n borderRadius: 2,\n }}\n >\n Live\n </span>\n )}\n {passRecordId && (\n <span\n style={{\n fontSize: 10,\n color: '#107c10',\n backgroundColor: '#dff6dd',\n padding: '2px 6px',\n borderRadius: 2,\n }}\n >\n + Record ID\n </span>\n )}\n {webResourceName && (\n <span style={{ fontSize: 11, color: '#605e5c', marginLeft: 'auto' }}>{typeConfig.label}</span>\n )}\n </div>\n\n {renderContent()}\n\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '4px 12px',\n borderTop: '1px solid #edebe9',\n backgroundColor: '#faf9f8',\n fontSize: 10,\n color: '#a19f9d',\n flexShrink: 0,\n }}\n >\n <span>{webResourceName || 'Not configured'}</span>\n <span>Height: {height}px</span>\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport type { ControlPartProps } from './types';\nimport { WebResourceRenderer } from './internals/WebResourceRenderer';\n\n/**\n * `webresource` control — dispatcher branch. The renderer pulls its own\n * `connection`, `previewContext`, and `fetchWebResource` from the runtime\n * context; there's nothing per-control to plumb. `interactive` is\n * carried so the dispatcher can pass `designMode` for parity, even\n * though the current renderer ignores it.\n *\n * Lifted from ControlRenderer.tsx case 'webresource'.\n */\nexport const WebResourceBranch: React.FC<ControlPartProps> = ({ control, interactive }) => (\n <WebResourceRenderer control={control} designMode={!interactive} />\n);\n","/**\n * Phase 1b — designer/preview placeholder for chart-category controls.\n *\n * Moved from apps/form-builder/src/components/form-designer/canvas/\n * ChartRenderer.tsx in Phase 6.5b. The form-builder original is now a\n * thin adapter that injects the `entry` prop from `controlMetadata` (the\n * registry hasn't moved to form-runtime yet — pending follow-up).\n *\n * The form-builder designer is locked to Fluent UI v8 (per CLAUDE.md);\n * real chart rendering belongs to the generated output. At authoring\n * time we show a labelled card with the chart icon, title, and a short\n * data-source summary so users can confirm the tile is configured\n * correctly without us pulling in the full v8 chart library as a\n * designer dependency.\n *\n * v9-only charts (funnel, scatter) carry an additional badge so the user\n * understands they will only render in v9-export targets.\n */\n\nimport React from 'react';\nimport { Icon, Text, mergeStyles } from '@fluentui/react';\nimport type { ChartConfig, ControlDefinition, ControlType } from '../../../types';\n\nconst cardClass = mergeStyles({\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n minHeight: 140,\n padding: 12,\n borderRadius: 4,\n border: '1px dashed #c8c6c4',\n backgroundColor: '#faf9f8',\n color: '#323130',\n gap: 8,\n});\n\nconst headerClass = mergeStyles({\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n marginBottom: 4,\n});\n\nconst iconClass = mergeStyles({\n fontSize: 20,\n color: '#0078d4',\n});\n\nconst titleClass = mergeStyles({\n fontWeight: 600,\n fontSize: 14,\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nconst v9BadgeClass = mergeStyles({\n fontSize: 10,\n fontWeight: 600,\n padding: '2px 6px',\n borderRadius: 10,\n backgroundColor: '#fff4ce',\n color: '#7a4d00',\n border: '1px solid #ffb900',\n});\n\nconst bodyClass = mergeStyles({\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: 60,\n});\n\nconst metaClass = mergeStyles({\n fontSize: 11,\n color: '#605e5c',\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n});\n\n/**\n * Minimal subset of `ControlRegistryEntry` that ChartRenderer reads.\n * Decoupled here so form-runtime doesn't depend on the form-builder's\n * `controlMetadata` registry. The caller (designer or runtime\n * dispatcher) resolves the full entry from its own metadata source and\n * passes the slice down.\n */\nexport interface ChartRendererEntry {\n /** Display label shown in the card body and the aria-label fallback. */\n label?: string;\n /** v8 Fluent icon name (e.g. 'BarChartVertical'). */\n icon?: string;\n /** Marks the v9-only badge when true. */\n requiresV9?: boolean;\n}\n\nfunction formatBindingSummary(\n config: ChartConfig | undefined,\n sourceLabel: string | null,\n): string {\n if (!config?.dataSourceId) return 'Sample data — bind to a data source';\n const parts: string[] = [];\n if (sourceLabel) parts.push(sourceLabel);\n if (config.aggregation && config.valueAttribute) {\n parts.push(`${config.aggregation}(${config.valueAttribute})`);\n } else if (config.valueAttribute) {\n parts.push(config.valueAttribute);\n }\n if (config.categoryAttribute) parts.push(`by ${config.categoryAttribute}`);\n return parts.length > 0 ? parts.join(' · ') : 'Data source bound';\n}\n\nexport interface ChartRendererProps {\n control: ControlDefinition;\n /**\n * Optional lookup of data source id → display label. Caller (canvas or\n * preview) reads from `form.settings.dataSources`. We don't import the\n * form here to keep this component pure + testable.\n */\n dataSourceLabelById?: Record<string, string>;\n /**\n * Optional registry slice for the control's type (icon, label,\n * v9-required flag). When omitted, ChartRenderer renders with\n * defaults — defaults match the form-builder editor's behavior when\n * `getControlEntry` returns undefined.\n */\n entry?: ChartRendererEntry;\n}\n\nexport const ChartRenderer: React.FC<ChartRendererProps> = ({\n control,\n dataSourceLabelById,\n entry,\n}) => {\n const chartConfig = control.properties.chartConfig as ChartConfig | undefined;\n const title = chartConfig?.title ?? control.label;\n const sourceLabel = chartConfig?.dataSourceId\n ? (dataSourceLabelById?.[chartConfig.dataSourceId] ?? chartConfig.dataSourceId)\n : null;\n const requiresV9 = entry?.requiresV9 === true;\n\n return (\n <div className={cardClass} aria-label={`${entry?.label ?? 'Chart'}: ${title}`}>\n <div className={headerClass}>\n <Icon iconName={entry?.icon ?? 'BarChartVertical'} className={iconClass} />\n <span className={titleClass}>{title}</span>\n {requiresV9 && (\n <span className={v9BadgeClass} title=\"This chart type renders only in v9 export targets\">\n v9\n </span>\n )}\n </div>\n <div className={bodyClass}>\n <Text variant=\"small\" styles={{ root: { color: '#605e5c', fontStyle: 'italic' } }}>\n {entry?.label ?? 'Chart'} preview\n </Text>\n </div>\n <div className={metaClass}>\n <span>{formatBindingSummary(chartConfig, sourceLabel)}</span>\n {requiresV9 && (\n <span style={{ color: '#7a4d00' }}>\n Requires Fluent UI v9 export — Power Pages / Canvas targets are blocked.\n </span>\n )}\n </div>\n </div>\n );\n};\n\n/**\n * Chart control types — the set the form-builder's `controlMetadata`\n * registry tags with `category === 'chart'`. Inlined here so the runtime\n * can ship `isChartControlType` without depending on the registry.\n *\n * TODO: when `controlMetadata.ts` (692 LOC) moves into form-runtime as\n * its own task, this list collapses into a registry-backed lookup.\n * Keep this in sync until then; the existing\n * `apps/form-builder/src/utils/controlMetadata.ts` is the upstream\n * source of truth.\n */\nconst CHART_CONTROL_TYPES: ReadonlySet<string> = new Set([\n 'barchart',\n 'linechart',\n 'areachart',\n 'piechart',\n 'donutchart',\n 'horizontalbarchart',\n 'gaugechart',\n 'sparkline',\n 'heatmapchart',\n 'kpicard',\n 'funnelchart',\n 'scatterchart',\n]);\n\n/** Test whether a control type belongs to the chart category. */\nexport function isChartControlType(type: ControlType | string): boolean {\n return CHART_CONTROL_TYPES.has(type);\n}\n","import React from 'react';\nimport type { ControlPartProps } from './types';\nimport { ChartRenderer, type ChartRendererEntry } from './internals/ChartRenderer';\n\n/**\n * Chart-category controls — `barchart`, `linechart`, `areachart`,\n * `piechart`, `donutchart`, `horizontalbarchart`, `gaugechart`,\n * `sparkline`, `heatmapchart`, `kpicard`, `funnelchart`, `scatterchart`.\n *\n * The dispatcher routes all 12 chart types here. `dataSourceLabelById`\n * and the registry-derived `entry` (icon/label/v9-required flag) flow\n * in via optional editor-supplied props; the runtime renders sensible\n * defaults when either is missing.\n *\n * Lifted from ControlRenderer.tsx cases 'barchart'…'scatterchart'.\n */\n\nexport interface ChartBranchProps extends ControlPartProps {\n /**\n * Optional editor-supplied lookup of data source id → display label.\n * The canvas / preview reads from `form.settings.dataSources`.\n */\n dataSourceLabelById?: Record<string, string>;\n /**\n * Optional editor-supplied registry slice (icon, label, requiresV9)\n * for this chart type. Forwarded as-is to `ChartRenderer`.\n */\n entry?: ChartRendererEntry;\n}\n\nexport const ChartBranch: React.FC<ChartBranchProps> = ({ control, dataSourceLabelById, entry }) => (\n <ChartRenderer control={control} dataSourceLabelById={dataSourceLabelById} entry={entry} />\n);\n","import React from 'react';\nimport { Persona, PersonaSize, PersonaPresence, type PersonaInitialsColor } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { getInitials, getPersonaColor } from '../shared/helpers';\n\n/**\n * `persona` control — renders a Fluent UI Persona from either:\n * - static configuration on `control.properties`, or\n * - a Dataverse-bound record (legacy systemUser* props normalized to\n * dvRecord* in the editor).\n *\n * Lifted from ControlRenderer.tsx case 'persona'.\n */\n\nconst SIZE_MAP: Record<string, PersonaSize> = {\n size24: PersonaSize.size24,\n size32: PersonaSize.size32,\n size40: PersonaSize.size40,\n size48: PersonaSize.size48,\n size56: PersonaSize.size56,\n size72: PersonaSize.size72,\n size100: PersonaSize.size100,\n size120: PersonaSize.size120,\n};\n\nconst PRESENCE_MAP: Record<string, PersonaPresence> = {\n none: PersonaPresence.none,\n online: PersonaPresence.online,\n away: PersonaPresence.away,\n busy: PersonaPresence.busy,\n dnd: PersonaPresence.dnd,\n offline: PersonaPresence.offline,\n blocked: PersonaPresence.blocked,\n};\n\nexport const PersonaControl: React.FC<ControlPartProps> = ({ control }) => {\n // Normalize legacy 'systemUser' → 'dataverse'.\n const rawSourceMode = (control.properties.personaSourceMode as string) || 'static';\n const sourceMode = rawSourceMode === 'systemUser' ? 'dataverse' : rawSourceMode;\n const personaSize = (control.properties.personaSize as string) || 'size48';\n const showPresence = (control.properties.showPresence as boolean) ?? false;\n const presenceOverride = (control.properties.presence as string) || 'none';\n const hideDetails = (control.properties.hideDetails as boolean) ?? false;\n const showSecondaryText = (control.properties.showSecondaryText as boolean) ?? true;\n\n let displayText: string;\n let displaySecondary: string;\n let displayImageUrl: string;\n let derivedPresence: PersonaPresence;\n\n if (sourceMode === 'dataverse') {\n const entityName = (control.properties.dvRecordEntityName as string) || 'systemuser';\n const recordId =\n (control.properties.dvRecordId as string) ||\n (control.properties.systemUserId as string) ||\n '';\n displayText =\n (control.properties.dvRecordName as string) ||\n (control.properties.systemUserName as string) ||\n 'Select a record...';\n displaySecondary =\n (control.properties.dvRecordSecondaryText as string) ||\n (control.properties.systemUserJobTitle as string) ||\n '';\n displayImageUrl =\n (control.properties.dvRecordImageDataUrl as string) ||\n (control.properties.systemUserImageDataUrl as string) ||\n '';\n\n if (presenceOverride !== 'none') {\n derivedPresence = PRESENCE_MAP[presenceOverride] ?? PersonaPresence.none;\n } else if (entityName === 'systemuser' && recordId) {\n const isDisabled =\n (control.properties.dvRecordIsDisabled as boolean) ??\n (control.properties.systemUserIsDisabled as boolean) ??\n false;\n derivedPresence = isDisabled ? PersonaPresence.offline : PersonaPresence.online;\n } else {\n derivedPresence = PersonaPresence.none;\n }\n } else {\n displayText = (control.properties.primaryText as string) || 'User Name';\n displaySecondary = (control.properties.secondaryText as string) || '';\n displayImageUrl = (control.properties.imageUrl as string) || '';\n derivedPresence = PRESENCE_MAP[presenceOverride] ?? PersonaPresence.none;\n }\n\n return (\n <Persona\n text={displayText}\n secondaryText={showSecondaryText ? displaySecondary : undefined}\n imageUrl={displayImageUrl || undefined}\n imageInitials={getInitials(displayText)}\n size={SIZE_MAP[personaSize] ?? PersonaSize.size48}\n initialsColor={getPersonaColor(displayText) as unknown as PersonaInitialsColor}\n presence={showPresence ? derivedPresence : PersonaPresence.none}\n hidePersonaDetails={hideDetails}\n showSecondaryText={showSecondaryText && !!displaySecondary}\n />\n );\n};\n","import type { ControlDefinition } from '../../types';\n\n/**\n * Pure helpers lifted from ControlRenderer.tsx for the v8 runtime.\n *\n * Every function here is data-in / data-out — no React, no stores, no\n * side effects. Callers in the editor (designer canvas) and at runtime\n * (generated host code) share these so behavior stays identical.\n */\n\n/**\n * Resolve the value to render for a bound control by reading from a\n * record-data object. Prefers Dataverse formatted-value annotations when\n * present (e.g. option-set labels instead of numeric codes) so the\n * runtime renders human-readable strings.\n *\n * Returns `undefined` when the control has no data binding or no record\n * is supplied — the caller should fall back to controlled/mock values.\n */\nexport function getBoundValue(\n control: ControlDefinition,\n recordData: Record<string, unknown> | null | undefined,\n): unknown {\n if (!recordData || !control.dataBinding?.attributeLogicalName) {\n return undefined;\n }\n const fieldName = control.dataBinding.attributeLogicalName;\n const formattedKey = `${fieldName}@OData.Community.Display.V1.FormattedValue`;\n if (formattedKey in recordData && recordData[formattedKey] !== undefined) {\n return recordData[formattedKey];\n }\n return recordData[fieldName];\n}\n\n/**\n * Convert a Dataverse logical field name to a display-friendly label.\n * e.g. \"ticketnumber\" → \"Ticket Number\", \"prioritycode\" → \"Priority\".\n *\n * Used wherever the runtime needs to surface a column header without\n * metadata being available (mock-data preview paths, fallback labels).\n */\nexport function toDisplayName(logicalName: string): string {\n let name = logicalName\n .replace(/id$/i, '')\n .replace(/code$/i, '')\n .replace(/name$/i, ' Name');\n\n const commonWords = [\n 'ticket', 'number', 'case', 'origin', 'customer', 'account', 'contact',\n 'created', 'modified', 'owner', 'status', 'state', 'reason', 'priority',\n 'email', 'address', 'phone', 'first', 'last', 'full', 'primary', 'secondary',\n 'billing', 'shipping', 'street', 'city', 'country', 'postal', 'zip',\n 'parent', 'child', 'type', 'category', 'description', 'subject', 'title',\n 'date', 'time', 'start', 'end', 'due', 'actual', 'estimated', 'scheduled',\n 'total', 'amount', 'quantity', 'price', 'discount', 'tax', 'revenue',\n 'service', 'product', 'order', 'invoice', 'quote', 'opportunity', 'lead',\n 'activity', 'task', 'appointment', 'call', 'meeting', 'note', 'annotation',\n ];\n\n for (const word of commonWords) {\n const regex = new RegExp(`(${word})(?=[a-z])`, 'gi');\n name = name.replace(regex, '$1 ');\n }\n\n name = name\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/([a-z])(\\d)/g, '$1 $2')\n .replace(/(\\d)([a-z])/gi, '$1 $2');\n\n return (\n name\n .split(/[\\s_-]+/)\n .filter((word) => word.length > 0)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ')\n .trim() || logicalName\n );\n}\n\nconst PERSONA_COLORS = [\n '#0078d4', '#00bcf2', '#008272', '#107c10',\n '#5c2d91', '#b4009e', '#e3008c', '#d83b01',\n '#ca5010', '#986f0b', '#498205', '#038387',\n];\n\n/** Two-letter initials from a name. Falls back to `?` for empty input. */\nexport function getInitials(name: string): string {\n if (!name) return '?';\n const words = name.trim().split(/\\s+/);\n if (words.length >= 2) {\n return (words[0][0] + words[1][0]).toUpperCase();\n }\n return words[0].substring(0, 2).toUpperCase();\n}\n\n/** Stable persona-tile color picked from a 12-color palette via name hash. */\nexport function getPersonaColor(name: string): string {\n let hash = 0;\n for (let i = 0; i < name.length; i++) {\n hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;\n }\n return PERSONA_COLORS[Math.abs(hash) % PERSONA_COLORS.length];\n}\n\n/**\n * Check if a web resource name matches embedded entity browser patterns.\n * Matches `kh_/entitybrowser`, `kh_entitybrowser`, `entitybrowser`, etc.\n */\nexport function isEmbeddedEntityBrowser(webResourceName: string): boolean {\n if (!webResourceName) return false;\n const normalized = webResourceName.toLowerCase().replace(/[_/]/g, '');\n return normalized.includes('entitybrowser');\n}\n","import React, { useState } from 'react';\nimport {\n ActionButton,\n CommandBar,\n CompoundButton,\n DefaultButton,\n IconButton as FluentIconButton,\n TooltipHost,\n type ICommandBarItemProps,\n type IContextualMenuProps,\n} from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport type {\n ButtonAction,\n ButtonCommandBarItem,\n ButtonMenuItem,\n ButtonSize,\n ButtonVariant,\n} from '../../types';\n\n/**\n * `button` control — variants: default, primary (legacy), compound,\n * icon, action, command (CommandBar), split (with menu), toggle.\n *\n * Lifted from ControlRenderer.tsx case 'button'. Each sub-variant\n * preserves its specific Fluent UI rendering. `onButtonClick(action)`\n * routes click events to the dispatcher's action handler — when\n * omitted (preview/no-op), clicks are inert. In design mode\n * (`!interactive`) the button is force-disabled and a small variant\n * badge renders in the top-right corner.\n */\nexport const ButtonControl: React.FC<ControlPartProps> = ({\n control,\n interactive,\n onButtonClick,\n}) => {\n const buttonVariant = (control.properties.buttonVariant as ButtonVariant) ?? 'default';\n const isPrimary = (control.properties.primary as boolean) ?? buttonVariant === 'primary';\n const buttonText = (control.properties.buttonText as string) ?? control.label ?? 'Button';\n const buttonAction = (control.properties.buttonAction as ButtonAction) ?? { type: 'none' };\n const iconName = control.properties.iconName as string | undefined;\n const iconPosition = (control.properties.iconPosition as string) ?? 'before';\n const buttonSize = (control.properties.size as ButtonSize) ?? 'medium';\n const fullWidth = (control.properties.fullWidth as boolean) ?? false;\n const alignment = (control.properties.alignment as string) ?? 'left';\n const buttonDisabled = (control.properties.disabled as boolean) ?? false;\n const tooltip = control.properties.tooltip as string | undefined;\n const secondaryText = control.properties.secondaryText as string | undefined;\n const iconOnly = (control.properties.iconOnly as boolean) ?? false;\n const backgroundColor = control.properties.backgroundColor as string | undefined;\n const textColor = control.properties.textColor as string | undefined;\n const iconColor = control.properties.iconColor as string | undefined;\n const menuItems = control.properties.menuItems as ButtonMenuItem[] | undefined;\n const commandBarItems = control.properties.commandBarItems as ButtonCommandBarItem[] | undefined;\n const commandBarIconOnly = (control.properties.commandBarIconOnly as boolean) ?? false;\n const commandBarMainPosition = (control.properties.commandBarMainPosition as number) ?? 0;\n const checkedText = control.properties.checkedText as string | undefined;\n const uncheckedText = control.properties.uncheckedText as string | undefined;\n const checkedIconName = control.properties.checkedIconName as string | undefined;\n const checkedBackgroundColor = control.properties.checkedBackgroundColor as string | undefined;\n const checkedTextColor = control.properties.checkedTextColor as string | undefined;\n const checkedIconColor = control.properties.checkedIconColor as string | undefined;\n\n const designMode = !interactive;\n const [toggleChecked, setToggleChecked] = useState(false);\n\n const sizeHeightMap: Record<ButtonSize, number> = { small: 24, medium: 32, large: 40 };\n const btnHeight = sizeHeightMap[buttonSize] ?? 32;\n\n const handleClick = () => {\n if (designMode || !onButtonClick) return;\n onButtonClick(buttonAction);\n };\n\n const iconProps = iconName ? { iconName } : undefined;\n const resolvedIconColor = iconColor || textColor;\n const displayText = iconOnly && iconName ? undefined : buttonText;\n\n const customStyles = {\n root: {\n height: btnHeight,\n minWidth: buttonSize === 'small' ? 60 : undefined,\n ...(fullWidth && { width: '100%' }),\n ...(backgroundColor && { backgroundColor, borderColor: backgroundColor }),\n ...(textColor && { color: textColor }),\n },\n flexContainer: {\n ...(iconPosition === 'after' && { flexDirection: 'row-reverse' as const }),\n },\n label: {\n ...(textColor && { color: textColor }),\n ...(iconOnly && iconName && { display: 'none' }),\n },\n icon: {\n ...(resolvedIconColor && { color: resolvedIconColor }),\n },\n };\n\n const menuProps: IContextualMenuProps | undefined =\n (buttonVariant === 'split' || buttonVariant === 'command') && menuItems && menuItems.length > 0\n ? {\n items: menuItems.map((mi) => ({\n key: mi.id,\n text: mi.text,\n iconProps: mi.iconName ? { iconName: mi.iconName } : undefined,\n onClick: () => {\n if (!designMode && onButtonClick) {\n onButtonClick(mi.action);\n }\n },\n })),\n }\n : undefined;\n\n const justifyMap: Record<string, string> = {\n left: 'flex-start',\n center: 'center',\n right: 'flex-end',\n };\n\n // Untyped — `React.CSSProperties` would force the form-runtime's\n // bundled `csstype` instance into the caller's tree (see grid cell\n // renderers note). The spread into `<div style={...}>` casts via the\n // consumer's CSSProperties.\n const wrapperStyle = {\n display: 'flex',\n justifyContent: fullWidth ? 'stretch' : justifyMap[alignment] ?? 'flex-start',\n padding: '4px 0',\n position: 'relative',\n } as const;\n\n const renderButton = () => {\n switch (buttonVariant) {\n case 'primary':\n return (\n <DefaultButton\n text={displayText}\n iconProps={iconProps}\n onClick={handleClick}\n disabled={designMode || buttonDisabled}\n styles={customStyles}\n primary\n />\n );\n case 'compound':\n return (\n <CompoundButton\n text={displayText ?? buttonText}\n secondaryText={secondaryText || 'Description'}\n iconProps={iconProps}\n onClick={handleClick}\n disabled={designMode || buttonDisabled}\n styles={customStyles}\n primary={isPrimary}\n />\n );\n case 'icon':\n return (\n <FluentIconButton\n iconProps={iconProps || { iconName: 'Add' }}\n title={buttonText}\n ariaLabel={buttonText}\n onClick={handleClick}\n disabled={designMode || buttonDisabled}\n styles={{\n root: {\n height: btnHeight,\n width: btnHeight,\n ...(backgroundColor && { backgroundColor, borderColor: backgroundColor }),\n },\n icon: {\n ...(resolvedIconColor && { color: resolvedIconColor }),\n },\n }}\n />\n );\n case 'action':\n return (\n <ActionButton\n text={displayText}\n iconProps={iconProps}\n onClick={handleClick}\n disabled={designMode || buttonDisabled}\n styles={customStyles}\n />\n );\n case 'command': {\n const cmdButtonStyles = {\n root: {\n height: btnHeight,\n ...(backgroundColor && { backgroundColor, borderColor: backgroundColor }),\n ...(textColor && { color: textColor }),\n },\n label: {\n ...(textColor && { color: textColor }),\n },\n icon: {\n ...(resolvedIconColor && { color: resolvedIconColor }),\n },\n menuIcon: {\n ...(textColor && { color: textColor }),\n },\n };\n\n const mainButtonItem: ICommandBarItemProps = {\n key: 'main',\n text: displayText,\n iconProps: iconProps,\n iconOnly: iconOnly && !!iconName,\n ariaLabel: buttonText,\n onClick: handleClick,\n disabled: designMode || buttonDisabled,\n buttonStyles: cmdButtonStyles,\n subMenuProps: menuProps,\n };\n\n const additionalItems: ICommandBarItemProps[] = [];\n if (commandBarItems && commandBarItems.length > 0) {\n commandBarItems.forEach((cbi) => {\n const cbiSubMenuProps: IContextualMenuProps | undefined =\n cbi.subMenuItems && cbi.subMenuItems.length > 0\n ? {\n items: cbi.subMenuItems.map((sub) => ({\n key: sub.id,\n text: sub.text,\n iconProps: sub.iconName ? { iconName: sub.iconName } : undefined,\n onClick: () => {\n if (!designMode && onButtonClick) {\n onButtonClick(sub.action);\n }\n },\n })),\n }\n : undefined;\n\n const cbiIconOnly =\n (cbi.iconOnly !== undefined ? cbi.iconOnly : commandBarIconOnly) && !!cbi.iconName;\n\n additionalItems.push({\n key: cbi.id,\n text: cbiIconOnly ? undefined : cbi.text,\n iconProps: cbi.iconName ? { iconName: cbi.iconName } : undefined,\n iconOnly: cbiIconOnly,\n ariaLabel: cbi.text,\n disabled: designMode || buttonDisabled,\n buttonStyles: cmdButtonStyles,\n onClick: () => {\n if (!designMode && onButtonClick) {\n onButtonClick(cbi.action);\n }\n },\n subMenuProps: cbiSubMenuProps,\n });\n });\n }\n\n const cmdItems = [...additionalItems];\n const insertPos = Math.min(Math.max(commandBarMainPosition, 0), cmdItems.length);\n cmdItems.splice(insertPos, 0, mainButtonItem);\n\n return (\n <CommandBar\n items={cmdItems}\n styles={{\n root: {\n padding: 0,\n height: btnHeight,\n ...(fullWidth && { width: '100%' }),\n ...(backgroundColor && { backgroundColor }),\n },\n }}\n />\n );\n }\n case 'split':\n return (\n <DefaultButton\n text={displayText}\n iconProps={iconProps}\n onClick={handleClick}\n disabled={designMode || buttonDisabled}\n styles={customStyles}\n split\n primary={isPrimary}\n menuProps={menuProps || { items: [] }}\n />\n );\n case 'toggle': {\n const toggleText = toggleChecked\n ? checkedText || displayText\n : uncheckedText || displayText;\n const toggleIconProps =\n toggleChecked && checkedIconName ? { iconName: checkedIconName } : iconProps;\n const effectiveToggleIconOnly = iconOnly && !!(toggleIconProps?.iconName || iconName);\n\n const toggleBg =\n toggleChecked && checkedBackgroundColor ? checkedBackgroundColor : backgroundColor;\n const toggleTextCol =\n toggleChecked && checkedTextColor ? checkedTextColor : textColor;\n const toggleIconCol = toggleChecked\n ? checkedIconColor || checkedTextColor || resolvedIconColor\n : resolvedIconColor;\n\n const toggleStyles = {\n root: {\n height: btnHeight,\n minWidth: buttonSize === 'small' ? 60 : undefined,\n ...(fullWidth && { width: '100%' }),\n ...(toggleBg && { backgroundColor: toggleBg, borderColor: toggleBg }),\n ...(toggleTextCol && { color: toggleTextCol }),\n },\n flexContainer: {\n ...(iconPosition === 'after' && { flexDirection: 'row-reverse' as const }),\n },\n rootChecked: {\n ...(checkedBackgroundColor && {\n backgroundColor: checkedBackgroundColor,\n borderColor: checkedBackgroundColor,\n }),\n ...(checkedTextColor && { color: checkedTextColor }),\n },\n rootCheckedHovered: {\n ...(checkedBackgroundColor && {\n backgroundColor: checkedBackgroundColor,\n borderColor: checkedBackgroundColor,\n }),\n ...(checkedTextColor && { color: checkedTextColor }),\n },\n label: {\n ...(toggleTextCol && { color: toggleTextCol }),\n ...(effectiveToggleIconOnly && { display: 'none' }),\n },\n icon: {\n ...(toggleIconCol && { color: toggleIconCol }),\n },\n };\n\n return (\n <DefaultButton\n text={effectiveToggleIconOnly ? undefined : toggleText}\n iconProps={toggleIconProps}\n onClick={() => {\n setToggleChecked(!toggleChecked);\n handleClick();\n }}\n disabled={designMode || buttonDisabled}\n styles={toggleStyles}\n toggle\n checked={toggleChecked}\n primary={isPrimary}\n />\n );\n }\n default:\n return (\n <DefaultButton\n text={displayText}\n iconProps={iconProps}\n onClick={handleClick}\n disabled={designMode || buttonDisabled}\n styles={customStyles}\n primary={isPrimary}\n />\n );\n }\n };\n\n const buttonElement = tooltip ? (\n <TooltipHost content={tooltip}>{renderButton()}</TooltipHost>\n ) : (\n renderButton()\n );\n\n return (\n <div style={wrapperStyle}>\n {buttonElement}\n {designMode && (\n <span\n style={{\n position: 'absolute',\n top: 0,\n right: 0,\n fontSize: 9,\n padding: '1px 4px',\n backgroundColor: '#deecf9',\n color: '#0078d4',\n borderRadius: 2,\n pointerEvents: 'none',\n }}\n >\n {buttonVariant}\n </span>\n )}\n </div>\n );\n};\n","import React, { useMemo } from 'react';\nimport {\n DetailsList,\n DetailsListLayoutMode,\n SelectionMode,\n Icon,\n Spinner,\n SpinnerSize,\n type IColumn,\n} from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport type { SubgridColumn } from '../../types';\nimport { useLiveData } from '../../hooks';\n\n/**\n * `subgrid` control — standard mode renderer. The editor's branch\n * additionally handles focused-view layouts, card-list views,\n * grid-customizer integration, and mock-data fallbacks; those stay\n * inline in `ControlRenderer.tsx` and migrate in a follow-up — the\n * runtime focus here is the deployed-runtime path: a Fluent v8\n * `DetailsList` rendered from records fetched via `fetchLiveData`.\n *\n * Lifted (partial) from ControlRenderer.tsx case 'subgrid'.\n */\n\nexport interface SubgridBranchProps extends ControlPartProps {\n /**\n * Optional pre-fetched records. When omitted, the runtime calls\n * `useLiveData(control)` to source records from the surrounding\n * `FormRuntimeContext`. The editor passes mock data via this prop\n * during designer-time rendering.\n */\n records?: Record<string, unknown>[];\n /**\n * Optional column override. Falls back to\n * `control.properties.columns` (the legacy inline definition).\n */\n columns?: SubgridColumn[];\n}\n\nexport const SubgridBranch: React.FC<SubgridBranchProps> = ({\n control,\n records: recordsProp,\n columns: columnsProp,\n}) => {\n const declaredColumns: SubgridColumn[] =\n columnsProp ?? ((control.properties.columns as SubgridColumn[]) ?? []);\n const entityName = (control.properties.entityName as string) || '';\n const maxRows = (control.properties.maxRows as number) ?? 5;\n\n // Skip the live-data fetch when records were passed in (designer mock).\n const skipFetch = recordsProp !== undefined;\n const { records: liveRecords, loading, error } = useLiveData(control, !skipFetch);\n const records = recordsProp ?? liveRecords ?? [];\n\n const detailsListColumns: IColumn[] = useMemo(\n () =>\n declaredColumns.map((col) => ({\n key: col.key,\n name: col.name || col.fieldName,\n fieldName: col.fieldName,\n minWidth: col.minWidth ?? 80,\n maxWidth: col.maxWidth ?? (col.minWidth ?? 80) * 2,\n isResizable: col.isResizable ?? true,\n })),\n [declaredColumns],\n );\n\n return (\n <div style={{ border: '1px solid #edebe9', borderRadius: 2, overflow: 'hidden', backgroundColor: '#fff' }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n padding: '6px 12px',\n borderBottom: '1px solid #edebe9',\n backgroundColor: '#faf9f8',\n gap: 8,\n }}\n >\n <Icon iconName=\"GridViewSmall\" styles={{ root: { fontSize: 14, color: '#0078d4' } }} />\n <span style={{ fontSize: 12, fontWeight: 600, color: '#323130' }}>{entityName || 'Subgrid'}</span>\n {!skipFetch && liveRecords !== null && liveRecords.length > 0 && (\n <span\n style={{\n fontSize: 10,\n color: '#107c10',\n backgroundColor: '#dff6dd',\n padding: '2px 6px',\n borderRadius: 2,\n }}\n >\n Live\n </span>\n )}\n <span style={{ marginLeft: 'auto', fontSize: 11, color: '#605e5c' }}>Max: {maxRows}</span>\n </div>\n\n {loading && (\n <div style={{ padding: 16, textAlign: 'center' }}>\n <Spinner size={SpinnerSize.small} label=\"Loading records...\" labelPosition=\"right\" />\n </div>\n )}\n\n {error && !loading && (\n <div\n style={{\n padding: 12,\n backgroundColor: '#fef0f0',\n color: '#a80000',\n fontSize: 12,\n borderBottom: '1px solid #edebe9',\n }}\n >\n <Icon iconName=\"Warning\" styles={{ root: { marginRight: 6, verticalAlign: 'middle' } }} />\n {error}\n </div>\n )}\n\n {!loading && !error && (\n <div style={{ maxHeight: Math.max(200, maxRows * 36), overflow: 'auto' }}>\n {records.length === 0 || detailsListColumns.length === 0 ? (\n <div style={{ padding: 24, textAlign: 'center', color: '#605e5c', fontSize: 12 }}>\n {detailsListColumns.length === 0 ? 'No columns configured' : 'No records'}\n </div>\n ) : (\n <DetailsList\n items={records}\n columns={detailsListColumns}\n layoutMode={DetailsListLayoutMode.justified}\n selectionMode={SelectionMode.none}\n compact\n isHeaderVisible\n />\n )}\n </div>\n )}\n </div>\n );\n};\n","// @dataverse-kit/form-runtime/hooks — FluentUI-agnostic React hooks.\n//\n// Today: `useLiveData` — wraps `FormRuntimeCapabilities.fetchLiveData`\n// with React-state choreography (loading / error / records /\n// timelineItems / fetchXmlAttributes). Used by the runtime's subgrid\n// and timeline per-type branches.\n//\n// Planned: useSubgridData, useChartData, useLookupSearch, useFormState,\n// useDirtyTracker (scaffolds; populated when their consumers move into\n// form-runtime).\n\nimport { useEffect, useState } from 'react';\nimport type { ControlDefinition } from './types';\nimport type { LiveDataResult, TimelineItem } from './types/runtime-capabilities';\nimport { useOptionalFormRuntimeContext } from './context/FormRuntimeContext';\n\nexport interface UseLiveDataResult {\n records: Record<string, unknown>[] | null;\n loading: boolean;\n error: string | null;\n fetchXmlAttributes: string[];\n timelineItems: TimelineItem[] | null;\n}\n\n/**\n * Subscribe to live records / timeline activities for a bound control.\n * Calls `FormRuntimeCapabilities.fetchLiveData` on mount + whenever the\n * control reference changes. Returns the empty/no-context shape when no\n * provider wraps the caller (the deployed runtime is expected to wrap;\n * tests can use the un-wrapped shape).\n *\n * The capability returns raw data; this hook adds the React state\n * machinery (loading flag, error string, abort on unmount).\n */\nexport function useLiveData(control: ControlDefinition, enabled: boolean = true): UseLiveDataResult {\n const ctx = useOptionalFormRuntimeContext();\n const [records, setRecords] = useState<Record<string, unknown>[] | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [fetchXmlAttributes, setFetchXmlAttributes] = useState<string[]>([]);\n const [timelineItems, setTimelineItems] = useState<TimelineItem[] | null>(null);\n\n // The hook fires on stable primitive deps only — `control` and `ctx`\n // are referentially unstable each render (FormRuntime walks the tree;\n // capabilities memo rebuilds when callbacks change), and depending on\n // them caused an abort/refetch loop. The fetcher reference, control\n // identity, and a hash of the properties that affect the query are\n // what actually matter; everything else is a noisy false positive.\n const fetchLiveData = ctx?.fetchLiveData;\n const propertiesKey = JSON.stringify(control.properties ?? {});\n const dataBindingKey = JSON.stringify(control.dataBinding ?? {});\n\n useEffect(() => {\n if (!enabled || !fetchLiveData) {\n setRecords(null);\n setLoading(false);\n setError(null);\n setTimelineItems(null);\n setFetchXmlAttributes([]);\n return;\n }\n\n let cancelled = false;\n const controller = new AbortController();\n setLoading(true);\n setError(null);\n\n fetchLiveData(control, { signal: controller.signal })\n .then((data: LiveDataResult) => {\n if (cancelled) return;\n setRecords(data.records);\n setFetchXmlAttributes(data.fetchXmlAttributes);\n setTimelineItems(data.timelineItems);\n setLoading(false);\n })\n .catch((err: unknown) => {\n if (cancelled) return;\n setError(err instanceof Error ? err.message : 'Failed to fetch live data');\n setRecords(null);\n setTimelineItems(null);\n setLoading(false);\n });\n\n return () => {\n cancelled = true;\n controller.abort();\n };\n // `control` is read once per fetch call but isn't a dep — its\n // identity churns each parent render. The `*Key` strings cover\n // the actual inputs the capability reads from `control`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetchLiveData, enabled, control.type, control.name, propertiesKey, dataBindingKey]);\n\n return { records, loading, error, fetchXmlAttributes, timelineItems };\n}\n","import React, { useMemo } from 'react';\nimport { Icon, Spinner, SpinnerSize } from '@fluentui/react';\nimport type { ControlPartProps } from './types';\nimport { useLiveData } from '../../hooks';\nimport { useOptionalFormRuntimeContext } from '../../context/FormRuntimeContext';\nimport type { TimelineItem } from '../../types/runtime-capabilities';\n\n/**\n * `timeline` control — chronological list of activitypointer records\n * (email / phonecall / task / note / appointment).\n *\n * Lifted from ControlRenderer.tsx case 'timeline'. The runtime sources\n * its data via `useLiveData(control)` — the editor's\n * `EditorFormRuntimeProvider` wires `fetchLiveData` against the live\n * Dataverse client; deployed host code wires it against `IApiService`.\n *\n * Designer-time mock data: 20 representative activities filtered by\n * the per-type toggles. When `interactive=false` (designer) the mock\n * data acts as a placeholder; when `interactive=true` and live data\n * arrives, the runtime swaps to live.\n */\n\nconst ALL_MOCK_ACTIVITIES: Array<TimelineItem & { timestamp: number }> = [\n { id: 'mock-1', type: 'email', icon: 'Mail', title: 'Email sent', description: 'Re: Follow up on proposal', time: '2 hours ago', color: '#0078d4', createdon: new Date(), timestamp: 19 },\n { id: 'mock-2', type: 'phonecall', icon: 'Phone', title: 'Phone call', description: 'Discussed pricing options', time: 'Yesterday', color: '#107c10', createdon: new Date(), timestamp: 18 },\n { id: 'mock-3', type: 'task', icon: 'TaskSolid', title: 'Task completed', description: 'Send product brochure', time: '3 days ago', color: '#8764b8', createdon: new Date(), timestamp: 17 },\n { id: 'mock-4', type: 'note', icon: 'QuickNote', title: 'Note added', description: 'Customer interested in premium plan', time: '1 week ago', color: '#ca5010', createdon: new Date(), timestamp: 16 },\n { id: 'mock-5', type: 'appointment', icon: 'Calendar', title: 'Appointment scheduled', description: 'Demo meeting with stakeholders', time: '2 weeks ago', color: '#038387', createdon: new Date(), timestamp: 15 },\n];\n\nexport const TimelineControl: React.FC<ControlPartProps> = ({ control, interactive }) => {\n const maxActivities = (control.properties.maxActivities as number) ?? 4;\n const showEmail = (control.properties.showEmail as boolean) ?? true;\n const showPhoneCall = (control.properties.showPhoneCall as boolean) ?? true;\n const showTask = (control.properties.showTask as boolean) ?? true;\n const showNote = (control.properties.showNote as boolean) ?? true;\n const showAppointment = (control.properties.showAppointment as boolean) ?? true;\n const sortOrder = (control.properties.sortOrder as string) ?? 'newest';\n\n // Only attempt to fetch activities when there's a preview record to\n // anchor against — the editor adapter throws \"Select a preview record\"\n // otherwise, and the deployed runtime can't resolve placeholders\n // without one. Falls through to the mock-activities path while empty.\n const ctx = useOptionalFormRuntimeContext();\n const hasPreviewRecord = !!ctx?.previewContext?.recordId;\n const { timelineItems, loading, error } = useLiveData(control, hasPreviewRecord);\n const useLiveDataMode = !!(timelineItems && timelineItems.length > 0);\n const isLoading = loading;\n\n const filteredMockActivities = useMemo(\n () =>\n ALL_MOCK_ACTIVITIES.filter((activity) => {\n switch (activity.type) {\n case 'email':\n return showEmail;\n case 'phonecall':\n return showPhoneCall;\n case 'task':\n return showTask;\n case 'note':\n return showNote;\n case 'appointment':\n return showAppointment;\n default:\n return true;\n }\n }),\n [showEmail, showPhoneCall, showTask, showNote, showAppointment],\n );\n\n const sortedMockActivities = useMemo(\n () =>\n [...filteredMockActivities].sort((a, b) =>\n sortOrder === 'newest' ? b.timestamp - a.timestamp : a.timestamp - b.timestamp,\n ),\n [filteredMockActivities, sortOrder],\n );\n\n const mockDisplayActivities = sortedMockActivities.slice(0, maxActivities);\n const displayActivities: TimelineItem[] = useLiveDataMode ? timelineItems! : mockDisplayActivities;\n const activeFilters = [showEmail, showPhoneCall, showTask, showNote, showAppointment].filter(Boolean).length;\n void interactive;\n\n return (\n <div style={{ border: '1px solid #edebe9', borderRadius: 2, overflow: 'hidden', backgroundColor: '#fff' }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 12px',\n borderBottom: '1px solid #edebe9',\n backgroundColor: '#faf9f8',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <Icon iconName=\"TimelineProgress\" styles={{ root: { fontSize: 14, color: '#0078d4' } }} />\n <span style={{ fontSize: 13, fontWeight: 600, color: '#323130' }}>Timeline</span>\n {(useLiveDataMode || isLoading) && (\n <span\n style={{\n fontSize: 10,\n color: '#107c10',\n backgroundColor: '#dff6dd',\n padding: '2px 6px',\n borderRadius: 2,\n }}\n >\n Live\n </span>\n )}\n {activeFilters < 5 && (\n <span\n style={{\n fontSize: 10,\n color: '#605e5c',\n backgroundColor: '#f3f2f1',\n padding: '2px 6px',\n borderRadius: 2,\n }}\n >\n {activeFilters} of 5 types\n </span>\n )}\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{ fontSize: 10, color: '#a19f9d' }}>\n {sortOrder === 'newest' ? '↓ Newest' : '↑ Oldest'}\n </span>\n </div>\n </div>\n\n {isLoading && (\n <div style={{ padding: 16, textAlign: 'center', backgroundColor: '#faf9f8' }}>\n <Spinner size={SpinnerSize.small} label=\"Loading activities...\" labelPosition=\"right\" />\n </div>\n )}\n\n {error && !isLoading && (\n <div\n style={{\n padding: 12,\n backgroundColor: error.includes('Select a preview record') ? '#deecf9' : '#fef0f0',\n color: error.includes('Select a preview record') ? '#0078d4' : '#a80000',\n fontSize: 12,\n borderBottom: '1px solid #edebe9',\n }}\n >\n <Icon\n iconName={error.includes('Select a preview record') ? 'Info' : 'Warning'}\n styles={{ root: { marginRight: 6, verticalAlign: 'middle' } }}\n />\n {error}\n </div>\n )}\n\n {!isLoading && (\n <div style={{ maxHeight: Math.max(200, maxActivities * 52), overflowY: 'auto' }}>\n {displayActivities.length === 0 ? (\n <div style={{ padding: 24, textAlign: 'center', color: '#605e5c', fontSize: 12 }}>\n <Icon\n iconName={useLiveDataMode ? 'TimelineProgress' : 'Filter'}\n styles={{ root: { fontSize: 24, color: '#a19f9d', marginBottom: 8 } }}\n />\n <div>{useLiveDataMode ? 'No activities found for this record' : 'No activities to display'}</div>\n </div>\n ) : (\n displayActivities.map((activity, idx) => (\n <div\n key={activity.id || idx}\n style={{\n display: 'flex',\n padding: '10px 12px',\n borderBottom: idx < displayActivities.length - 1 ? '1px solid #edebe9' : 'none',\n gap: 10,\n }}\n >\n <div\n style={{\n width: 32,\n height: 32,\n borderRadius: '50%',\n backgroundColor: activity.color,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n >\n <Icon iconName={activity.icon} styles={{ root: { fontSize: 14, color: '#fff' } }} />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 13, fontWeight: 600, color: '#323130' }}>{activity.title}</div>\n <div\n style={{\n fontSize: 12,\n color: '#605e5c',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {activity.description}\n </div>\n </div>\n <div style={{ fontSize: 11, color: '#a19f9d', whiteSpace: 'nowrap' }}>{activity.time}</div>\n </div>\n ))\n )}\n </div>\n )}\n\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '6px 12px',\n borderTop: '1px solid #edebe9',\n backgroundColor: '#faf9f8',\n fontSize: 11,\n color: '#605e5c',\n }}\n >\n {isLoading ? (\n <span>Loading...</span>\n ) : (\n <span>\n {useLiveDataMode\n ? `Showing ${displayActivities.length} activities`\n : `Showing ${displayActivities.length} of ${filteredMockActivities.length}`}\n </span>\n )}\n <span>Max: {maxActivities}</span>\n </div>\n </div>\n );\n};\n","/**\n * NestedRecordsSidePanel\n *\n * Side-panel host for a nested grid's child records. Used when a parent grid's\n * `nestedDisplay.mode` is `'side-panel'` — the parent surface (focused-view\n * detail pane, card-list card, or any explicit \"View related\" trigger) opens\n * this panel with the selected parent row's children.\n *\n * Renders the child grid as a Fluent UI v8 DetailsList using mock data sized\n * to the configured page. The export generators emit a near-identical Panel\n * + DetailsList runtime so the designer preview matches the deployed UX.\n *\n * Moved from apps/form-builder/src/components/grid-customizer/preview/ in\n * Phase 6.5c. The mock-data generator is injected via the optional\n * `generateMockData` prop rather than imported from\n * `@dataverse-kit/export-engine` — keeps the runtime independent of the\n * editor-only export-engine package. When the prop is omitted (e.g. in a\n * deployed runtime), the panel renders zero rows.\n */\n\nimport React, { useMemo } from 'react';\nimport {\n Panel,\n PanelType,\n DetailsList,\n DetailsListLayoutMode,\n SelectionMode,\n IColumn,\n Stack,\n Text,\n DefaultButton,\n mergeStyles,\n} from '@fluentui/react';\nimport type {\n GridCustomizerDefinition,\n NestedSidePanelSize,\n} from '../../../types/gridCustomizer';\nimport { renderGridCell, type GridMockDataGenerator } from '../../shared/gridCellRenderers';\n\nconst PANEL_TYPE_BY_SIZE: Record<NestedSidePanelSize, PanelType> = {\n small: PanelType.smallFixedFar,\n medium: PanelType.medium,\n large: PanelType.large,\n};\n\nconst headerSubtitleClass = mergeStyles({\n fontSize: 12,\n color: '#605e5c',\n marginTop: 2,\n});\n\nconst emptyStateClass = mergeStyles({\n padding: 24,\n textAlign: 'center',\n color: '#605e5c',\n});\n\nexport interface NestedRecordsSidePanelProps {\n /** Whether the panel is open. */\n isOpen: boolean;\n /** Close handler. */\n onDismiss: () => void;\n /** The child grid definition whose rows should render in the panel. */\n childGridDef: GridCustomizerDefinition | null;\n /**\n * Display name of the parent row (e.g. \"Acme Corp\"). Surfaced in the panel\n * header so the user knows which parent these children belong to.\n */\n parentLabel?: string;\n /** Panel size. Defaults to 'medium'. */\n panelSize?: NestedSidePanelSize;\n /**\n * Optional override for how many child rows to render. Falls back to the\n * child grid's `pageSize` so the side-panel preview matches the embedded\n * grid by default.\n */\n rowCount?: number;\n /**\n * Optional mock-data generator. When provided (typically by the editor's\n * shim wrapper), the panel renders a mocked DetailsList for preview. When\n * omitted, the panel renders zero rows.\n */\n generateMockData?: GridMockDataGenerator;\n}\n\nexport const NestedRecordsSidePanel: React.FC<NestedRecordsSidePanelProps> = ({\n isOpen,\n onDismiss,\n childGridDef,\n parentLabel,\n panelSize = 'medium',\n rowCount,\n generateMockData,\n}) => {\n const visibleColumns = useMemo(() => {\n if (!childGridDef) return [];\n return [...childGridDef.columns]\n .filter((c) => c.isVisible)\n .sort((a, b) => a.order - b.order);\n }, [childGridDef]);\n\n const items = useMemo(() => {\n if (!childGridDef || !generateMockData) return [];\n const count = rowCount ?? childGridDef.pageSize ?? 5;\n return generateMockData(visibleColumns, count);\n }, [childGridDef, rowCount, visibleColumns, generateMockData]);\n\n const detailsListColumns: IColumn[] = useMemo(\n () =>\n visibleColumns.map((col) => ({\n key: col.id,\n name: col.displayName || col.fieldName,\n fieldName: col.fieldName,\n minWidth: col.minWidth ?? 50,\n maxWidth: col.maxWidth ?? 200,\n isResizable: true,\n onRender: (item: Record<string, unknown>) => (\n <>{renderGridCell(item[col.fieldName], col)}</>\n ),\n })),\n [visibleColumns],\n );\n\n const headerText = childGridDef?.name ?? 'Related records';\n\n return (\n <Panel\n isOpen={isOpen}\n onDismiss={onDismiss}\n type={PANEL_TYPE_BY_SIZE[panelSize] ?? PanelType.medium}\n headerText={headerText}\n closeButtonAriaLabel=\"Close\"\n isLightDismiss\n onRenderHeader={() => (\n <Stack tokens={{ childrenGap: 2 }} styles={{ root: { padding: '12px 24px 0 24px' } }}>\n <Text variant=\"xLarge\" styles={{ root: { fontWeight: 600 } }}>\n {headerText}\n </Text>\n {parentLabel ? (\n <span className={headerSubtitleClass}>for {parentLabel}</span>\n ) : null}\n </Stack>\n )}\n onRenderFooterContent={() => (\n <Stack horizontal horizontalAlign=\"end\" tokens={{ childrenGap: 8 }}>\n <DefaultButton onClick={onDismiss}>Close</DefaultButton>\n </Stack>\n )}\n isFooterAtBottom\n >\n {!childGridDef ? (\n <div className={emptyStateClass}>\n No related grid is configured for this row.\n </div>\n ) : visibleColumns.length === 0 ? (\n <div className={emptyStateClass}>\n The related grid has no visible columns.\n </div>\n ) : (\n <DetailsList\n items={items}\n columns={detailsListColumns}\n layoutMode={DetailsListLayoutMode.justified}\n selectionMode={SelectionMode.multiple}\n compact={childGridDef.compactMode}\n isHeaderVisible\n />\n )}\n </Panel>\n );\n};\n","/**\n * Grid Cell Renderers\n *\n * Shared cell renderer functions for grid customizer preview.\n * Used by GridPreview (grid customizer mode) and ControlRenderer (form canvas subgrids).\n * All renderers use Fluent UI v8.\n *\n * Moved from apps/form-builder/src/utils/gridCellRenderers.tsx in Phase 6.5c.\n * The form-builder file is now a thin re-export shim.\n */\n\nimport React from 'react';\nimport {\n ProgressIndicator,\n Rating,\n RatingSize,\n Icon,\n Link,\n Toggle,\n} from '@fluentui/react';\nimport type { GridColumnDefinition, CompositeRendererConfig, CompositeSlot, ConditionalStyle } from '../../types/gridCustomizer';\n\nfunction renderStatusBadge(value: unknown, config: Record<string, unknown>): React.ReactNode {\n if (value == null) return <span style={{ color: '#a19f9d' }}>-</span>;\n const displayMode = (config.displayMode as string) || 'box';\n const iconOnly = config.iconOnly === true;\n let label: string;\n let color: string;\n let icon: string | undefined;\n let optionKey: unknown;\n\n if (typeof value === 'object' && value !== null && 'label' in value) {\n const opt = value as { value?: unknown; label: string; color: string; icon?: string };\n label = opt.label;\n color = opt.color || '#605e5c';\n icon = opt.icon;\n optionKey = opt.value;\n } else {\n label = String(value);\n color = '#605e5c';\n optionKey = value;\n }\n\n // Look up the matching configured option to pick up its icon. The cell\n // value is a snapshot from when the row was generated and may not include\n // an icon even when the column has been configured with one — fall back to\n // the option mapping by value (or by label) so the rendered badge stays in\n // sync with the column config.\n if (!icon) {\n const cfgOptions = (config.options as Array<{ value: unknown; label?: string; icon?: string }> | undefined) ?? [];\n const matched = cfgOptions.find(\n (o) => String(o.value) === String(optionKey) || (o.label && o.label === label),\n );\n if (matched?.icon) icon = matched.icon;\n }\n\n // When the column is set to icon-only and the value resolves to an icon,\n // hide the label and use it as the tooltip instead. If no icon resolved we\n // still show the label so the cell never goes blank.\n const labelHidden = iconOnly && !!icon;\n\n // Untyped — `React.CSSProperties` would force the form-runtime's\n // bundled `csstype` instance into the caller's tree, and form-builder\n // hoists its own copy. The JSX call sites cast to the consumer's\n // CSSProperties via the `style={{ ...baseStyle, ... }}` spread.\n const baseStyle = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: labelHidden ? 0 : 4,\n padding: labelHidden ? '2px 4px' : '2px 8px',\n borderRadius: 3,\n fontSize: 12,\n lineHeight: '18px',\n fontWeight: 500,\n } as const;\n\n const iconNode = icon ? (\n <Icon iconName={icon} styles={{ root: { fontSize: labelHidden ? 14 : 12 } }} />\n ) : null;\n const labelNode = labelHidden ? null : <span>{label}</span>;\n // Tooltip carries the label when it's hidden so the cell stays accessible.\n const titleAttr = labelHidden ? label : undefined;\n\n switch (displayMode) {\n case 'box':\n return (\n <span title={titleAttr} aria-label={titleAttr} style={{ ...baseStyle, backgroundColor: color, color: '#fff' }}>\n {iconNode}\n {labelNode}\n </span>\n );\n case 'border':\n return (\n <span title={titleAttr} aria-label={titleAttr} style={{ ...baseStyle, border: `1px solid ${color}`, color }}>\n {iconNode}\n {labelNode}\n </span>\n );\n default:\n return (\n <span title={titleAttr} aria-label={titleAttr} style={{ ...baseStyle, color }}>\n {iconNode}\n {labelNode}\n </span>\n );\n }\n}\n\nfunction renderCurrency(value: unknown, config: Record<string, unknown>): React.ReactNode {\n if (value == null) return <span style={{ color: '#a19f9d' }}>-</span>;\n const currencyCode = (config.currencyCode as string) || 'USD';\n const decimals = (config.decimals as number) ?? 2;\n const showTrend = !!config.showTrend;\n\n let amount: number;\n let trend: string | undefined;\n\n if (typeof value === 'object' && value !== null && 'amount' in value) {\n const cv = value as { amount: number; trend?: string };\n amount = cv.amount;\n trend = cv.trend;\n } else {\n amount = typeof value === 'number' ? value : parseFloat(String(value)) || 0;\n }\n\n const symbols: Record<string, string> = { USD: '$', EUR: '€', GBP: '£', JPY: '¥', CAD: 'C$', AUD: 'A$' };\n const symbol = symbols[currencyCode] || currencyCode;\n const formatted = `${symbol}${amount.toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals })}`;\n\n const trendIcons: Record<string, { icon: string; color: string }> = {\n up: { icon: 'TriangleSolidUp12', color: '#107C10' },\n down: { icon: 'TriangleSolidDown12', color: '#D13438' },\n flat: { icon: 'Remove', color: '#605e5c' },\n };\n\n return (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>\n <span>{formatted}</span>\n {showTrend && trend && trendIcons[trend] && (\n <Icon\n iconName={trendIcons[trend].icon}\n styles={{ root: { fontSize: 10, color: trendIcons[trend].color } }}\n />\n )}\n </span>\n );\n}\n\nfunction renderProgress(value: unknown, config: Record<string, unknown>): React.ReactNode {\n const max = (config.max as number) ?? 100;\n const min = (config.min as number) ?? 0;\n const showLabel = config.showLabel !== false;\n const thresholds = (config.thresholds as Record<string, number>) || {};\n\n const numVal = typeof value === 'number' ? value : parseFloat(String(value)) || 0;\n const pct = Math.max(0, Math.min(1, (numVal - min) / (max - min)));\n const pctDisplay = Math.round(pct * 100);\n\n let barColor = '#0078d4';\n if (thresholds.danger != null && pctDisplay < thresholds.danger) barColor = '#D13438';\n else if (thresholds.warning != null && pctDisplay < thresholds.warning) barColor = '#CA5010';\n\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 80 }}>\n <ProgressIndicator\n percentComplete={pct}\n barHeight={6}\n styles={{\n root: { flex: 1 },\n progressBar: { backgroundColor: barColor },\n }}\n />\n {showLabel && <span style={{ fontSize: 11, color: '#605e5c', minWidth: 28 }}>{pctDisplay}%</span>}\n </div>\n );\n}\n\nfunction renderDate(value: unknown, config: Record<string, unknown>): React.ReactNode {\n if (value == null) return <span style={{ color: '#a19f9d' }}>-</span>;\n const format = (config.format as string) || 'short';\n const showTime = config.showTime === true;\n const str = String(value);\n\n try {\n const date = new Date(str);\n if (isNaN(date.getTime())) return <span>{str}</span>;\n\n let dateText: string;\n switch (format) {\n case 'long':\n dateText = date.toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' });\n break;\n case 'relative': {\n // Relative format already implies \"ago\"; combining it with a time\n // suffix reads awkwardly, so showTime is intentionally ignored here.\n const diffMs = Date.now() - date.getTime();\n const diffDays = Math.floor(diffMs / 86400000);\n if (diffDays === 0) return <span>Today</span>;\n if (diffDays === 1) return <span>Yesterday</span>;\n if (diffDays < 30) return <span>{diffDays} days ago</span>;\n if (diffDays < 365) return <span>{Math.floor(diffDays / 30)} months ago</span>;\n return <span>{Math.floor(diffDays / 365)} years ago</span>;\n }\n case 'iso':\n // ISO already encodes time when present; honor showTime by including\n // the HH:MM portion, otherwise just the date.\n if (showTime) {\n return <span>{date.toISOString().slice(0, 16).replace('T', ' ')}</span>;\n }\n return <span>{date.toISOString().split('T')[0]}</span>;\n default:\n dateText = date.toLocaleDateString();\n }\n\n if (showTime) {\n const timeText = date.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' });\n return <span>{`${dateText} ${timeText}`}</span>;\n }\n return <span>{dateText}</span>;\n } catch {\n return <span>{str}</span>;\n }\n}\n\nfunction renderBoolean(value: unknown, config: Record<string, unknown>): React.ReactNode {\n const boolVal = !!value;\n const displayAs = (config.displayAs as string) || 'icon';\n\n switch (displayAs) {\n case 'toggle':\n return <Toggle checked={boolVal} disabled styles={{ root: { margin: 0 } }} />;\n case 'text':\n return <span>{boolVal ? ((config.trueLabel as string) || 'Yes') : ((config.falseLabel as string) || 'No')}</span>;\n default:\n return (\n <Icon\n iconName={boolVal ? 'CheckMark' : 'Cancel'}\n styles={{ root: { color: boolVal ? '#107C10' : '#D13438', fontSize: 14 } }}\n />\n );\n }\n}\n\nfunction renderRating(value: unknown, config: Record<string, unknown>): React.ReactNode {\n const max = (config.max as number) ?? 5;\n const numVal = typeof value === 'number' ? value : parseFloat(String(value)) || 0;\n\n return (\n <Rating\n rating={numVal}\n max={max}\n size={RatingSize.Small}\n readOnly\n styles={{ root: { display: 'inline-flex' } }}\n />\n );\n}\n\nfunction renderLookup(value: unknown, config: Record<string, unknown>): React.ReactNode {\n if (value == null) return <span style={{ color: '#a19f9d' }}>-</span>;\n const displayAsLink = config.displayAsLink !== false;\n const showEntityIcon = !!config.showEntityIcon;\n\n let name: string;\n let entityType: string | undefined;\n\n if (typeof value === 'object' && value !== null && 'name' in value) {\n const lv = value as { name: string; entityType?: string };\n name = lv.name;\n entityType = lv.entityType;\n } else {\n name = String(value);\n }\n\n const entityIcons: Record<string, string> = {\n account: 'CityNext',\n contact: 'Contact',\n opportunity: 'Lightbulb',\n lead: 'PeopleAdd',\n };\n\n return (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>\n {showEntityIcon && entityType && entityIcons[entityType] && (\n <Icon iconName={entityIcons[entityType]} styles={{ root: { fontSize: 12, color: '#605e5c' } }} />\n )}\n {displayAsLink ? <Link>{name}</Link> : <span>{name}</span>}\n </span>\n );\n}\n\n// ─── Conditional Style Evaluation ─────────────────────────────────────────────\n\nfunction evaluateCondition(\n rowData: Record<string, unknown>,\n condition: ConditionalStyle,\n): boolean {\n const fieldVal = rowData[condition.field];\n const numField = typeof fieldVal === 'number' ? fieldVal : parseFloat(String(fieldVal));\n const numCondition = typeof condition.value === 'number' ? condition.value : parseFloat(String(condition.value));\n\n switch (condition.operator) {\n case 'eq': return fieldVal === condition.value || String(fieldVal) === String(condition.value);\n case 'gt': return !isNaN(numField) && !isNaN(numCondition) && numField > numCondition;\n case 'lt': return !isNaN(numField) && !isNaN(numCondition) && numField < numCondition;\n case 'gte': return !isNaN(numField) && !isNaN(numCondition) && numField >= numCondition;\n case 'lte': return !isNaN(numField) && !isNaN(numCondition) && numField <= numCondition;\n case 'contains': return String(fieldVal).toLowerCase().includes(String(condition.value).toLowerCase());\n case 'between': {\n const numTo = typeof condition.valueTo === 'number' ? condition.valueTo : parseFloat(String(condition.valueTo));\n return !isNaN(numField) && !isNaN(numCondition) && !isNaN(numTo) && numField >= numCondition && numField <= numTo;\n }\n default: return false;\n }\n}\n\n// Returns a plain `Record<string, string>` rather than `React.CSSProperties`\n// — the JSX consumer (form-builder or form-runtime test harness) casts\n// it through the `style={{ ...style }}` spread under its own csstype tree.\n// See note on `baseStyle` above.\nfunction resolveConditionalStyle(\n rowData: Record<string, unknown>,\n conditionalStyles?: ConditionalStyle[],\n defaultStyle?: Record<string, string>,\n): Record<string, string> {\n if (conditionalStyles) {\n for (const rule of conditionalStyles) {\n if (evaluateCondition(rowData, rule)) {\n return rule.style;\n }\n }\n }\n return defaultStyle ?? {};\n}\n\n// ─── Composite Slot Renderer ──────────────────────────────────────────────────\n\nfunction resolveSlotValue(slot: CompositeSlot, rowData: Record<string, unknown>): unknown {\n if (slot.fieldBinding) return rowData[slot.fieldBinding];\n return slot.staticValue;\n}\n\nfunction renderCompositeSlot(\n slot: CompositeSlot,\n rowData: Record<string, unknown>,\n): React.ReactNode {\n const value = resolveSlotValue(slot, rowData);\n const style = resolveConditionalStyle(rowData, slot.conditionalStyles, slot.defaultStyle);\n\n switch (slot.type) {\n case 'icon': {\n const iconName = value != null ? String(value) : 'StatusCircleQuestionMark';\n return <Icon iconName={iconName} styles={{ root: { fontSize: 14, color: style.color as string } }} />;\n }\n case 'text':\n if (value == null) return <span style={{ color: '#a19f9d', ...style }}>-</span>;\n return <span style={{ fontSize: 13, ...style }}>{String(value)}</span>;\n case 'badge': {\n const label = value != null ? String(value) : '-';\n return (\n <span style={{\n display: 'inline-block', padding: '1px 6px', borderRadius: 3,\n fontSize: 11, fontWeight: 500, backgroundColor: '#edebe9', ...style,\n }}>\n {label}\n </span>\n );\n }\n case 'link':\n return <Link style={style}>{value != null ? String(value) : '-'}</Link>;\n case 'image': {\n const src = value != null ? String(value) : '';\n return src ? <img src={src} alt=\"\" style={{ height: 20, borderRadius: 2, ...style }} /> : null;\n }\n case 'spacer':\n return <span style={{ flex: 1, ...style }} />;\n case 'progress': {\n const numVal = typeof value === 'number' ? value : parseFloat(String(value)) || 0;\n const pct = Math.max(0, Math.min(1, numVal / 100));\n return (\n <ProgressIndicator\n percentComplete={pct}\n barHeight={4}\n styles={{ root: { flex: 1, minWidth: 40 }, progressBar: { backgroundColor: style.backgroundColor as string } }}\n />\n );\n }\n case 'rating': {\n const numVal = typeof value === 'number' ? value : parseFloat(String(value)) || 0;\n return <Rating rating={numVal} max={5} size={RatingSize.Small} readOnly styles={{ root: { display: 'inline-flex' } }} />;\n }\n default:\n return value != null ? <span style={style}>{String(value)}</span> : null;\n }\n}\n\nfunction renderComposite(value: unknown, config: Record<string, unknown>, rowData?: Record<string, unknown>): React.ReactNode {\n const compositeConfig = config as unknown as CompositeRendererConfig;\n if (!compositeConfig?.slots?.length) {\n return <span style={{ color: '#a19f9d', fontSize: 11 }}>No slots configured</span>;\n }\n\n // Build row data: if we have the full row, use it; otherwise use the value as a single-field row\n const row: Record<string, unknown> = rowData || (typeof value === 'object' && value !== null ? value as Record<string, unknown> : {});\n\n return (\n <div style={{\n display: 'flex',\n flexDirection: compositeConfig.layout === 'vertical' ? 'column' : 'row',\n alignItems: compositeConfig.layout === 'vertical' ? 'flex-start' : 'center',\n gap: compositeConfig.gap ?? 4,\n }}>\n {compositeConfig.slots.map((slot) => (\n <React.Fragment key={slot.id}>\n {renderCompositeSlot(slot, row)}\n </React.Fragment>\n ))}\n </div>\n );\n}\n\n/**\n * Render a cell value using the grid customizer column definition's renderer type and config.\n * @param rowData Optional full row data — used by composite renderer for cross-field slot bindings.\n */\nexport function renderGridCell(\n value: unknown,\n colDef: GridColumnDefinition,\n rowData?: Record<string, unknown>,\n): React.ReactNode {\n const { rendererType, rendererConfig } = colDef;\n\n switch (rendererType) {\n case 'optionset':\n return renderStatusBadge(value, rendererConfig);\n case 'currency':\n return renderCurrency(value, rendererConfig);\n case 'progress':\n return renderProgress(value, rendererConfig);\n case 'date':\n return renderDate(value, rendererConfig);\n case 'boolean':\n return renderBoolean(value, rendererConfig);\n case 'rating':\n return renderRating(value, rendererConfig);\n case 'lookup':\n return renderLookup(value, rendererConfig);\n case 'composite':\n return renderComposite(value, rendererConfig, rowData);\n case 'text':\n default:\n if (value == null) return <span style={{ color: '#a19f9d' }}>-</span>;\n if (typeof value === 'object') return <span>{JSON.stringify(value)}</span>;\n return <span>{String(value)}</span>;\n }\n}\n\n/**\n * Signature for a function that generates mock grid rows from a set of\n * grid columns. The runtime components don't compute mock data themselves\n * — callers in the editor inject this so the runtime stays free of any\n * editor-only dependencies (e.g. `@dataverse-kit/export-engine`). When\n * the prop is omitted, the runtime renders zero rows.\n */\nexport type GridMockDataGenerator = (\n columns: GridColumnDefinition[],\n rowCount: number,\n) => Record<string, unknown>[];\n","/**\n * NestedRecordsCallout\n *\n * Hover-triggered compact preview of a nested grid's child records. Used when\n * a parent grid's `nestedDisplay.mode` is `'hover-callout'`. Pairs with\n * `NestedRecordsSidePanel` — the callout footer escalates to the full panel.\n *\n * Pattern mirrors `GridCellCallout.tsx` (LookupPreviewCallout): hover delay,\n * `Callout` with `DirectionalHint`, fixed width, light dismiss.\n *\n * Moved from apps/form-builder/src/components/grid-customizer/preview/ in\n * Phase 6.5c. The mock-data generator is injected via the optional\n * `generateMockData` prop rather than imported from\n * `@dataverse-kit/export-engine`.\n */\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n Callout,\n DirectionalHint,\n Link as FluentLink,\n mergeStyles,\n} from '@fluentui/react';\nimport type { GridCustomizerDefinition } from '../../../types/gridCustomizer';\nimport { renderGridCell, type GridMockDataGenerator } from '../../shared/gridCellRenderers';\n\nconst calloutContentClass = mergeStyles({\n width: 320,\n padding: 12,\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n});\n\nconst calloutHeaderClass = mergeStyles({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: 12,\n fontWeight: 600,\n color: '#323130',\n textTransform: 'uppercase',\n letterSpacing: '0.5px',\n});\n\nconst calloutRowClass = mergeStyles({\n display: 'flex',\n flexDirection: 'column',\n padding: '6px 0',\n borderTop: '1px solid #edebe9',\n fontSize: 12,\n color: '#323130',\n gap: 2,\n});\n\nconst calloutPrimaryClass = mergeStyles({\n fontWeight: 500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nconst calloutSecondaryClass = mergeStyles({\n fontSize: 11,\n color: '#605e5c',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nconst calloutFooterClass = mergeStyles({\n display: 'flex',\n justifyContent: 'flex-end',\n paddingTop: 4,\n borderTop: '1px solid #edebe9',\n});\n\nconst emptyStateClass = mergeStyles({\n fontSize: 12,\n color: '#605e5c',\n fontStyle: 'italic',\n});\n\nexport interface NestedRecordsCalloutProps {\n /** The child grid definition whose rows should preview. */\n childGridDef: GridCustomizerDefinition | null;\n /** Hover delay in ms before showing. Defaults to 300. */\n hoverDelay?: number;\n /** Max child rows to show. Defaults to 5. */\n maxRows?: number;\n /**\n * Click escalation handler — when present, the callout footer renders a\n * \"View all N →\" link that opens the full side panel.\n */\n onViewAll?: () => void;\n /** The trigger element (badge / button / icon) that owns the hover surface. */\n children: React.ReactElement;\n /**\n * Optional mock-data generator. When omitted, the callout shows the\n * \"No related records to preview.\" empty state.\n */\n generateMockData?: GridMockDataGenerator;\n}\n\nexport const NestedRecordsCallout: React.FC<NestedRecordsCalloutProps> = ({\n childGridDef,\n hoverDelay = 300,\n maxRows = 5,\n onViewAll,\n children,\n generateMockData,\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const targetRef = useRef<HTMLSpanElement | null>(null);\n const hoverTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Delayed-dismiss timer: when the mouse leaves the trigger we don't close\n // the callout immediately — otherwise the user can never reach the callout\n // body to click \"View all\" or scan the rows. Entering the callout content\n // cancels this timer; leaving it restarts it.\n const dismissTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const DISMISS_DELAY_MS = 200;\n\n const cancelHoverTimer = useCallback(() => {\n if (hoverTimer.current) {\n clearTimeout(hoverTimer.current);\n hoverTimer.current = null;\n }\n }, []);\n\n const cancelDismissTimer = useCallback(() => {\n if (dismissTimer.current) {\n clearTimeout(dismissTimer.current);\n dismissTimer.current = null;\n }\n }, []);\n\n const startDismiss = useCallback(() => {\n cancelDismissTimer();\n dismissTimer.current = setTimeout(() => setIsOpen(false), DISMISS_DELAY_MS);\n }, [cancelDismissTimer]);\n\n const handleTriggerEnter = useCallback(() => {\n cancelDismissTimer();\n cancelHoverTimer();\n hoverTimer.current = setTimeout(() => setIsOpen(true), hoverDelay);\n }, [cancelDismissTimer, cancelHoverTimer, hoverDelay]);\n\n const handleTriggerLeave = useCallback(() => {\n // Cancel any pending open (so a quick brush-by doesn't fire), then start\n // the delayed dismiss — gives the user a window to traverse the gap into\n // the callout body.\n cancelHoverTimer();\n startDismiss();\n }, [cancelHoverTimer, startDismiss]);\n\n const closeNow = useCallback(() => {\n cancelHoverTimer();\n cancelDismissTimer();\n setIsOpen(false);\n }, [cancelHoverTimer, cancelDismissTimer]);\n\n useEffect(() => () => {\n cancelHoverTimer();\n cancelDismissTimer();\n }, [cancelHoverTimer, cancelDismissTimer]);\n\n const visibleColumns = childGridDef\n ? [...childGridDef.columns]\n .filter((c) => c.isVisible)\n .sort((a, b) => a.order - b.order)\n : [];\n\n const previewItems = childGridDef && generateMockData\n ? generateMockData(visibleColumns, maxRows)\n : [];\n\n const primaryCol = visibleColumns[0];\n const secondaryCol = visibleColumns[1];\n\n return (\n <>\n <span\n ref={targetRef}\n onMouseEnter={handleTriggerEnter}\n onMouseLeave={handleTriggerLeave}\n >\n {children}\n </span>\n {isOpen && targetRef.current ? (\n <Callout\n target={targetRef.current}\n directionalHint={DirectionalHint.bottomLeftEdge}\n isBeakVisible={false}\n gapSpace={4}\n onDismiss={closeNow}\n setInitialFocus={false}\n // Hover-style callout: don't auto-dismiss on focus changes inside\n // the callout (e.g. when a Link is focused). Click-outside still\n // dismisses via the default Callout behavior.\n preventDismissOnLostFocus\n preventDismissOnScroll\n styles={{ root: { borderRadius: 4 } }}\n >\n <div\n className={calloutContentClass}\n onMouseEnter={cancelDismissTimer}\n onMouseLeave={startDismiss}\n >\n <div className={calloutHeaderClass}>\n <span>{childGridDef?.name ?? 'Related records'}</span>\n <span style={{ fontWeight: 400, color: '#605e5c' }}>\n {previewItems.length}\n </span>\n </div>\n {!childGridDef || previewItems.length === 0 ? (\n <div className={emptyStateClass}>No related records to preview.</div>\n ) : (\n previewItems.map((item, idx) => (\n <div key={idx} className={calloutRowClass}>\n <div className={calloutPrimaryClass}>\n {primaryCol ? renderGridCell(item[primaryCol.fieldName], primaryCol) : '—'}\n </div>\n {secondaryCol ? (\n <div className={calloutSecondaryClass}>\n {renderGridCell(item[secondaryCol.fieldName], secondaryCol)}\n </div>\n ) : null}\n </div>\n ))\n )}\n {onViewAll ? (\n <div className={calloutFooterClass}>\n <FluentLink\n onClick={() => {\n closeNow();\n onViewAll();\n }}\n >\n View all →\n </FluentLink>\n </div>\n ) : null}\n </div>\n </Callout>\n ) : null}\n </>\n );\n};\n","/**\n * NestedRecordsTrigger\n *\n * Renders the \"view related records\" affordance for a parent row when the\n * parent grid type can't show inline children (focused-view, card-list).\n * Switches on `nestedDisplay.mode`:\n * - side-panel → DefaultButton that toggles NestedRecordsSidePanel\n * - hover-callout → small badge wrapped in NestedRecordsCallout (with\n * \"View all\" escalation that opens the side panel)\n * - detail-pane → renders a compact inline child grid below the parent\n *\n * Designed to be dropped into a focused-view card or a card-list card without\n * affecting layout — wraps itself in a div with margin-top so callers can stay\n * unaware of the trigger's exact shape.\n *\n * Moved from apps/form-builder/src/components/grid-customizer/preview/ in\n * Phase 6.5c. The mock-data generator is injected via the optional\n * `generateMockData` prop rather than imported from\n * `@dataverse-kit/export-engine`.\n */\n\nimport React, { useState, useMemo } from 'react';\nimport {\n DefaultButton,\n DetailsList,\n DetailsListLayoutMode,\n Icon,\n IColumn,\n SelectionMode,\n mergeStyles,\n} from '@fluentui/react';\nimport type {\n GridCustomizerDefinition,\n NestedDisplayConfig,\n} from '../../../types/gridCustomizer';\nimport { renderGridCell, type GridMockDataGenerator } from '../../shared/gridCellRenderers';\nimport { NestedRecordsSidePanel } from './NestedRecordsSidePanel';\nimport { NestedRecordsCallout } from './NestedRecordsCallout';\n\nconst triggerWrapperClass = mergeStyles({\n marginTop: 6,\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n});\n\nconst badgeClass = mergeStyles({\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n padding: '2px 8px',\n borderRadius: 12,\n backgroundColor: '#deecf9',\n color: '#0078d4',\n fontSize: 11,\n fontWeight: 500,\n cursor: 'pointer',\n selectors: {\n ':hover': { backgroundColor: '#c7e0f4' },\n },\n});\n\nconst detailPaneClass = mergeStyles({\n marginTop: 8,\n borderTop: '1px solid #edebe9',\n paddingTop: 8,\n});\n\nconst detailPaneHeaderClass = mergeStyles({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: 11,\n color: '#605e5c',\n marginBottom: 4,\n textTransform: 'uppercase',\n letterSpacing: '0.4px',\n fontWeight: 600,\n});\n\nconst DEFAULT_TRIGGER_LABEL = 'View {count} related';\nconst DEFAULT_TRIGGER_ICON = 'OpenPaneMirrored';\n\nfunction formatTriggerLabel(label: string | undefined, count: number): string {\n const template = label && label.trim().length > 0 ? label : DEFAULT_TRIGGER_LABEL;\n return template.replace(/\\{count\\}/g, String(count));\n}\n\nexport interface NestedRecordsTriggerProps {\n /** The child grid definition. */\n childGridDef: GridCustomizerDefinition | null;\n /** Display config from the parent grid. */\n config: NestedDisplayConfig;\n /** Parent record label surfaced in the side panel header. */\n parentLabel?: string;\n /**\n * Number of related records to advertise in the trigger label and to render\n * in mock previews. Falls back to the child grid's pageSize when unset.\n */\n childCount?: number;\n /**\n * When true, the component does not auto-mount any panel/callout — used by\n * the focused-view mode that wants to control its own detail-pane container.\n * Currently unused but reserved for future composition.\n */\n inlineOnly?: boolean;\n /**\n * Optional mock-data generator forwarded to the sub-components\n * (NestedRecordsSidePanel, NestedRecordsCallout, NestedDetailPaneList).\n * When omitted, all child surfaces render zero rows.\n */\n generateMockData?: GridMockDataGenerator;\n}\n\nexport const NestedRecordsTrigger: React.FC<NestedRecordsTriggerProps> = ({\n childGridDef,\n config,\n parentLabel,\n childCount,\n generateMockData,\n}) => {\n const [panelOpen, setPanelOpen] = useState(false);\n\n const advertisedCount = useMemo(() => {\n if (typeof childCount === 'number') return childCount;\n return childGridDef?.pageSize ?? 5;\n }, [childCount, childGridDef]);\n\n const label = formatTriggerLabel(config.triggerLabel, advertisedCount);\n const iconName = config.triggerIcon && config.triggerIcon.trim().length > 0\n ? config.triggerIcon\n : DEFAULT_TRIGGER_ICON;\n\n // detail-pane: render the child grid inline below the parent row.\n if (config.mode === 'detail-pane') {\n return (\n <div className={detailPaneClass}>\n <div className={detailPaneHeaderClass}>\n <span>{childGridDef?.name ?? 'Related records'}</span>\n <span style={{ fontWeight: 400 }}>{advertisedCount}</span>\n </div>\n <NestedDetailPaneList\n childGridDef={childGridDef}\n rowCount={advertisedCount}\n generateMockData={generateMockData}\n />\n </div>\n );\n }\n\n // side-panel: button → Panel.\n if (config.mode === 'side-panel') {\n return (\n <>\n <div className={triggerWrapperClass}>\n <DefaultButton\n iconProps={{ iconName }}\n text={label}\n onClick={(e) => {\n e.stopPropagation();\n setPanelOpen(true);\n }}\n styles={{ root: { height: 28, padding: '0 8px', fontSize: 12 } }}\n />\n </div>\n <NestedRecordsSidePanel\n isOpen={panelOpen}\n onDismiss={() => setPanelOpen(false)}\n childGridDef={childGridDef}\n parentLabel={parentLabel}\n panelSize={config.panelSize}\n generateMockData={generateMockData}\n />\n </>\n );\n }\n\n // hover-callout: badge wrapped in callout, with side-panel escalation.\n if (config.mode === 'hover-callout') {\n return (\n <>\n <div className={triggerWrapperClass}>\n <NestedRecordsCallout\n childGridDef={childGridDef}\n hoverDelay={config.hoverDelay}\n maxRows={config.calloutMaxRows}\n onViewAll={() => setPanelOpen(true)}\n generateMockData={generateMockData}\n >\n <span className={badgeClass}>\n <Icon iconName={iconName} styles={{ root: { fontSize: 11 } }} />\n {label}\n </span>\n </NestedRecordsCallout>\n </div>\n <NestedRecordsSidePanel\n isOpen={panelOpen}\n onDismiss={() => setPanelOpen(false)}\n childGridDef={childGridDef}\n parentLabel={parentLabel}\n panelSize={config.panelSize}\n generateMockData={generateMockData}\n />\n </>\n );\n }\n\n // 'inline' here means the parent grid type doesn't support inline expand\n // (focused-view, card-list) — auto-fall-back to a side-panel button so users\n // are not stranded. The settings UI prevents this combination, but this is a\n // safety net.\n return (\n <>\n <div className={triggerWrapperClass}>\n <DefaultButton\n iconProps={{ iconName }}\n text={label}\n onClick={(e) => {\n e.stopPropagation();\n setPanelOpen(true);\n }}\n styles={{ root: { height: 28, padding: '0 8px', fontSize: 12 } }}\n />\n </div>\n <NestedRecordsSidePanel\n isOpen={panelOpen}\n onDismiss={() => setPanelOpen(false)}\n childGridDef={childGridDef}\n parentLabel={parentLabel}\n generateMockData={generateMockData}\n />\n </>\n );\n};\n\ninterface NestedDetailPaneListProps {\n childGridDef: GridCustomizerDefinition | null;\n rowCount: number;\n generateMockData?: GridMockDataGenerator;\n}\n\nconst NestedDetailPaneList: React.FC<NestedDetailPaneListProps> = ({\n childGridDef,\n rowCount,\n generateMockData,\n}) => {\n const visibleColumns = useMemo(() => {\n if (!childGridDef) return [];\n return [...childGridDef.columns]\n .filter((c) => c.isVisible)\n .sort((a, b) => a.order - b.order);\n }, [childGridDef]);\n\n const items = useMemo(\n () => (childGridDef && generateMockData ? generateMockData(visibleColumns, rowCount) : []),\n [childGridDef, rowCount, visibleColumns, generateMockData],\n );\n\n const columns: IColumn[] = useMemo(\n () =>\n visibleColumns.map((col) => ({\n key: col.id,\n name: col.displayName || col.fieldName,\n fieldName: col.fieldName,\n minWidth: col.minWidth ?? 50,\n maxWidth: col.maxWidth ?? 160,\n isResizable: true,\n onRender: (item: Record<string, unknown>) => (\n <>{renderGridCell(item[col.fieldName], col)}</>\n ),\n })),\n [visibleColumns],\n );\n\n if (!childGridDef || visibleColumns.length === 0) {\n return (\n <div style={{ fontSize: 11, color: '#a19f9d', fontStyle: 'italic', padding: '4px 0' }}>\n No related grid configured.\n </div>\n );\n }\n\n return (\n <DetailsList\n items={items}\n columns={columns}\n layoutMode={DetailsListLayoutMode.justified}\n selectionMode={SelectionMode.none}\n compact\n isHeaderVisible\n />\n );\n};\n","/**\n * FocusedViewMasterDetailPreview\n *\n * Designer-side preview for `gridType: 'focused-view'` with a configured\n * nested grid. Mirrors the runtime layout the form-code generator emits:\n * left rail of persona cards (the focused list of parent records) + right\n * pane that hosts the child grid for the currently selected parent.\n *\n * Replaces the \"left rail + per-card View N related button\" preview so\n * what users see in the designer matches the export.\n *\n * Moved from apps/form-builder/src/components/grid-customizer/preview/ in\n * Phase 6.5c. The mock-data generator is injected via the optional\n * `generateMockData` prop rather than imported from\n * `@dataverse-kit/export-engine`.\n */\n\nimport React, { useMemo, useState, useEffect } from 'react';\nimport {\n Persona,\n PersonaSize,\n Icon,\n SearchBox,\n Spinner,\n SpinnerSize,\n DetailsList,\n DetailsListLayoutMode,\n SelectionMode,\n IColumn,\n mergeStyles,\n} from '@fluentui/react';\nimport type { GridCustomizerDefinition } from '../../../types/gridCustomizer';\nimport type { FocusedViewConfig } from '../../../types/focusedView';\nimport { renderGridCell, type GridMockDataGenerator } from '../../shared/gridCellRenderers';\n\nexport interface FocusedCardRow {\n primaryValue: string;\n secondaryValue?: string;\n iconName?: string;\n isFirst: boolean;\n}\n\nexport interface FocusedCardData {\n id: string;\n rows: FocusedCardRow[];\n}\n\nexport interface FocusedViewMasterDetailPreviewProps {\n /** Parent records rendered in the left rail. */\n cards: FocusedCardData[];\n /** Field configuration for the cards (used to resolve labels per row). */\n focusedViewConfig: FocusedViewConfig;\n /** Header text — typically the parent entity name. */\n entityName: string;\n /** Whether to render the \"Related\" pill next to the header. */\n showRelatedRecords?: boolean;\n /** Whether to hide the search box (controlled by the subgrid's `hideSearchBox`). */\n hideSearchBox?: boolean;\n /** Live-data loading state. */\n liveLoading?: boolean;\n /** The child grid configuration to render in the right pane. */\n childGridDef: GridCustomizerDefinition;\n /** Persona initials helper (matches existing focused-view rendering). */\n getInitials: (name: string) => string;\n /** Persona color helper (matches existing focused-view rendering). */\n getPersonaColor: (name: string) => string;\n /** Should the upcoming-activity row at the bottom of the rail render. */\n showUpNextActivity?: boolean;\n /**\n * Optional mock-data generator. When provided (typically by the editor's\n * shim wrapper), each card receives a stable mocked row set. When omitted,\n * the right pane renders zero rows.\n */\n generateMockData?: GridMockDataGenerator;\n}\n\nconst containerClass = mergeStyles({\n border: '1px solid #edebe9',\n borderRadius: 2,\n overflow: 'hidden',\n backgroundColor: '#fff',\n display: 'flex',\n height: 460,\n});\n\nconst railClass = mergeStyles({\n width: 320,\n flexShrink: 0,\n display: 'flex',\n flexDirection: 'column',\n borderRight: '1px solid #edebe9',\n});\n\nconst railHeaderClass = mergeStyles({\n display: 'flex',\n alignItems: 'center',\n padding: '10px 12px',\n borderBottom: '1px solid #edebe9',\n});\n\nconst railHeaderTextClass = mergeStyles({\n fontSize: 14,\n fontWeight: 600,\n color: '#323130',\n flex: 1,\n});\n\nconst railSearchClass = mergeStyles({\n padding: '8px 12px',\n borderBottom: '1px solid #edebe9',\n flexShrink: 0,\n});\n\nconst railListClass = mergeStyles({\n flex: 1,\n overflowY: 'auto',\n});\n\nconst cardClass = mergeStyles({\n display: 'flex',\n alignItems: 'flex-start',\n padding: '10px 12px',\n cursor: 'pointer',\n borderBottom: '1px solid #edebe9',\n borderLeft: '3px solid transparent',\n transition: 'background-color 0.1s',\n ':hover': {\n backgroundColor: '#f3f2f1',\n },\n});\n\nconst cardSelectedClass = mergeStyles({\n backgroundColor: '#cce4f6',\n borderLeftColor: '#0078d4',\n ':hover': {\n backgroundColor: '#cce4f6',\n },\n});\n\nconst cardContentClass = mergeStyles({\n flex: 1,\n minWidth: 0,\n marginLeft: 10,\n});\n\nconst cardPrimaryNameClass = mergeStyles({\n fontSize: 14,\n fontWeight: 600,\n color: '#323130',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n});\n\nconst cardRowClass = mergeStyles({\n fontSize: 12,\n color: '#605e5c',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n lineHeight: '18px',\n});\n\nconst railFooterClass = mergeStyles({\n padding: '8px 12px',\n borderTop: '1px solid #edebe9',\n fontSize: 12,\n color: '#605e5c',\n textAlign: 'center',\n flexShrink: 0,\n});\n\nconst detailPaneClass = mergeStyles({\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n});\n\nconst detailHeaderClass = mergeStyles({\n padding: '12px 16px',\n borderBottom: '1px solid #edebe9',\n flexShrink: 0,\n});\n\nconst detailHeaderTitleClass = mergeStyles({\n fontSize: 16,\n fontWeight: 600,\n color: '#323130',\n});\n\nconst detailHeaderSubtitleClass = mergeStyles({\n fontSize: 12,\n color: '#605e5c',\n marginTop: 2,\n});\n\nconst detailBodyClass = mergeStyles({\n flex: 1,\n overflow: 'auto',\n});\n\nconst emptyStateClass = mergeStyles({\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#605e5c',\n fontSize: 13,\n padding: 32,\n textAlign: 'center',\n});\n\nconst upNextClass = mergeStyles({\n padding: '8px 12px',\n borderTop: '1px solid #edebe9',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 11,\n color: '#605e5c',\n});\n\nexport const FocusedViewMasterDetailPreview: React.FC<FocusedViewMasterDetailPreviewProps> = ({\n cards,\n focusedViewConfig,\n entityName,\n showRelatedRecords = false,\n hideSearchBox = false,\n liveLoading = false,\n childGridDef,\n getInitials,\n getPersonaColor,\n showUpNextActivity = false,\n generateMockData,\n}) => {\n const [selectedCardId, setSelectedCardId] = useState<string | null>(null);\n\n // Drop a stale selection if the focused card falls out of the list (e.g.\n // search filtering). We don't auto-select the first card so the preview\n // matches the export — toolbar buttons gated on selection stay hidden\n // until the user explicitly clicks a card, and the empty-state right\n // pane mirrors the deployed UX.\n useEffect(() => {\n if (cards.length === 0) {\n setSelectedCardId(null);\n return;\n }\n if (selectedCardId && !cards.some((c) => c.id === selectedCardId)) {\n setSelectedCardId(null);\n }\n }, [cards, selectedCardId]);\n\n const selectedCard = useMemo(\n () => cards.find((c) => c.id === selectedCardId) ?? null,\n [cards, selectedCardId],\n );\n const selectedDisplayName = selectedCard?.rows[0]?.primaryValue ?? '';\n\n // Build the right-pane child grid. Reuse the same mock-data helpers the\n // side-panel preview uses so both surfaces stay visually aligned.\n const childVisibleColumns = useMemo(\n () => [...childGridDef.columns]\n .filter((c) => c.isVisible)\n .sort((a, b) => a.order - b.order),\n [childGridDef.columns],\n );\n\n // Generate child rows once per parent so switching between cards swaps the\n // visible rows — useful for showing the layout's purpose at a glance.\n const childItemsByParent = useMemo(() => {\n const out: Record<string, Record<string, unknown>[]> = {};\n if (!generateMockData) return out;\n const childCount = childGridDef.pageSize ?? 4;\n cards.forEach((card, idx) => {\n // Stable seed per card: regenerate-but-deterministic by index.\n out[card.id] = generateMockData(childVisibleColumns, childCount + (idx % 2));\n });\n return out;\n }, [cards, childVisibleColumns, childGridDef.pageSize, generateMockData]);\n\n const childDetailsListColumns: IColumn[] = useMemo(\n () => childVisibleColumns.map((col) => ({\n key: col.id,\n name: col.displayName || col.fieldName,\n fieldName: col.fieldName,\n minWidth: col.minWidth ?? 80,\n maxWidth: col.maxWidth ?? 200,\n isResizable: true,\n onRender: (item: Record<string, unknown>) => (\n <>{renderGridCell(item[col.fieldName], col)}</>\n ),\n })),\n [childVisibleColumns],\n );\n\n const childRows = selectedCard ? (childItemsByParent[selectedCard.id] ?? []) : [];\n\n return (\n <div className={containerClass}>\n <div className={railClass}>\n <div className={railHeaderClass}>\n <span className={railHeaderTextClass}>\n {entityName}\n {showRelatedRecords && (\n <span style={{\n fontSize: 10,\n color: '#0078d4',\n backgroundColor: '#deecf9',\n padding: '2px 6px',\n borderRadius: 2,\n marginLeft: 8,\n fontWeight: 400,\n }}>Related</span>\n )}\n </span>\n <Icon iconName=\"ChevronDown\" styles={{ root: { fontSize: 12, color: '#605e5c' } }} />\n </div>\n {!hideSearchBox && (\n <div className={railSearchClass}>\n <SearchBox\n placeholder=\"Search this view\"\n styles={{ root: { borderRadius: 4 } }}\n />\n </div>\n )}\n <div className={railListClass}>\n {cards.length === 0 ? (\n <div style={{ padding: 32, textAlign: 'center', color: '#605e5c', fontSize: 13 }}>\n No records to preview\n </div>\n ) : (\n cards.map((card) => {\n const isSelected = card.id === selectedCardId;\n const primaryName = card.rows[0]?.primaryValue || 'Record';\n return (\n <div\n key={card.id}\n role=\"option\"\n aria-selected={isSelected}\n tabIndex={0}\n onClick={() => setSelectedCardId((prev) => (prev === card.id ? null : card.id))}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setSelectedCardId((prev) => (prev === card.id ? null : card.id));\n } else if (e.key === 'Escape') {\n setSelectedCardId(null);\n }\n }}\n className={`${cardClass} ${isSelected ? cardSelectedClass : ''}`}\n >\n <Persona\n text={primaryName}\n imageInitials={getInitials(primaryName)}\n size={PersonaSize.size32}\n initialsColor={getPersonaColor(primaryName)}\n hidePersonaDetails\n />\n <div className={cardContentClass}>\n <div className={cardPrimaryNameClass} title={primaryName}>\n {primaryName}\n </div>\n {card.rows.slice(1).map((row, rowIdx) => {\n const label = focusedViewConfig.rows[rowIdx + 1]?.primaryField.label;\n return (\n <div key={rowIdx} className={cardRowClass}>\n {label ? `${label}: ${row.primaryValue}` : row.primaryValue}\n </div>\n );\n })}\n </div>\n </div>\n );\n })\n )}\n </div>\n {showUpNextActivity && (\n <div className={upNextClass}>\n <Icon iconName=\"CheckboxComposite\" styles={{ root: { fontSize: 12 } }} />\n <span>Up next activity</span>\n <span style={{ marginLeft: 'auto' }}>00:00 AM</span>\n </div>\n )}\n <div className={railFooterClass}>\n {liveLoading ? (\n <Spinner size={SpinnerSize.xSmall} label=\"Loading...\" labelPosition=\"right\" />\n ) : (\n <span>{cards.length > 0 ? `1-${cards.length}` : '0-0'} of {cards.length}</span>\n )}\n </div>\n </div>\n\n <div className={detailPaneClass}>\n {selectedCard ? (\n <>\n <div className={detailHeaderClass}>\n <div className={detailHeaderTitleClass}>{selectedDisplayName}</div>\n <div className={detailHeaderSubtitleClass}>{childGridDef.name}</div>\n </div>\n <div className={detailBodyClass}>\n {childVisibleColumns.length === 0 ? (\n <div className={emptyStateClass}>\n The related grid has no visible columns.\n </div>\n ) : (\n <DetailsList\n items={childRows}\n columns={childDetailsListColumns}\n layoutMode={DetailsListLayoutMode.justified}\n selectionMode={SelectionMode.multiple}\n compact={childGridDef.compactMode}\n isHeaderVisible\n />\n )}\n </div>\n </>\n ) : (\n <div className={emptyStateClass}>\n Select a record to view related {childGridDef.name}\n </div>\n )}\n </div>\n </div>\n );\n};\n","/**\n * `<FormRuntime>` — Phase 1 dispatcher (Task 7).\n *\n * Single mount point for every form-renderer host: the form-builder\n * designer canvas (with overlay chrome), preview, and (Phase 3)\n * generated code. Branches internally on `form.layoutMode`:\n *\n * - `'tabbed'` (default) → `TabsShell` + header + command bar + BPF\n * - `'grid'` → `GridShell` (no tabs / command bar by\n * design — dashboard layout pushes those\n * into the parent host)\n *\n * The dispatcher computes `ControlPartProps` for each cell via\n * `DispatchedControl` (see `v8/controls/dispatcher.tsx`) so per-type\n * files stay UI-only. Async capabilities (`fetchLiveData`,\n * `fetchWebResource`, `searchLookup`, `connection`,\n * `previewContext`) come from a surrounding `FormRuntimeProvider`;\n * callers supply this via the editor's `EditorFormRuntimeProvider`\n * or, in Phase 3, generated host code that wraps an `IApiService`.\n */\n\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport type { FormDefinition, ControlDefinition, CommandBarItem } from './types';\nimport { HeaderShell } from './shell/HeaderShell';\nimport { CommandBarShell } from './shell/CommandBarShell';\nimport { BpfShell } from './shell/BpfShell';\nimport { TabsShell } from './shell/TabsShell';\nimport { GridShell } from './shell/GridShell';\nimport { FooterShell } from './shell/FooterShell';\nimport { CalloutsProvider } from './context/CalloutsContext';\nimport { RuleStatesProvider } from './context/RuleStatesContext';\nimport type { FieldState, SectionState, TabState } from './types/businessRules';\nimport type { InstrumentationMode } from './instrumentation';\n\nexport interface FormRuntimeProps {\n /** The form definition to render (tabs, sections, controls, etc.). */\n form: FormDefinition;\n /**\n * Initial record values. Keyed by `dataBinding.attributeLogicalName`\n * (and the `…@OData.Community.Display.V1.FormattedValue` annotations\n * Dataverse returns). The dispatcher reads from this when a control\n * has a binding and no controlled override.\n */\n recordData?: Record<string, unknown> | null;\n /**\n * `false` disables every input control + reveals the legacy\n * \"designer affordances\" inside per-type files (e.g. spacer/label\n * placeholder outlines). Default `true`.\n */\n interactive?: boolean;\n /**\n * `'designer'` emits `data-element-id` / `data-element-type` /\n * `data-element-path` attributes on every structural element so the\n * Phase 2 designer overlay can locate them. Default `'off'`.\n */\n instrumentation?: InstrumentationMode;\n /**\n * Optional click handler for command-bar items. The runtime stays\n * neutral on what an item does — the host decides.\n */\n onCommandClick?: (item: CommandBarItem) => void;\n /** Optional button-click handler propagated into `DispatchedControl`. */\n onButtonClick?: (action: unknown) => void;\n /**\n * Optional value-change handler. When omitted, edits are tracked\n * internally via the runtime's local `useFormState` so the user can\n * still interact with controls. Hosts that own form state pass\n * `onChange` to take over.\n */\n onChange?: (controlName: string, next: unknown) => void;\n /**\n * Optional dialog/panel footer action-button click handler. Phase 3\n * m3 — the runtime emits the buttons but stays neutral on actions;\n * the host (preview wrapper or generated app) decides what 'close'\n * / 'save' / 'cancel' etc. do.\n */\n onActionButtonClick?: (button: import('./types').DialogActionButton) => void;\n /**\n * Optional business-rule evaluation outputs. The runtime consumes\n * these to gate field / section / tab visibility and merge\n * readOnly + required overrides into individual controls. Phase 3\n * m4. The runtime does NOT own the rule engine — pass the maps\n * from the host's rule-execution store (form-builder uses\n * useRuleExecutionStore; generated apps pass equivalent maps).\n */\n ruleStates?: {\n fieldStates?: Record<string, FieldState>;\n sectionStates?: Record<string, SectionState>;\n tabStates?: Record<string, TabState>;\n };\n}\n\nexport const FormRuntime: React.FC<FormRuntimeProps> = ({\n form,\n recordData,\n interactive = true,\n instrumentation = 'off',\n onCommandClick,\n onButtonClick,\n onChange,\n onActionButtonClick,\n ruleStates,\n}) => {\n // Local form state for hosts that don't manage their own values.\n // Records edits per control.name; merged into `recordData` so the\n // dispatched controls see the latest value. Cleared whenever the\n // form identity changes — otherwise switching to a different form\n // with overlapping control names would leak stale edits.\n const [localEdits, setLocalEdits] = useState<Record<string, unknown>>({});\n useEffect(() => {\n setLocalEdits({});\n }, [form.id]);\n const onCellValueChange = useCallback(\n (controlName: string, next: unknown) => {\n if (onChange) {\n onChange(controlName, next);\n } else {\n setLocalEdits((prev) => ({ ...prev, [controlName]: next }));\n }\n },\n [onChange],\n );\n\n // Merge local edits into recordData under each control's\n // `attributeLogicalName`. Unbound controls (formlink / button /\n // spacer / label) ignore this; per-type files reading\n // `effectiveValue` get the edited value transparently.\n const mergedRecord = useMemo(() => {\n if (Object.keys(localEdits).length === 0) return recordData ?? null;\n const out: Record<string, unknown> = { ...(recordData ?? {}) };\n bindControls(form).forEach((control) => {\n const edit = localEdits[control.name];\n if (edit === undefined) return;\n const attr = control.dataBinding?.attributeLogicalName;\n if (attr) out[attr] = edit;\n });\n return out;\n }, [recordData, localEdits, form]);\n\n const layoutMode = form.layoutMode ?? 'tabbed';\n\n return (\n <CalloutsProvider callouts={form.callouts}>\n <RuleStatesProvider\n fieldStates={ruleStates?.fieldStates}\n sectionStates={ruleStates?.sectionStates}\n tabStates={ruleStates?.tabStates}\n >\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n backgroundColor: '#fff',\n }}\n >\n {form.type === 'main' && (\n <>\n <HeaderShell\n form={form}\n recordData={mergedRecord}\n interactive={interactive}\n instrumentation={instrumentation}\n onButtonClick={onButtonClick}\n />\n <CommandBarShell\n form={form}\n interactive={interactive}\n instrumentation={instrumentation}\n onCommandClick={onCommandClick}\n />\n <BpfShell form={form} instrumentation={instrumentation} />\n </>\n )}\n <div style={{ flex: 1, overflow: 'auto' }}>\n {layoutMode === 'grid' ? (\n <GridShell\n form={form}\n recordData={mergedRecord}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n ) : form.tabs && form.tabs.length > 0 ? (\n <TabsShell\n form={form}\n recordData={mergedRecord}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n ) : (\n // Dialog/panel/callout — flat sections, no tab bar.\n <FlatSections\n form={form}\n recordData={mergedRecord}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n )}\n </div>\n {/* Dialog/panel footer action buttons — m3. No-op for main/callout. */}\n <FooterShell form={form} onActionButtonClick={onActionButtonClick} />\n </div>\n </RuleStatesProvider>\n </CalloutsProvider>\n );\n};\n\n// Lazy-import to avoid a circular-friendly cycle through SectionShell.\nimport { SectionShell } from './shell/SectionShell';\nimport { paths } from './instrumentation';\nimport type { DispatchControlInputs } from './v8/controls/dispatcher';\n\ninterface FlatSectionsProps {\n form: FormDefinition;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nconst FlatSections: React.FC<FlatSectionsProps> = ({\n form,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12, padding: 12 }}>\n {(form.sections ?? []).map((section) => (\n <SectionShell\n key={section.id}\n section={section}\n parentPath={paths.tab(form.id)}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n ))}\n </div>\n);\n\n/** Walk the form's structure and yield every bound control. */\nfunction bindControls(form: FormDefinition): ControlDefinition[] {\n const out: ControlDefinition[] = [];\n const walkSections = (sections: FormDefinition['sections']) => {\n for (const section of sections ?? []) {\n for (const row of section.rows ?? []) {\n for (const cell of row.cells ?? []) {\n if (cell.control) out.push(cell.control);\n }\n }\n }\n };\n walkSections(form.sections);\n for (const tab of form.tabs ?? []) {\n if ('sections' in tab && tab.sections) {\n walkSections(tab.sections);\n }\n }\n if (form.header?.cells) {\n for (const cell of form.header.cells) {\n if (cell.control) out.push(cell.control);\n }\n }\n return out;\n}\n","/**\n * HeaderShell — main-form top banner (title, subtitle, 0–4 cell slots).\n *\n * Two rendering modes governed by `form.settings.headerDisplayMode`:\n *\n * - `'inline'` (or absent — the runtime's current default): cells\n * render in a CSS grid alongside the title. Each cell dispatches\n * through the runtime's normal control dispatcher.\n *\n * - `'flyout'` (Phase 3 m5): cells render as compact label/value\n * summary tiles separated by vertical bars, with a chevron toggle\n * on the right. Clicking the chevron opens a Callout containing\n * the same cells as editable controls — matches the legacy\n * `HeaderFieldSummaryPreview` + flyout in\n * apps/form-builder/.../form-preview/FormPreview.tsx.\n *\n * The legacy preview also fetched lookup entity images and presence\n * for systemuser lookups via direct Dataverse calls. That belongs in\n * a FormRuntimeCapabilities enhancement, not the shell itself — for\n * now the persona renders with initials only (the universal baseline).\n */\n\nimport React, { useRef, useState } from 'react';\nimport {\n Callout,\n DirectionalHint,\n IconButton,\n Persona,\n PersonaSize,\n type PersonaInitialsColor,\n} from '@fluentui/react';\nimport type { FormDefinition, FormCell, ControlDefinition } from '../types';\nimport {\n DispatchedControl,\n type DispatchControlInputs,\n} from '../v8/controls/dispatcher';\nimport { instrumentAttrs, paths, type InstrumentationMode } from '../instrumentation';\nimport { getInitials, getPersonaColor } from '../v8/shared/helpers';\n\nexport interface HeaderShellProps {\n form: FormDefinition;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n /**\n * Pass-through so the dispatcher's button-click handler can route\n * up to the host (open record, run action, etc.).\n */\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\n/** Person-type entities for which a Persona avatar renders in the flyout\n * summary. Matches the legacy PREVIEW_PERSON_ENTITIES set — entities not\n * in this set still get a summary tile, just without the avatar. */\nconst PERSON_ENTITIES: ReadonlySet<string> = new Set(['systemuser', 'contact', 'lead']);\n\nexport const HeaderShell: React.FC<HeaderShellProps> = ({\n form,\n recordData,\n interactive,\n instrumentation,\n onButtonClick,\n}) => {\n const header = form.header;\n if (!header) return null;\n\n const title = header.title || form.name;\n const subtitle = header.subtitle;\n const slotCells = (header.cells ?? []).slice(0, header.slotCount ?? 4);\n const titleColor = header.titleColor ?? '#323130';\n const subtitleColor = header.subtitleColor ?? '#605e5c';\n const flyoutMode = form.settings.headerDisplayMode === 'flyout' && slotCells.length > 0;\n\n return (\n <div\n {...instrumentAttrs(instrumentation, 'header', 'header', paths.header())}\n style={{\n padding: '12px 16px',\n borderBottom: '1px solid #edebe9',\n backgroundColor: '#faf9f8',\n display: 'flex',\n flexDirection: 'row',\n alignItems: flyoutMode ? 'center' : 'baseline',\n gap: flyoutMode ? 12 : 8,\n }}\n >\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n flex: flyoutMode ? '0 0 auto' : 1,\n }}\n >\n <div style={{ fontSize: 18, fontWeight: 600, color: titleColor }}>{title}</div>\n {subtitle ? (\n <div style={{ fontSize: 12, color: subtitleColor }}>{subtitle}</div>\n ) : null}\n </div>\n\n {!flyoutMode && slotCells.length > 0 && (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${slotCells.length}, minmax(0, 1fr))`,\n gap: 12,\n flex: 1,\n }}\n >\n {slotCells.map((cell) =>\n cell.control ? (\n <div\n key={cell.id}\n {...instrumentAttrs(instrumentation, cell.id, 'cell', `header/cells/${cell.id}`)}\n >\n <DispatchedControl\n control={cell.control}\n recordData={recordData}\n interactive={interactive}\n onButtonClick={onButtonClick}\n />\n </div>\n ) : (\n <div key={cell.id} />\n ),\n )}\n </div>\n )}\n\n {flyoutMode && (\n <FlyoutHeaderFields\n cells={slotCells}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n textColor={titleColor}\n subtitleColor={subtitleColor}\n onButtonClick={onButtonClick}\n />\n )}\n </div>\n );\n};\n\ninterface FlyoutHeaderFieldsProps {\n cells: FormCell[];\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n textColor: string;\n subtitleColor: string;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nconst FlyoutHeaderFields: React.FC<FlyoutHeaderFieldsProps> = ({\n cells,\n recordData,\n interactive,\n instrumentation,\n textColor,\n subtitleColor,\n onButtonClick,\n}) => {\n const chevronRef = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n\n return (\n <div\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'flex-end',\n flexWrap: 'wrap',\n gap: 0,\n }}\n >\n {cells.map((cell, index) => (\n <div\n key={cell.id}\n {...instrumentAttrs(instrumentation, cell.id, 'cell', `header/cells/${cell.id}`)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 0,\n }}\n >\n {index > 0 && (\n <div\n style={{\n width: 1,\n height: 24,\n backgroundColor: 'rgba(0,0,0,0.1)',\n margin: '0 12px',\n }}\n />\n )}\n <HeaderFieldSummary\n cell={cell}\n recordData={recordData}\n textColor={textColor}\n subtitleColor={subtitleColor}\n />\n </div>\n ))}\n <div\n ref={chevronRef}\n data-runtime-chrome=\"header-flyout-chevron\"\n style={{ display: 'flex', alignItems: 'center', marginLeft: 4 }}\n >\n <IconButton\n iconProps={{ iconName: open ? 'ChevronUp' : 'ChevronDown' }}\n title={open ? 'Collapse header fields' : 'Expand header fields'}\n ariaLabel={open ? 'Collapse header fields' : 'Expand header fields'}\n onClick={() => setOpen((v) => !v)}\n styles={{\n root: {\n color: textColor,\n backgroundColor: 'transparent',\n width: 32,\n height: 32,\n },\n icon: { fontSize: 16 },\n }}\n />\n </div>\n {open && chevronRef.current && (\n <Callout\n target={chevronRef.current}\n onDismiss={() => setOpen(false)}\n directionalHint={DirectionalHint.bottomRightEdge}\n gapSpace={4}\n isBeakVisible={false}\n styles={{ root: { boxShadow: '0 3px 12px rgba(0,0,0,0.15)' } }}\n >\n <div\n data-runtime-chrome=\"header-flyout-callout\"\n style={{ padding: 16, minWidth: 280, display: 'flex', flexDirection: 'column', gap: 12 }}\n >\n {cells.map((cell) =>\n cell.control ? (\n <div key={cell.id} style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>\n <div style={{ fontSize: 12, color: '#605e5c' }}>\n {cell.control.label || 'Field'}\n {cell.control.required ? (\n <span style={{ color: '#d13438', marginLeft: 2 }}>*</span>\n ) : null}\n </div>\n <DispatchedControl\n control={{ ...cell.control, hideLabel: true }}\n recordData={recordData}\n interactive={interactive}\n onButtonClick={onButtonClick}\n />\n </div>\n ) : null,\n )}\n </div>\n </Callout>\n )}\n </div>\n );\n};\n\ninterface HeaderFieldSummaryProps {\n cell: FormCell;\n recordData?: Record<string, unknown> | null;\n textColor: string;\n subtitleColor: string;\n}\n\nconst HeaderFieldSummary: React.FC<HeaderFieldSummaryProps> = ({\n cell,\n recordData,\n textColor,\n subtitleColor,\n}) => {\n const control = cell.control;\n if (!control) {\n return <SummaryTile value=\"---\" label=\"Empty\" textColor={textColor} subtitleColor={subtitleColor} />;\n }\n\n const displayValue = resolveDisplayValue(control, recordData);\n const isLookup = control.type === 'lookup';\n const targetEntity = (control.properties?.targetEntity as string | undefined) ?? '';\n const isPersonLookup = isLookup && PERSON_ENTITIES.has(targetEntity);\n const showPersona = isPersonLookup && displayValue !== '---';\n\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {showPersona && (\n <Persona\n text={displayValue}\n imageInitials={getInitials(displayValue)}\n size={PersonaSize.size32}\n hidePersonaDetails\n // Persona's initialsColor enum is keyed by name; map our hex\n // palette pick onto the string by coercion — Persona accepts\n // a CSS color string here too.\n initialsColor={getPersonaColor(displayValue) as unknown as PersonaInitialsColor}\n styles={{ root: { flexShrink: 0 } }}\n data-runtime-chrome=\"header-field-persona\"\n />\n )}\n <SummaryTile\n value={displayValue}\n label={control.label || 'Field'}\n textColor={isLookup ? '#0078d4' : textColor}\n subtitleColor={subtitleColor}\n />\n </div>\n );\n};\n\ninterface SummaryTileProps {\n value: string;\n label: string;\n textColor: string;\n subtitleColor: string;\n}\n\nconst SummaryTile: React.FC<SummaryTileProps> = ({ value, label, textColor, subtitleColor }) => (\n <div\n data-runtime-chrome=\"header-field-summary\"\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n maxWidth: 200,\n }}\n >\n <div\n style={{\n fontSize: 14,\n fontWeight: 600,\n color: textColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n title={value === '---' ? label : value}\n >\n {value}\n </div>\n <div\n style={{\n fontSize: 11,\n color: subtitleColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {label}\n </div>\n </div>\n);\n\n/**\n * Pick the value to render in the summary tile. Reads from\n * recordData via the control's dataBinding when present (matches the\n * runtime's normal dispatcher contract), then falls back to the\n * control's default / placeholder, then to '---'.\n */\nfunction resolveDisplayValue(\n control: ControlDefinition,\n recordData?: Record<string, unknown> | null,\n): string {\n const attr = control.dataBinding?.attributeLogicalName;\n if (attr && recordData) {\n // Prefer the OData FormattedValue annotation when present — it's\n // already locale + display-name-resolved (e.g. a lookup id becomes\n // its primaryname). Falls through to the raw value otherwise.\n const formatted = recordData[`${attr}@OData.Community.Display.V1.FormattedValue`];\n if (formatted != null && formatted !== '') return String(formatted);\n const raw = recordData[attr];\n if (raw != null && raw !== '') {\n if (raw instanceof Date) return raw.toLocaleDateString();\n if (typeof raw === 'boolean') return raw ? 'Yes' : 'No';\n return String(raw);\n }\n }\n const defaultValue = control.properties?.defaultValue as string | undefined;\n const placeholder = control.properties?.placeholder as string | undefined;\n return defaultValue || placeholder || '---';\n}\n","/**\n * Control dispatcher — maps a `ControlDefinition.type` to the\n * per-type renderer extracted in Phase 6.5f (Task 17). The dispatcher\n * is the single place that knows the full control taxonomy; the\n * surrounding `<FormRuntime>` shell pulls value/effectiveValue\n * computation up here so per-type files stay focused on UI.\n *\n * Routes legacy + chart types:\n * - `phone` / `email` / `url` → `UnknownControl` (legacy fallback\n * handles them via the `LEGACY_FORMAT_MAP`)\n * - 12 chart types → `ChartBranch`\n * - other type literals → the matching per-type file\n * - anything else → `UnknownControl`\n */\n\nimport React from 'react';\nimport type { ControlDefinition, ControlType } from '../../types';\nimport type { ControlPartProps } from './types';\nimport {\n SpacerControl,\n LabelControl,\n FormLinkControl,\n UnknownControl,\n TextControl,\n TextareaControl,\n NumberControl,\n DateControl,\n CheckboxControl,\n ToggleControl,\n SliderControl,\n RatingControl,\n SpinButtonControl,\n DropdownControl,\n ComboBoxControl,\n ChoiceGroupBranch,\n LookupBranch,\n WebResourceBranch,\n ChartBranch,\n PersonaControl,\n ButtonControl,\n SubgridBranch,\n TimelineControl,\n} from './index';\n\nconst CHART_TYPES: ReadonlySet<string> = new Set([\n 'barchart',\n 'linechart',\n 'areachart',\n 'piechart',\n 'donutchart',\n 'horizontalbarchart',\n 'gaugechart',\n 'sparkline',\n 'heatmapchart',\n 'kpicard',\n 'funnelchart',\n 'scatterchart',\n]);\n\ntype ControlComponent = React.FC<ControlPartProps>;\n\nconst REGISTRY: Partial<Record<ControlType, ControlComponent>> = {\n spacer: SpacerControl,\n label: LabelControl,\n formlink: FormLinkControl,\n text: TextControl,\n textarea: TextareaControl,\n number: NumberControl,\n decimal: NumberControl,\n currency: NumberControl,\n date: DateControl,\n datetime: DateControl,\n checkbox: CheckboxControl,\n toggle: ToggleControl,\n slider: SliderControl,\n rating: RatingControl,\n spinbutton: SpinButtonControl,\n dropdown: DropdownControl,\n optionset: DropdownControl,\n combobox: ComboBoxControl,\n choicegroup: ChoiceGroupBranch as ControlComponent,\n lookup: LookupBranch as ControlComponent,\n webresource: WebResourceBranch as ControlComponent,\n persona: PersonaControl,\n button: ButtonControl,\n subgrid: SubgridBranch as ControlComponent,\n timeline: TimelineControl,\n};\n\n/**\n * Resolve which per-type component should render `controlType`. Returns\n * `UnknownControl` for any type not in the registry (covers the legacy\n * phone/email/url path inside UnknownControl plus genuinely unknown\n * future types). Chart types route to `ChartBranch`.\n */\nexport function resolveControlComponent(controlType: string): ControlComponent {\n if (CHART_TYPES.has(controlType)) {\n return ChartBranch as ControlComponent;\n }\n return REGISTRY[controlType as ControlType] ?? UnknownControl;\n}\n\n/**\n * Inputs the dispatcher needs from the surrounding shell to compute\n * `ControlPartProps` for the resolved component.\n */\nexport interface DispatchControlInputs {\n control: ControlDefinition;\n /** Controlled value override (takes precedence over record-bound value). */\n controlledValue?: unknown;\n /** Bound record (live or mock). When supplied, looked up by attribute name. */\n recordData?: Record<string, unknown> | null;\n /** When false, controls disable and the legacy designMode affordances show. */\n interactive: boolean;\n /** Bubbles up edits — same shape every per-type file expects. */\n onChange?: (next: unknown) => void;\n /** Bubbles up button-click actions (used by ButtonControl + FormLinkControl). */\n onButtonClick?: (action: unknown) => void;\n}\n\n/** Read a value from `recordData` for a bound control, preferring\n * Dataverse's formatted-value annotation when present. */\nfunction getBoundValue(\n control: ControlDefinition,\n recordData: Record<string, unknown> | null | undefined,\n): unknown {\n if (!recordData || !control.dataBinding?.attributeLogicalName) return undefined;\n const fieldName = control.dataBinding.attributeLogicalName;\n const formattedKey = `${fieldName}@OData.Community.Display.V1.FormattedValue`;\n if (formattedKey in recordData && recordData[formattedKey] !== undefined) {\n return recordData[formattedKey];\n }\n return recordData[fieldName];\n}\n\n/**\n * Build the `ControlPartProps` the resolved per-type file expects.\n * The shell calls this once per cell so per-type files don't each\n * repeat the value-precedence rule.\n */\nexport function buildControlPartProps(inputs: DispatchControlInputs): ControlPartProps {\n const { control, controlledValue, recordData, interactive, onChange, onButtonClick } = inputs;\n const hasControlledValue = controlledValue !== undefined;\n const boundValue = getBoundValue(control, recordData);\n const effectiveValue = hasControlledValue ? controlledValue : boundValue;\n const hasValue = effectiveValue !== undefined && effectiveValue !== null && effectiveValue !== '';\n const displayValue = effectiveValue == null ? '' : String(effectiveValue);\n return {\n control,\n effectiveValue,\n displayValue,\n hasValue,\n hasControlledValue,\n interactive,\n onChange,\n onButtonClick,\n };\n}\n\n/**\n * Stateless dispatch component. Resolves the per-type renderer for\n * `control.type` and forwards the computed `ControlPartProps`.\n * Wrap with `<FormRuntime>` to get value resolution + instrumentation;\n * tests can use this directly with hand-rolled props.\n */\nexport const DispatchedControl: React.FC<DispatchControlInputs> = (inputs) => {\n const Component = resolveControlComponent(inputs.control.type);\n const props = buildControlPartProps(inputs);\n return <Component {...props} />;\n};\n","/**\n * Designer-mode instrumentation helpers.\n *\n * When `<FormRuntime instrumentation=\"designer\">` is mounted, every\n * structural element (tab, section, row, cell, control, header,\n * command-bar item, grid item) gets `data-element-id`,\n * `data-element-type`, and `data-element-path` attributes so the\n * designer overlay (Phase 2) can locate, measure, and decorate them\n * with selection chrome, drop zones, badges, etc.\n *\n * The helpers return plain attribute objects rather than React props\n * so they're trivial to spread onto host elements without importing\n * `@types/react` into the surface (matches the same pattern used by\n * `gridLayoutUtils.GridPositionStyle`).\n */\n\nexport type InstrumentationMode = 'designer' | 'off';\n\nexport type ElementType =\n | 'header'\n | 'commandBarItem'\n | 'tab'\n | 'column'\n | 'section'\n | 'row'\n | 'cell'\n | 'control'\n | 'gridItem'\n | 'bpf';\n\nexport interface InstrumentationAttrs {\n 'data-element-id'?: string;\n 'data-element-type'?: ElementType;\n 'data-element-path'?: string;\n}\n\n/**\n * Emit instrumentation attributes for a structural element. When the\n * runtime isn't in designer mode, returns an empty object so the\n * spread is a no-op and no extra DOM attributes are emitted in\n * deployed runtimes.\n */\nexport function instrumentAttrs(\n mode: InstrumentationMode,\n id: string,\n type: ElementType,\n path?: string,\n): InstrumentationAttrs {\n if (mode !== 'designer') return {};\n return {\n 'data-element-id': id,\n 'data-element-type': type,\n 'data-element-path': path,\n };\n}\n\n/** Path helpers — string composition so paths read top-down. */\nexport const paths = {\n header(): string {\n return 'header';\n },\n commandBarItem(itemId: string): string {\n return `commandBar/${itemId}`;\n },\n tab(tabId: string): string {\n return `tabs/${tabId}`;\n },\n column(tabPath: string, colIdx: number): string {\n return `${tabPath}/columns/${colIdx}`;\n },\n section(parentPath: string, sectionId: string): string {\n return `${parentPath}/sections/${sectionId}`;\n },\n row(sectionPath: string, rowId: string): string {\n return `${sectionPath}/rows/${rowId}`;\n },\n cell(rowPath: string, cellId: string): string {\n return `${rowPath}/cells/${cellId}`;\n },\n control(cellPath: string, controlName: string): string {\n return `${cellPath}/control/${controlName}`;\n },\n gridItem(sectionId: string): string {\n return `gridItems/${sectionId}`;\n },\n callout(parentPath: string, calloutId: string): string {\n return `${parentPath}/callout/${calloutId}`;\n },\n};\n","/**\n * CommandBarShell — top command bar for main forms.\n *\n * Renders the configured `FormDefinition.commandBar` items as Fluent UI\n * v8 CommandBar buttons. Overflow / far positions are honored via\n * Fluent's `overflowItems` and `farItems`. Click handlers route up\n * through `onCommandClick` so the host decides what to do (save,\n * navigate, run action).\n */\n\nimport React, { useMemo } from 'react';\nimport { CommandBar, type ICommandBarItemProps } from '@fluentui/react';\nimport type { CommandBarItem, FormDefinition } from '../types';\nimport { instrumentAttrs, paths, type InstrumentationMode } from '../instrumentation';\n\nexport interface CommandBarShellProps {\n form: FormDefinition;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCommandClick?: (item: CommandBarItem) => void;\n}\n\nfunction toFluentItem(\n item: CommandBarItem,\n interactive: boolean,\n onCommandClick?: (item: CommandBarItem) => void,\n): ICommandBarItemProps {\n return {\n key: item.id,\n text: item.iconOnly ? undefined : item.text,\n iconProps: item.iconName ? { iconName: item.iconName } : undefined,\n iconOnly: item.iconOnly === true,\n ariaLabel: item.text,\n disabled: !interactive,\n onClick: onCommandClick ? () => onCommandClick(item) : undefined,\n };\n}\n\nexport const CommandBarShell: React.FC<CommandBarShellProps> = ({\n form,\n interactive,\n instrumentation,\n onCommandClick,\n}) => {\n const items = form.commandBar ?? [];\n const showCommandBar = form.settings?.showCommandBar ?? true;\n\n const grouped = useMemo(() => {\n const primary: ICommandBarItemProps[] = [];\n const overflow: ICommandBarItemProps[] = [];\n const far: ICommandBarItemProps[] = [];\n for (const item of items) {\n const fluent = toFluentItem(item, interactive, onCommandClick);\n // Spread instrumentation onto the buttonProps so the overlay can\n // address command-bar items individually.\n const instrumented: ICommandBarItemProps = {\n ...fluent,\n // CommandBar passes unknown props through to the inner button.\n ...(instrumentation === 'designer'\n ? {\n ...instrumentAttrs(\n instrumentation,\n item.id,\n 'commandBarItem',\n paths.commandBarItem(item.id),\n ),\n }\n : {}),\n };\n switch (item.position) {\n case 'primary':\n primary.push(instrumented);\n break;\n case 'overflow':\n overflow.push(instrumented);\n break;\n case 'far':\n far.push(instrumented);\n break;\n }\n }\n return { primary, overflow, far };\n }, [items, interactive, instrumentation, onCommandClick]);\n\n if (!showCommandBar || items.length === 0) return null;\n\n return (\n <CommandBar\n items={grouped.primary}\n overflowItems={grouped.overflow.length > 0 ? grouped.overflow : undefined}\n farItems={grouped.far.length > 0 ? grouped.far : undefined}\n styles={{ root: { padding: 0, borderBottom: '1px solid #edebe9' } }}\n />\n );\n};\n","/**\n * BpfShell — Business Process Flow progress indicator.\n *\n * Scaffolded for Phase 1. The BPF designer + progress indicators live\n * in the form-builder app today; this shell renders a minimal stage\n * strip so the runtime tree has somewhere to drop the BPF in\n * `<FormRuntime>`. The full pivot through stages / steps + the chevron\n * / circle / minimal variants land in a follow-up.\n *\n * When the form has no `bpfId`, the shell renders nothing.\n */\n\nimport React from 'react';\nimport type { FormDefinition } from '../types';\nimport { instrumentAttrs, type InstrumentationMode } from '../instrumentation';\n\nexport interface BpfShellProps {\n form: FormDefinition;\n instrumentation: InstrumentationMode;\n}\n\nexport const BpfShell: React.FC<BpfShellProps> = ({ form, instrumentation }) => {\n const bpfId = form.settings?.bpfId;\n if (!bpfId || form.settings?.showBpfProgress === false) return null;\n return (\n <div\n {...instrumentAttrs(instrumentation, `bpf:${bpfId}`, 'bpf', `bpf/${bpfId}`)}\n style={{\n padding: '8px 16px',\n borderBottom: '1px solid #edebe9',\n backgroundColor: '#f3f2f1',\n fontSize: 12,\n color: '#605e5c',\n }}\n >\n Business Process Flow: {bpfId}\n </div>\n );\n};\n","/**\n * TabsShell — tabbed-form layout. Renders the tab strip plus the\n * sections of the active main tab. Related / audit tabs render a\n * placeholder until those surfaces fully migrate to runtime (Phase 1+\n * follow-up).\n */\n\nimport React, { useState } from 'react';\nimport { Pivot, PivotItem } from '@fluentui/react';\nimport type { FormDefinition, FormTab } from '../types';\nimport { isMainTab, isRelatedTab, isAuditTab } from '../types';\nimport { SectionShell } from './SectionShell';\nimport { instrumentAttrs, paths, type InstrumentationMode } from '../instrumentation';\nimport type { DispatchControlInputs } from '../v8/controls/dispatcher';\nimport { useRuleStates } from '../context/RuleStatesContext';\nimport { useTabContentSlots } from '../context/TabContentSlotsContext';\n\nexport interface TabsShellProps {\n form: FormDefinition;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nexport const TabsShell: React.FC<TabsShellProps> = ({\n form,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n // Rule-driven tab visibility — hide whole tabs when a rule's\n // tabState has visible=false. Missing entries mean \"no constraint\".\n // Matches the legacy MainFormPreview filter:\n // form.tabs.filter(t => !ruleTabStates[t.id] || ruleTabStates[t.id].visible)\n const { tabStates } = useRuleStates();\n const allTabs = form.tabs ?? [];\n const tabs = allTabs.filter((t) => {\n const ts = tabStates[t.id];\n return !ts || ts.visible;\n });\n // Default-selected tab keeps a stable id even when rules reshape the\n // visible set — fall back to first visible when the original selection\n // gets hidden.\n const [selectedId, setSelectedId] = useState<string>(allTabs[0]?.id ?? '');\n if (tabs.length === 0) return null;\n const effectiveSelected = tabs.some((t) => t.id === selectedId) ? selectedId : tabs[0].id;\n\n return (\n <Pivot\n selectedKey={effectiveSelected}\n onLinkClick={(item) => {\n if (item?.props.itemKey) setSelectedId(item.props.itemKey);\n }}\n styles={{ root: { padding: '0 8px' } }}\n >\n {tabs.map((tab) => (\n <PivotItem key={tab.id} itemKey={tab.id} headerText={tab.label}>\n <div\n {...instrumentAttrs(instrumentation, tab.id, 'tab', paths.tab(tab.id))}\n style={{ padding: '8px 0' }}\n >\n <TabBody\n tab={tab}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n </div>\n </PivotItem>\n ))}\n </Pivot>\n );\n};\n\ninterface TabBodyProps {\n tab: FormTab;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nconst TabBody: React.FC<TabBodyProps> = ({\n tab,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n // Host-supplied overrides for related / audit tab content. Falls\n // through to the runtime's placeholder when no slot is provided\n // (matches the pre-m6 default — the runtime doesn't ship a related-\n // records data layer).\n const slots = useTabContentSlots();\n\n if (isMainTab(tab)) {\n const tabPath = paths.tab(tab.id);\n const layout = tab.layout;\n const columnCount = layout?.columns ?? 1;\n const groupedByColumn: Record<number, typeof tab.sections> = {};\n tab.sections.forEach((section) => {\n const col = section.tabColumn ?? 0;\n if (!groupedByColumn[col]) groupedByColumn[col] = [];\n groupedByColumn[col].push(section);\n });\n\n return (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`,\n gap: 12,\n }}\n >\n {Array.from({ length: columnCount }).map((_, idx) => {\n // Column wrapper carries a stable id so the overlay can\n // target cross-column section drops. The id encodes both\n // the tab and the column index so a 2-tab × 3-column form\n // produces six distinct addressable columns.\n const columnId = `${tab.id}:col${idx}`;\n return (\n <div\n key={idx}\n {...instrumentAttrs(\n instrumentation,\n columnId,\n 'column',\n paths.column(tabPath, idx),\n )}\n data-tab-id={tab.id}\n data-column-index={idx}\n style={{ display: 'flex', flexDirection: 'column', gap: 12, minHeight: 24 }}\n >\n {(groupedByColumn[idx] ?? []).map((section) => (\n <SectionShell\n key={section.id}\n section={section}\n parentPath={tabPath}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n ))}\n </div>\n );\n })}\n </div>\n );\n }\n\n if (isRelatedTab(tab)) {\n if (slots.renderRelatedTab) return <>{slots.renderRelatedTab(tab)}</>;\n return (\n <div style={{ padding: 16, color: '#605e5c', fontSize: 12 }}>\n Related records preview — provide TabContentSlots.renderRelatedTab to render.\n Entity: {tab.relatedConfig?.entityDisplayName ?? tab.relatedConfig?.entityLogicalName}\n </div>\n );\n }\n\n if (isAuditTab(tab)) {\n if (slots.renderAuditTab) return <>{slots.renderAuditTab(tab)}</>;\n return (\n <div style={{ padding: 16, color: '#605e5c', fontSize: 12 }}>\n Audit history preview — provide TabContentSlots.renderAuditTab to render.\n </div>\n );\n }\n\n return null;\n};\n","import { ControlDefinition, SubgridColumn } from './control';\nimport { FormThemeSettings, BackgroundConfig } from './theme';\nimport type { NavigationAction, FormParameter } from './navigation';\n\nexport type FormType = 'main' | 'dialog' | 'panel' | 'callout';\n\n/**\n * Layout mode for a form. Tabbed forms use the classic tab/section/row/cell\n * flow; grid forms place sections as tiles on a CSS Grid (dashboard-style).\n *\n * Defaulting absent values to `'tabbed'` at read time preserves backwards\n * compatibility with v12 projects (see StorageService migration v12 → v13).\n */\nexport type FormLayoutMode = 'tabbed' | 'grid';\n\n/**\n * Grid container configuration used when `FormDefinition.layoutMode === 'grid'`.\n * Sections position themselves with `FormSection.gridPosition`; sections lacking\n * a position get auto-placed by the renderer (top-to-bottom, column-first).\n */\nexport interface FormGridLayout {\n /** Total columns in the grid (e.g. 12 for a responsive 12-column grid). */\n columns: number;\n /** Auto-row height in pixels. Sections span H rows. */\n rowHeight: number;\n /** Gap between grid cells in pixels (applies to both axes). */\n gap: number;\n /** Optional responsive column overrides — designer hint only in v1. */\n breakpoints?: { sm?: number; md?: number; lg?: number };\n}\n\n/** Default grid layout applied when a form is created in grid mode. */\nexport const DEFAULT_FORM_GRID_LAYOUT: FormGridLayout = {\n columns: 12,\n rowHeight: 80,\n gap: 12,\n};\n\n// ============================================================================\n// Dialog Action Buttons\n// ============================================================================\n\n/** Button appearance style */\nexport type DialogButtonAppearance = 'primary' | 'default' | 'subtle';\n\n/** Button position in dialog footer */\nexport type DialogButtonPosition = 'left' | 'right';\n\n/**\n * Action to perform when a dialog button is clicked.\n * Supports close, submit, navigate, and custom actions.\n */\nexport type DialogButtonAction =\n | { type: 'close' } // Close dialog without saving\n | { type: 'submit' } // Submit form and close\n | { type: 'navigate'; target: NavigationAction } // Navigate to another form/URL\n | { type: 'custom'; actionId: string }; // Custom JS action identifier\n\n/**\n * Configuration for a dialog action button.\n * Used in dialog footers for confirm/cancel/custom actions.\n */\nexport interface DialogActionButton {\n /** Unique identifier */\n id: string;\n /** Button label text */\n label: string;\n /** Optional Fluent UI icon name */\n icon?: string;\n /** Button appearance style */\n appearance: DialogButtonAppearance;\n /** Position in dialog footer (left or right side) */\n position: DialogButtonPosition;\n /** Sort order within position group (lower = first) */\n order: number;\n /** Whether button is disabled */\n disabled?: boolean;\n /** Whether button is hidden */\n hidden?: boolean;\n /** Action when button is clicked */\n action: DialogButtonAction;\n}\n\nexport type CommandBarItemPosition = 'primary' | 'overflow' | 'far';\n\n/**\n * Where a command bar item is shown. Only meaningful for grid/subgrid\n * command bars (which also expose a row right-click menu); form-level\n * command bars treat any value as `commandBar`. Defaults to `both` at\n * read time so legacy items keep their current behavior.\n */\nexport type CommandBarItemVisibility = 'commandBar' | 'contextMenu' | 'both';\n\n/**\n * Default Dynamics action behaviors that a command bar item can be wired to.\n * - `custom` no default behavior (legacy items default here)\n * - `navigate` opens another form via `navigationAction`\n * - `new` opens the create form for the grid's entity\n * - `addExisting` opens the lookup dialog to associate an existing record\n * (only valid on related/nested grids)\n * - `edit` opens the edit form for the selected row; multi-select\n * falls through to the OOB bulk edit form\n * - `delete` deletes selected rows via `Xrm.WebApi.deleteRecord`\n * - `activate` sets statecode to active for selected rows\n * - `deactivate` sets statecode to inactive for selected rows\n * - `refresh` re-fetches the grid (always whole-grid)\n * - `export` exports the current view (always whole-grid)\n * - `bulkEdit` explicitly invokes `Xrm.Navigation.openBulkEditForm`\n */\nexport type CommandBarItemActionType =\n | 'custom'\n | 'navigate'\n | 'new'\n | 'addExisting'\n | 'edit'\n | 'delete'\n | 'activate'\n | 'deactivate'\n | 'refresh'\n | 'export'\n | 'bulkEdit';\n\n/**\n * Whether an action operates on selected rows or the whole grid.\n * - `auto` derived from `actionType`. Resolution:\n * refresh/export/new/addExisting → grid;\n * edit/delete/activate/deactivate/bulkEdit → selection;\n * navigate/custom → grid (caller decides).\n * - `selection` requires at least one selected row\n * - `grid` operates on the whole grid\n */\nexport type CommandBarItemActionScope = 'auto' | 'selection' | 'grid';\n\nexport interface CommandBarItem {\n id: string;\n text: string;\n iconName: string;\n position: CommandBarItemPosition;\n iconOnly?: boolean;\n /**\n * Optional visibility override (grids only). Defaults to `both` —\n * the item appears in both the toolbar and the row right-click menu.\n */\n visibility?: CommandBarItemVisibility;\n /** Navigation action when clicked (opens another form) */\n navigationAction?: NavigationAction;\n /**\n * Default Dynamics action behavior. Defaults to `custom` for legacy items\n * (no wired behavior). When set to `navigate`, `navigationAction` is used.\n */\n actionType?: CommandBarItemActionType;\n /** Whether the action operates on selected rows or the whole grid. Defaults to `auto`. */\n actionScope?: CommandBarItemActionScope;\n /**\n * Hide this item until at least N rows are selected. `0` (or undefined)\n * means always show. Most useful for `delete`, `edit`, `activate`,\n * `deactivate`, and `bulkEdit` — defaults are derived from `actionType`\n * when this is unset.\n */\n minSelectionCount?: number;\n}\n\n/** Number of header field slots (0-4) */\nexport type HeaderSlotCount = 0 | 1 | 2 | 3 | 4;\n\n/** Header display modes */\nexport type HeaderDisplayMode = 'inline' | 'flyout';\n\n/** Persona size options for header */\nexport type HeaderPersonaSize = 'size32' | 'size48' | 'size72';\n\n/** Preset colors for persona avatar */\nexport type HeaderPersonaColor =\n | 'lightBlue'\n | 'blue'\n | 'darkBlue'\n | 'teal'\n | 'lightGreen'\n | 'green'\n | 'darkGreen'\n | 'lightPink'\n | 'pink'\n | 'magenta'\n | 'purple'\n | 'orange'\n | 'red'\n | 'darkRed'\n | 'violet'\n | 'gold'\n | 'burgundy'\n | 'warmGray'\n | 'coolGray'\n | 'cyan'\n | 'rust'\n | 'custom';\n\n/** Source mode for header persona data */\nexport type HeaderPersonaSourceMode = 'static' | 'dataverse';\n\n/** Configuration for the header persona/avatar */\nexport interface HeaderPersonaConfig {\n /** Whether to show the persona in the header */\n enabled: boolean;\n /** Source mode: 'static' for manual text/image, 'dataverse' for record-driven */\n sourceMode?: HeaderPersonaSourceMode;\n\n // ── Static mode properties ──\n /** Field logical name to use for the display name (e.g., \"fullname\", \"name\") */\n nameField?: string;\n /** Field logical name to use for the image URL (e.g., \"entityimage_url\") */\n imageField?: string;\n /** Secondary text to display (e.g., entity type). Leave empty to use entity display name */\n secondaryText?: string;\n /** Whether to show the secondary text line */\n showSecondaryText?: boolean;\n /** Size of the persona avatar */\n size?: HeaderPersonaSize;\n /** Preset color for the avatar background */\n color?: HeaderPersonaColor;\n /** Custom hex color (used when color is 'custom') */\n customColor?: string;\n /** Static image URL or base64 data URL for the avatar */\n imageUrl?: string;\n /** Whether to use an uploaded image instead of initials */\n useImage?: boolean;\n\n // ── Dataverse record mode properties ──\n /** Dataverse entity logical name (e.g., 'systemuser', 'contact', 'account') */\n dvRecordEntityName?: string;\n /** Selected record ID */\n dvRecordId?: string;\n /** Selected record primary name */\n dvRecordName?: string;\n /** Selected record secondary text (jobtitle, description, etc.) */\n dvRecordSecondaryText?: string;\n /** Base64 data URL of the record's entity image */\n dvRecordImageDataUrl?: string;\n /** Whether the record is disabled (systemuser only, for presence derivation) */\n dvRecordIsDisabled?: boolean;\n /** Show presence indicator */\n showPresence?: boolean;\n /** Presence status override */\n presence?: string;\n}\n\nexport interface FormHeader {\n /** Display title shown in header; falls back to form.name when empty */\n title?: string;\n /** Subtitle shown below title; falls back to form type label when empty */\n subtitle?: string;\n /** Manual title text color override. Overrides auto-contrast when set. */\n titleColor?: string;\n /** Manual subtitle text color override. Overrides auto-contrast when set. */\n subtitleColor?: string;\n /** Number of field slots to display (0-4), defaults to 4 */\n slotCount?: HeaderSlotCount;\n /** Persona configuration for showing an avatar with name */\n persona?: HeaderPersonaConfig;\n cells: FormCell[];\n}\n\nexport interface FormDefinition {\n id: string;\n name: string;\n type: FormType;\n /**\n * Layout mode. `'tabbed'` (default) uses the classic tabs/sections flow.\n * `'grid'` places sections as tiles on a CSS Grid (dashboard-style). Only\n * meaningful when `type === 'main'` in v1; dialog/panel/callout ignore it.\n * Absent on v12-and-earlier projects → treated as `'tabbed'`.\n */\n layoutMode?: FormLayoutMode;\n /**\n * Grid container configuration. Only read when `layoutMode === 'grid'`.\n * Undefined means use `DEFAULT_FORM_GRID_LAYOUT`.\n */\n gridLayout?: FormGridLayout;\n settings: FormSettings;\n /** Header fields for main forms (up to 4 key fields) */\n header?: FormHeader;\n /** Command bar items for main forms */\n commandBar?: CommandBarItem[];\n /** Tabs for main forms */\n tabs: FormTab[];\n /** Flat sections for dialog/panel/callout */\n sections: FormSection[];\n\n /** Display order within type category (for sidebar organization) */\n order?: number;\n /** Description for documentation */\n description?: string;\n /** Parameters this form accepts when opened from another form */\n inputParameters?: FormParameter[];\n /** ID of the template this form was created from (for template editing workflow) */\n sourceTemplateId?: string;\n\n /** Embedded callout definitions owned by this form */\n callouts?: CalloutDefinition[];\n /** Callout-to-target attachments (maps callouts to controls/sections/etc.) */\n calloutAttachments?: CalloutAttachment[];\n}\n\n/** Aggregate function types supported in FetchXML */\nexport type FetchXmlAggregateFunction = 'avg' | 'count' | 'countcolumn' | 'max' | 'min' | 'sum';\n\n/** Attribute parsed from FetchXML */\nexport interface FetchXmlAttribute {\n /** The logical name of the attribute, e.g., \"fullname\" */\n logicalName: string;\n /** Optional alias if specified in FetchXML */\n alias?: string;\n /** If from a link-entity, the alias of that link-entity */\n linkedEntityAlias?: string;\n /** Whether to use the formatted value (e.g., \"Active\" instead of 0 for option sets) */\n useFormattedValue?: boolean;\n /** Aggregate function if this is an aggregate attribute (avg, count, countcolumn, max, min, sum) */\n aggregateFunction?: FetchXmlAggregateFunction;\n}\n\n/**\n * A FetchXML-based data source.\n *\n * The FIRST entry in `form.settings.dataSources` is the form's primary source and carries\n * the primary-entity metadata fields (entitySetName, primaryIdAttribute, etc.) needed for\n * runtime record fetching and PCF manifest generation. Secondary entries (index >= 1) are\n * related-record queries and may leave the primary-only fields undefined.\n */\nexport interface FormDataSource {\n /** Unique identifier for this data source */\n id: string;\n /** User-friendly name, e.g., \"Related Contacts\" */\n name: string;\n /** The raw FetchXML query */\n fetchXml: string;\n /** Entity name parsed from <entity name=\"...\"> */\n entityName: string;\n /** Attributes parsed from <attribute name=\"...\"/> */\n attributes: FetchXmlAttribute[];\n /** Placeholder tokens like {*accountid*} found in the FetchXML */\n placeholders: string[];\n /**\n * Include formatted values in API response.\n * When true, adds `Prefer: odata.include-annotations=\"OData.Community.Display.V1.FormattedValue\"`\n * header to the request. This provides display names for option sets, lookups, dates, etc.\n */\n includeFormattedValues?: boolean;\n /** True if fetch element has aggregate='true' - returns computed values instead of records */\n isAggregate?: boolean;\n\n // --- Primary-entity metadata (populated only on dataSources[0]) ---\n\n /** OData entity set name, e.g., \"accounts\". Required on the primary source for record fetch. */\n entitySetName?: string;\n /** Primary key attribute, e.g., \"accountid\". Required on the primary source. */\n primaryIdAttribute?: string;\n /** Primary name attribute, e.g., \"name\". Used by headers and lookup displays. */\n primaryNameAttribute?: string;\n /** Localized entity display name, e.g., \"Account\". */\n displayName?: string;\n /** Localized plural entity display name, e.g., \"Accounts\". */\n displayNamePlural?: string;\n}\n\nexport interface FormSettings {\n width?: number;\n height?: number;\n position?: 'left' | 'right' | 'center';\n showCommandBar: boolean;\n /** Whether to show text labels on command bar items (default: true) */\n showCommandBarLabels?: boolean;\n showHeader: boolean;\n /** How header fields are displayed: 'inline' (always visible) or 'flyout' (expandable callout). Default: 'flyout' */\n headerDisplayMode?: HeaderDisplayMode;\n /**\n * FetchXML-based data sources. The first entry (index [0]) is the form's primary source,\n * carrying entity metadata (entitySetName, primaryIdAttribute, etc.). Secondary entries are\n * related-record queries. Use `getPrimaryDataSource()` from `utils/formDataSource` to read.\n */\n dataSources?: FormDataSource[];\n /** Theme configuration (preset and custom colors) */\n theme?: FormThemeSettings;\n\n /** Business rule IDs applied to this form (references project.businessRules) */\n businessRuleIds?: string[];\n\n /** Overrides for entity-scoped rules on this form */\n ruleOverrides?: { ruleId: string; enabled: boolean }[];\n\n /** Dialog action buttons (only applicable for dialog form type) */\n dialogButtons?: DialogActionButton[];\n\n /** Alignment of the dialog button footer: left, center, or right (default: 'right') */\n dialogButtonAlignment?: 'left' | 'center' | 'right';\n\n /** Optional subheader text shown below the dialog title */\n dialogSubheader?: string;\n\n /** When true, dialog sections render as Pivot tabs instead of stacking vertically */\n dialogUsePivots?: boolean;\n\n /** Column layout for dialog sections (like tab layout for main forms) */\n dialogLayout?: TabLayout;\n\n /** When true, dialog expands to full viewport width */\n dialogFullWidth?: boolean;\n\n /** Optional record counter shown in dialog header (e.g., \"3 of 12\") */\n dialogRecordCounter?: {\n enabled: boolean;\n current: number; // 1-based\n total: number;\n position?: 'left' | 'right'; // default: 'right'\n };\n\n /** Panel action buttons (footer buttons for panel form type) */\n panelButtons?: DialogActionButton[];\n /** Alignment of the panel button footer (default: 'right') */\n panelButtonAlignment?: 'left' | 'center' | 'right';\n /** Optional subheader text shown below the panel title */\n panelSubheader?: string;\n /** When true, panel sections render as Pivot tabs */\n panelUsePivots?: boolean;\n\n /** Column layout for panel sections */\n panelLayout?: TabLayout;\n /** Fluent UI PanelType for controlling panel size/position */\n panelType?: 'smallFixedFar' | 'smallFixedNear' | 'medium' | 'large' | 'largeFixed' | 'extraLarge' | 'custom' | 'customNear';\n /** Whether panel shows a close button (default: true) */\n panelHasCloseButton?: boolean;\n /** Whether clicking outside the panel dismisses it (default: false) */\n panelIsLightDismiss?: boolean;\n /** Whether footer buttons are pinned to the bottom (default: true) */\n panelIsFooterAtBottom?: boolean;\n /** Whether the panel is non-modal (allows interaction with content behind it, no overlay) */\n panelIsNonModal?: boolean;\n\n /** Business Process Flow ID this form is associated with */\n bpfId?: string;\n\n /** BPF stage ID this form is linked to (for stage-specific forms) */\n bpfStageId?: string;\n\n /** Whether to show the BPF progress indicator on this form */\n showBpfProgress?: boolean;\n\n /** BPF progress indicator alignment */\n bpfAlignment?: 'left' | 'center' | 'right';\n\n /** Whether the BPF progress indicator should span full width */\n bpfFullWidth?: boolean;\n\n // ─── Form Selector Settings ────────────────────────────────────────────────\n\n /** Whether this is the default form for the entity (only one per entity) */\n isDefaultForEntity?: boolean;\n\n /** Order in form selector dropdown (lower = first) */\n formSelectorOrder?: number;\n\n /**\n * Form group ID for manual grouping.\n * Forms with the same formGroupId are grouped together in the form selector,\n * independent of or in addition to entity binding.\n */\n formGroupId?: string;\n\n /**\n * Display name for the form group (used when this form defines a new group)\n */\n formGroupName?: string;\n\n /**\n * Optional color for the form group indicator (hex color, e.g., \"#0078d4\")\n * When set, the link icon in the sidebar uses this color instead of default blue.\n */\n formGroupColor?: string;\n\n}\n\nexport interface TabLayout {\n columns: 1 | 2 | 3;\n columnWidths: number[]; // percentage widths, length matches columns\n}\n\n// ============================================================================\n// Tab Types (Discriminated Union)\n// ============================================================================\n\n/** Base tab properties shared by all tab types */\ninterface FormTabBase {\n id: string;\n label: string;\n expanded: boolean;\n showLabel: boolean;\n}\n\n/** Main content tab with sections (existing behavior) */\nexport interface MainFormTab extends FormTabBase {\n tabType: 'main';\n layout: TabLayout;\n sections: FormSection[];\n}\n\n/** Related records tab configuration */\nexport interface RelatedTabConfig {\n /** Logical name of the related entity (e.g., \"contact\") */\n entityLogicalName: string;\n /** Display name of the related entity (e.g., \"Contacts\") */\n entityDisplayName: string;\n /** FetchXML query for retrieving related records */\n fetchXml: string;\n /** Attributes parsed from the FetchXML */\n attributes: FetchXmlAttribute[];\n /** Placeholder tokens found in the FetchXML (e.g., \"{*accountid*}\") */\n placeholders: string[];\n /** Grid display type */\n gridType: 'standard' | 'readonly';\n /** Column configuration for the grid (optional - auto-generated from attributes if not provided) */\n columns?: SubgridColumn[];\n /** Maximum rows to display (default: 5) */\n maxRows?: number;\n /** Whether to show the command bar (Add, Edit, Delete buttons) */\n showCommandBar?: boolean;\n}\n\n/** Related records tab */\nexport interface RelatedFormTab extends FormTabBase {\n tabType: 'related';\n relatedConfig: RelatedTabConfig;\n}\n\n// ============================================================================\n// Audit History Tab\n// ============================================================================\n\n/** Configuration for audit history tab */\nexport interface AuditHistoryConfig {\n /** Maximum number of audit records to display (default: 20) */\n maxRows?: number;\n /** Whether to show the user who made the change (default: true) */\n showChangedBy?: boolean;\n /** Whether to show detailed field changes (default: true) */\n showFieldChanges?: boolean;\n /** Sort order for audit records (default: 'newest') */\n sortOrder?: 'newest' | 'oldest';\n}\n\n/** Audit history tab */\nexport interface AuditFormTab extends FormTabBase {\n tabType: 'audit';\n auditConfig: AuditHistoryConfig;\n}\n\n/**\n * Union type for form tabs.\n * - Main tabs: Have sections and layout (existing behavior)\n * - Related tabs: Display related records via FetchXML\n * - Audit tabs: Display change history from the audit entity\n *\n * Note: For backward compatibility, tabs without tabType are treated as 'main'\n */\nexport type FormTab = MainFormTab | RelatedFormTab | AuditFormTab;\n\n// ============================================================================\n// Tab Type Guards\n// ============================================================================\n\n/**\n * Check if a tab is a main content tab (has sections).\n * Also handles backward compatibility for tabs without tabType property.\n */\nexport function isMainTab(tab: FormTab): tab is MainFormTab {\n return tab.tabType === 'main' || !('tabType' in tab) || tab.tabType === undefined;\n}\n\n/**\n * Check if a tab is a related records tab.\n */\nexport function isRelatedTab(tab: FormTab): tab is RelatedFormTab {\n return tab.tabType === 'related';\n}\n\n/**\n * Check if a tab is an audit history tab.\n */\nexport function isAuditTab(tab: FormTab): tab is AuditFormTab {\n return tab.tabType === 'audit';\n}\n\n/**\n * Position of a section within a grid-mode form. `x`/`y` are top-left cell\n * indices; `w`/`h` are spans in grid cells. Only read when the parent\n * `FormDefinition.layoutMode === 'grid'`. Tabbed mode ignores this field.\n */\nexport interface FormSectionGridPosition {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface FormSection {\n id: string;\n label: string;\n columns: 1 | 2 | 3 | 4;\n showLabel: boolean;\n collapsible: boolean;\n variant: 'card' | 'flat' | 'placeholder';\n tabColumn?: number; // 0-indexed column within parent tab layout\n /**\n * Grid placement for this section. Only honored when the parent form's\n * `layoutMode === 'grid'`. Absent → renderer auto-places the section.\n */\n gridPosition?: FormSectionGridPosition;\n rows: FormRow[];\n // Section sizing\n minHeight?: number; // Minimum height in pixels (optional)\n widthPercent?: number; // Width as percentage of column (1-100, optional)\n fullWidth?: boolean; // Span all columns when true (overrides tabColumn)\n /** When true, this section renders as a tab in a pivot group with adjacent pivot sections */\n isPivotTab?: boolean;\n /** Per-section background override (color, image, or gradient). When undefined, inherits from theme. */\n background?: BackgroundConfig;\n /** Manual text color override for section header label. Overrides auto-contrast when set. */\n textColor?: string;\n /** Label position: 'beside' (left of field, default) or 'above' (stacked on top) */\n labelPosition?: 'beside' | 'above';\n /** Label column width as a percentage (default 35). Only applies when labelPosition is 'beside'. */\n labelWidth?: number;\n /** Vertical gap between rows in pixels (default 4) */\n rowGap?: number;\n /** Horizontal gap between cells in pixels (default 8) */\n cellGap?: number;\n /** When true, labels wrap instead of truncating with ellipsis */\n wrapLabel?: boolean;\n /** When true, hidden fields collapse and remaining fields reflow to fill space */\n collapseHidden?: boolean;\n}\n\nexport interface FormRow {\n id: string;\n columns: 1 | 2 | 3 | 4;\n cells: FormCell[];\n}\n\nexport interface FormCell {\n id: string;\n control: ControlDefinition | null;\n colSpan: number;\n rowSpan: number;\n}\n\n// ============================================================================\n// Callout Definitions (Embedded Utilities)\n// ============================================================================\n\n/** Directional hint for callout positioning relative to target */\nexport type CalloutDirectionalHint =\n | 'topLeftEdge' | 'topCenter' | 'topRightEdge' | 'topAutoEdge'\n | 'bottomLeftEdge' | 'bottomCenter' | 'bottomRightEdge' | 'bottomAutoEdge'\n | 'leftTopEdge' | 'leftCenter' | 'leftBottomEdge'\n | 'rightTopEdge' | 'rightCenter' | 'rightBottomEdge';\n\n/** How the callout is triggered on the target element */\nexport type CalloutTrigger = 'click' | 'hover' | 'icon-click';\n\n/** Action button in callout footer */\nexport interface CalloutActionButton {\n id: string;\n label: string;\n icon?: string;\n appearance: 'primary' | 'default';\n action: 'dismiss' | 'submit';\n}\n\n/** A field binding for data-bound grid callouts */\nexport interface CalloutFieldBinding {\n id: string;\n /** Row field name to read the value from */\n fieldName: string;\n /** Display label shown in the callout */\n label: string;\n /** How to render the value */\n displayType: 'text' | 'badge' | 'currency' | 'date' | 'link' | 'icon-value';\n /** Optional icon to show next to the label */\n iconName?: string;\n /** Display order */\n order: number;\n}\n\n/**\n * A callout definition embedded within a parent form or grid.\n * Callouts are floating popups attached to controls/sections on a form,\n * or to grid columns for data-aware cell popups.\n * Static callouts use FormSection structure for content.\n * Data-bound callouts use fieldBindings resolved against row data.\n */\nexport interface CalloutDefinition {\n id: string;\n name: string;\n /** Callout width in pixels (default: 320) */\n width?: number;\n /** Position relative to target (default: bottomAutoEdge) */\n directionalHint?: CalloutDirectionalHint;\n /** Show the beak/arrow pointing to target (default: true) */\n isBeakVisible?: boolean;\n /** Beak width in pixels (default: 16) */\n beakWidth?: number;\n /** Gap between callout and target in pixels (default: 0) */\n gapSpace?: number;\n /** How the callout is triggered (default: click) */\n trigger?: CalloutTrigger;\n /** Whether clicking outside dismisses the callout (default: true) */\n dismissOnClickOutside?: boolean;\n /** Action buttons in callout footer */\n actionButtons?: CalloutActionButton[];\n /** Footer button alignment (default: right) */\n buttonAlignment?: 'left' | 'center' | 'right';\n /** When true, sections render as Pivot tabs instead of stacking vertically */\n usePivots?: boolean;\n /** Callout content (reuses existing section structure) — used when contentMode is 'static' */\n sections: FormSection[];\n /** Content mode: 'static' uses sections, 'data-bound' uses fieldBindings (default: 'static') */\n contentMode?: 'static' | 'data-bound';\n /** Field bindings for data-bound callouts — each maps a row field to a display slot */\n fieldBindings?: CalloutFieldBinding[];\n /** Tracks which factory preset was used for data-bound callouts */\n presetType?: 'lookup-detail' | 'status-detail' | 'custom';\n}\n\n/** Type of element a callout can be attached to */\nexport type CalloutTargetType = 'control' | 'section' | 'commandBarItem' | 'headerField';\n\n/** Describes a callout's attachment to a specific target element */\nexport interface CalloutAttachment {\n calloutId: string;\n targetType: CalloutTargetType;\n targetId: string;\n /** Override the callout's default trigger for this specific attachment */\n trigger?: CalloutTrigger;\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","/**\n * SectionShell — renders a single FormSection's rows + cells + controls.\n *\n * Phase 3 m1 grew this file to honor the FormSection fields that the\n * legacy `SectionPreview` (apps/form-builder/.../FormPreview.tsx) was\n * already rendering and the runtime canvas had been ignoring:\n * - `variant: 'placeholder'` → render an empty spacer\n * - `minHeight` / `widthPercent` → section dimensions\n * - `background` (color / image / gradient) → per-section override\n * - `collapsible` → header click toggles expanded state\n * - `collapseHidden` → skip rows where every cell's control is hidden\n * - `labelPosition` / `labelWidth` / `wrapLabel` → section-level\n * defaults that cascade into controls without explicit values\n * - control-level `hidden` → cell becomes visibility-hidden\n *\n * These were preview-only features in the legacy code. Lifting them\n * into the runtime makes both the editor canvas AND the preview\n * surface render identically — the goal of the WYSIWYG-canvas refactor.\n */\n\nimport React, { useState } from 'react';\nimport type { ControlDefinition, FormSection, FormRow, FormCell } from '../types';\nimport {\n DispatchedControl,\n type DispatchControlInputs,\n} from '../v8/controls/dispatcher';\nimport { instrumentAttrs, paths, type InstrumentationMode } from '../instrumentation';\nimport { backgroundConfigToCss } from '../utils/backgroundUtils';\nimport { CalloutAnchor } from './CalloutAnchor';\nimport { useCallout } from '../context/CalloutsContext';\nimport { useFieldState, useRuleStates, useSectionState } from '../context/RuleStatesContext';\nimport type { FieldState } from '../types/businessRules';\n\nexport interface SectionShellProps {\n section: FormSection;\n parentPath: string;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nexport const SectionShell: React.FC<SectionShellProps> = ({\n section,\n parentPath,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n const sectionPath = paths.section(parentPath, section.id);\n const rowGap = section.rowGap ?? 4;\n const cellGap = section.cellGap ?? 8;\n const [isExpanded, setIsExpanded] = useState(true);\n // Rule-driven section visibility — when a rule has set this section\n // to invisible, skip rendering entirely (matches the legacy preview).\n // Missing entry == \"no rule constraint\" -> render normally.\n const sectionState = useSectionState(section.id);\n if (sectionState && !sectionState.visible) return null;\n\n // Placeholder sections render as empty space — used in the dialog/panel\n // multi-column flow to balance columns without rendering chrome.\n if (section.variant === 'placeholder') {\n return (\n <div\n {...instrumentAttrs(instrumentation, section.id, 'section', sectionPath)}\n style={{\n minHeight: section.minHeight != null ? `${section.minHeight}px` : 60,\n ...(section.widthPercent != null ? { width: `${section.widthPercent}%` } : null),\n }}\n />\n );\n }\n\n const isCard = section.variant === 'card';\n const backgroundStyle = section.background\n ? backgroundConfigToCss(section.background)\n : isCard\n ? { backgroundColor: '#fff' }\n : {};\n\n // Inferred type — explicit `React.CSSProperties` annotation drags the\n // form-runtime's csstype install into the type signature, and the\n // consumer (form-builder) has its own csstype install. Dual csstype\n // trees clash; let inference flow through.\n const sectionStyle = {\n display: 'flex' as const,\n flexDirection: 'column' as const,\n gap: rowGap,\n padding: isCard ? '8px 12px' : 0,\n border: isCard ? '1px solid #edebe9' : 'none',\n borderRadius: isCard ? 2 : 0,\n ...backgroundStyle,\n ...(section.minHeight != null ? { minHeight: `${section.minHeight}px` } : null),\n ...(section.widthPercent != null ? { width: `${section.widthPercent}%` } : null),\n ...(section.background?.type === 'image' ? { position: 'relative' as const, overflow: 'hidden' as const } : null),\n };\n\n const collapsible = section.collapsible === true;\n const showBody = !collapsible || isExpanded;\n\n return (\n <section\n {...instrumentAttrs(instrumentation, section.id, 'section', sectionPath)}\n style={sectionStyle}\n >\n {section.showLabel && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n fontSize: 13,\n fontWeight: 600,\n color: section.textColor ?? '#323130',\n marginBottom: 4,\n cursor: collapsible ? 'pointer' : 'default',\n userSelect: collapsible ? 'none' : undefined,\n }}\n onClick={collapsible ? () => setIsExpanded((v) => !v) : undefined}\n >\n {collapsible && (\n <span\n aria-hidden\n style={{\n display: 'inline-block',\n width: 12,\n textAlign: 'center',\n fontSize: 10,\n transition: 'transform 0.15s',\n transform: isExpanded ? 'rotate(0deg)' : 'rotate(-90deg)',\n }}\n >\n ▾\n </span>\n )}\n <span>{section.label}</span>\n </div>\n )}\n {showBody &&\n section.rows.map((row) => (\n <RowShell\n key={row.id}\n row={row}\n section={section}\n parentPath={sectionPath}\n cellGap={cellGap}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n ))}\n </section>\n );\n};\n\ninterface RowShellProps {\n row: FormRow;\n section: FormSection;\n parentPath: string;\n cellGap: number;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nconst RowShell: React.FC<RowShellProps> = ({\n row,\n section,\n parentPath,\n cellGap,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n const rowPath = paths.row(parentPath, row.id);\n const effectiveColumns = row.columns || section.columns;\n // Read the full rule-state map once so we can ask the same question\n // (\"is this cell's control hidden\") about every cell without violating\n // the rules of hooks (no useFieldState in a loop).\n const { fieldStates } = useRuleStates();\n\n // collapseHidden: when every cell in the row is hidden, drop the row\n // entirely so the grid doesn't reserve vertical space. Rule state\n // wins over the control's own `hidden` flag — matches the legacy\n // SectionPreview's `fieldHidden = fs ? !fs.visible : defaultHidden`.\n if (section.collapseHidden) {\n const everyCellHidden = row.cells.every((cell) => {\n const fs = cell.control ? fieldStates[cell.control.name] : undefined;\n return fs ? !fs.visible : cell.control?.hidden === true;\n });\n if (everyCellHidden) return null;\n }\n\n return (\n <div\n {...instrumentAttrs(instrumentation, row.id, 'row', rowPath)}\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${effectiveColumns}, minmax(0, 1fr))`,\n gap: cellGap,\n }}\n >\n {row.cells.map((cell) => (\n <CellShell\n key={cell.id}\n cell={cell}\n section={section}\n parentPath={rowPath}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n ))}\n </div>\n );\n};\n\ninterface CellShellProps {\n cell: FormCell;\n section: FormSection;\n parentPath: string;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nconst CellShell: React.FC<CellShellProps> = ({\n cell,\n section,\n parentPath,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n const cellPath = paths.cell(parentPath, cell.id);\n const colSpan = cell.colSpan && cell.colSpan > 1 ? cell.colSpan : undefined;\n const rowSpan = cell.rowSpan && cell.rowSpan > 1 ? cell.rowSpan : undefined;\n // Rule field state — wins over the control's own props when present.\n // Mirrors the legacy SectionPreview merge: visible -> hidden override,\n // locked -> readOnly, required override.\n const fieldState = useFieldState(cell.control?.name);\n const hidden = fieldState ? !fieldState.visible : cell.control?.hidden === true;\n const effectiveControl = cell.control\n ? mergeFieldState(cell.control, fieldState)\n : undefined;\n\n // collapseHidden at the cell level collapses to zero height while\n // preserving the grid slot; the default keeps the slot reserved\n // (visibility:hidden) so siblings don't reflow on toggle. Inferred\n // style type for csstype dual-tree reasons (see sectionStyle above).\n const hiddenStyle = hidden\n ? section.collapseHidden\n ? { height: 0, overflow: 'hidden' as const, minHeight: 0 }\n : { visibility: 'hidden' as const, height: 0, overflow: 'hidden' as const }\n : undefined;\n\n return (\n <div\n {...instrumentAttrs(instrumentation, cell.id, 'cell', cellPath)}\n style={{\n gridColumn: colSpan ? `span ${colSpan}` : undefined,\n gridRow: rowSpan ? `span ${rowSpan}` : undefined,\n minWidth: 0,\n ...hiddenStyle,\n }}\n >\n {effectiveControl ? (\n <CalloutAwareSlot\n control={effectiveControl}\n section={section}\n parentPath={cellPath}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n ) : null}\n </div>\n );\n};\n\n/**\n * Wraps {@link ControlSlot} with a {@link CalloutAnchor} when the\n * control has a `calloutId` that resolves to a definition in the\n * surrounding `CalloutsProvider`. When the id is missing or doesn't\n * resolve, renders the slot directly — no chrome, no anchor wrapper.\n *\n * This is the integration point that replaces the legacy preview's\n * `CalloutControlWrapper`. Lives in SectionShell.tsx (not its own\n * file) so the cell -> control path stays readable in one place.\n */\ninterface CalloutAwareSlotProps {\n control: ControlDefinition;\n section: FormSection;\n parentPath: string;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nconst CalloutAwareSlot: React.FC<CalloutAwareSlotProps> = ({\n control,\n section,\n parentPath,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n const callout = useCallout(control.calloutId);\n const slot = (\n <ControlSlot\n control={control}\n section={section}\n parentPath={parentPath}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n );\n if (!callout) return slot;\n return (\n <CalloutAnchor\n callout={callout}\n triggerOverride={control.calloutTrigger}\n parentPath={paths.control(parentPath, control.name)}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n >\n {slot}\n </CalloutAnchor>\n );\n};\n\ninterface ControlSlotProps {\n control: ControlDefinition;\n section: FormSection;\n parentPath: string;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nconst ControlSlot: React.FC<ControlSlotProps> = ({\n control,\n section,\n parentPath,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n const controlPath = paths.control(parentPath, control.name);\n const isFullWidth = FULL_WIDTH_TYPES.has(control.type);\n // Section-level defaults cascade into controls that don't pin their\n // own value — mirrors what the legacy `SectionPreview` passes into\n // `ControlRenderer` as label-rendering props.\n const labelPosition = control.labelPosition ?? section.labelPosition ?? 'beside';\n const labelWidth = control.labelWidth ?? section.labelWidth ?? 35;\n const wrapLabel = control.wrapLabel ?? section.wrapLabel ?? false;\n const showLabel = !control.hideLabel && !isFullWidth;\n const handleChange = onCellValueChange ? (next: unknown) => onCellValueChange(control.name, next) : undefined;\n const slot = (\n <div\n {...instrumentAttrs(instrumentation, control.name, 'control', controlPath)}\n style={{ minWidth: 0 }}\n >\n <DispatchedControl\n control={control}\n recordData={recordData}\n interactive={interactive}\n onChange={handleChange}\n onButtonClick={onButtonClick}\n />\n </div>\n );\n\n if (isFullWidth) return slot;\n\n if (labelPosition === 'above') {\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n {showLabel && <Label control={control} wrapLabel={wrapLabel} />}\n {slot}\n </div>\n );\n }\n\n // 'beside' — label column + control column.\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {showLabel && (\n <div style={{ flexShrink: 0, width: `${labelWidth}%` }}>\n <Label control={control} wrapLabel={wrapLabel} />\n </div>\n )}\n <div style={{ flex: 1, minWidth: 0 }}>{slot}</div>\n </div>\n );\n};\n\nconst Label: React.FC<{ control: ControlDefinition; wrapLabel: boolean }> = ({ control, wrapLabel }) => (\n <span\n style={{\n fontSize: 12,\n color: control.labelColor ?? '#323130',\n overflow: 'hidden',\n textOverflow: wrapLabel ? undefined : 'ellipsis',\n whiteSpace: wrapLabel ? 'normal' : 'nowrap',\n }}\n title={control.label}\n >\n {control.label}\n {control.required ? <span style={{ color: '#a4262c', marginLeft: 2 }}>*</span> : null}\n </span>\n);\n\nconst FULL_WIDTH_TYPES: ReadonlySet<string> = new Set([\n 'spacer',\n 'subgrid',\n 'timeline',\n 'webresource',\n 'label',\n 'button',\n]);\n\n/**\n * Merge rule-engine FieldState into a control's static props. The\n * field state ALWAYS wins where it's set; the control's own prop\n * remains when no rule overrides it. Matches the legacy preview's\n * effectiveControl computation.\n *\n * - `locked` -> readOnly true (OR-merged with control.readOnly: a\n * rule can lock a field but cannot unlock one statically marked\n * readOnly in the definition).\n * - `required: 'required'` -> required true. Other rule values\n * ('recommended' | 'none') fall through to the control's own\n * required flag.\n */\nfunction mergeFieldState(control: ControlDefinition, fieldState: FieldState | undefined): ControlDefinition {\n if (!fieldState) return control;\n return {\n ...control,\n readOnly: control.readOnly || fieldState.locked,\n required: fieldState.required === 'required' ? true : control.required,\n };\n}\n","/**\n * backgroundUtils — converts a {@link BackgroundConfig} into CSS so the\n * shells can render per-section / per-theme color, image, or gradient\n * backgrounds.\n *\n * Vendored slim from the form-builder\n * (`apps/form-builder/src/utils/backgroundUtils.ts`) — the form-builder\n * version also owns image compression + preset palettes, which are\n * editor-side concerns and stay out of the runtime.\n */\n\nimport type { BackgroundConfig } from '../types/theme';\n\n/**\n * A subset of React.CSSProperties wide enough for any output of\n * {@link backgroundConfigToCss}. Inlined to avoid pinning the helper\n * to form-runtime's `react` / `csstype` install — downstream consumers\n * (form-builder) bring their own csstype tree and the duplicate\n * installs trip TS2322 when the type signature carries the full\n * `React.CSSProperties`.\n */\nexport type BackgroundStyle = {\n backgroundColor?: string;\n backgroundImage?: string;\n backgroundSize?: string;\n backgroundPosition?: string;\n backgroundRepeat?: string;\n background?: string;\n};\n\n/**\n * Convert a {@link BackgroundConfig} into style props. Returns a\n * solid-color fallback when `config` is undefined and `fallbackColor`\n * is supplied; otherwise an empty style object.\n */\nexport function backgroundConfigToCss(\n config: BackgroundConfig | undefined,\n fallbackColor?: string,\n): BackgroundStyle {\n if (!config) {\n return fallbackColor ? { backgroundColor: fallbackColor } : {};\n }\n\n switch (config.type) {\n case 'color':\n return { backgroundColor: config.color };\n\n case 'image':\n return {\n backgroundImage: `url(${config.src})`,\n backgroundSize: config.size,\n backgroundPosition: config.position,\n backgroundRepeat: config.repeat,\n };\n\n case 'gradient': {\n const stops = config.stops\n .slice()\n .sort((a, b) => a.position - b.position)\n .map((s) => `${s.color} ${s.position}%`)\n .join(', ');\n return {\n background: `linear-gradient(${config.direction}deg, ${stops})`,\n };\n }\n\n default:\n return fallbackColor ? { backgroundColor: fallbackColor } : {};\n }\n}\n","/**\n * CalloutAnchor — wraps a control with click / hover / icon-click\n * trigger handlers that open a {@link CalloutShell} anchored to the\n * control's DOM node.\n *\n * Phase 3 milestone 2 — replaces `CalloutControlWrapper` +\n * `CalloutIndicator` from\n * `apps/form-builder/src/components/form-preview/CalloutPreview.tsx`.\n *\n * State is local to each anchor (each control with a callout owns its\n * own open/close state). The legacy preview centralized state in\n * FormPreview, but FluentCallout's dismiss-on-click-outside makes\n * \"only one open at a time\" the natural behavior anyway — and the\n * local model avoids prop-drilling activation handlers through the\n * shell hierarchy.\n *\n * Hover bridging: when the trigger is `hover`, a 300ms timer governs\n * dismissal so the user can move from the anchor onto the callout\n * content without losing it. CalloutShell calls back into this\n * component via onContentMouse* to cancel / restart the timer.\n */\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Icon, mergeStyles } from '@fluentui/react';\nimport type { CalloutDefinition, CalloutTrigger } from '../types';\nimport { CalloutShell } from './CalloutShell';\nimport type { InstrumentationMode } from '../instrumentation';\nimport type { DispatchControlInputs } from '../v8/controls/dispatcher';\n\nconst HOVER_DISMISS_DELAY_MS = 300;\n\nconst indicatorClass = mergeStyles({\n position: 'absolute',\n top: -4,\n right: -4,\n width: 18,\n height: 18,\n borderRadius: '50%',\n backgroundColor: '#0078d4',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n boxShadow: '0 1px 3px rgba(0,0,0,0.2)',\n zIndex: 1,\n selectors: {\n ':hover': {\n backgroundColor: '#106ebe',\n transform: 'scale(1.1)',\n },\n },\n});\n\nexport interface CalloutAnchorProps {\n callout: CalloutDefinition;\n /** Optional per-attachment override of the callout's default trigger. */\n triggerOverride?: CalloutTrigger;\n children: React.ReactNode;\n /** Parent path threaded through to {@link CalloutShell} for nested\n * section instrumentation. */\n parentPath: string;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nexport const CalloutAnchor: React.FC<CalloutAnchorProps> = ({\n callout,\n triggerOverride,\n children,\n parentPath,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n const anchorRef = useRef<HTMLDivElement>(null);\n const indicatorRef = useRef<HTMLDivElement>(null);\n const dismissTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [open, setOpen] = useState(false);\n\n const trigger: CalloutTrigger = triggerOverride ?? callout.trigger ?? 'click';\n\n const cancelHoverDismiss = useCallback(() => {\n if (dismissTimerRef.current) {\n clearTimeout(dismissTimerRef.current);\n dismissTimerRef.current = null;\n }\n }, []);\n\n const scheduleHoverDismiss = useCallback(() => {\n cancelHoverDismiss();\n dismissTimerRef.current = setTimeout(() => {\n setOpen(false);\n dismissTimerRef.current = null;\n }, HOVER_DISMISS_DELAY_MS);\n }, [cancelHoverDismiss]);\n\n // Cleanup pending timer on unmount.\n useEffect(() => cancelHoverDismiss, [cancelHoverDismiss]);\n\n const dismiss = useCallback(() => {\n cancelHoverDismiss();\n setOpen(false);\n }, [cancelHoverDismiss]);\n\n const handleAnchorClick = trigger === 'click' ? () => setOpen((v) => !v) : undefined;\n const handleAnchorMouseEnter =\n trigger === 'hover'\n ? () => {\n cancelHoverDismiss();\n setOpen(true);\n }\n : undefined;\n const handleAnchorMouseLeave = trigger === 'hover' ? scheduleHoverDismiss : undefined;\n\n const handleIndicatorClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n setOpen((v) => !v);\n };\n\n // Resolve which element the callout anchors to. `icon-click` opens\n // off the indicator so the visual arrow points at it; click/hover\n // open off the anchor wrapper so the callout covers the field.\n const target = trigger === 'icon-click' ? indicatorRef.current : anchorRef.current;\n\n return (\n <div\n ref={anchorRef}\n style={{ position: 'relative' }}\n onClick={handleAnchorClick}\n onMouseEnter={handleAnchorMouseEnter}\n onMouseLeave={handleAnchorMouseLeave}\n data-runtime-chrome=\"callout-anchor\"\n data-callout-id={callout.id}\n >\n {children}\n {trigger === 'icon-click' && (\n <div\n ref={indicatorRef}\n className={indicatorClass}\n onClick={handleIndicatorClick}\n title=\"Click to show callout\"\n data-runtime-chrome=\"callout-indicator\"\n >\n <Icon iconName=\"Comment\" styles={{ root: { fontSize: 10, color: '#ffffff' } }} />\n </div>\n )}\n {open && target && (\n <CalloutShell\n callout={callout}\n target={target}\n onDismiss={dismiss}\n onContentMouseEnter={trigger === 'hover' ? cancelHoverDismiss : undefined}\n onContentMouseLeave={trigger === 'hover' ? scheduleHoverDismiss : undefined}\n parentPath={parentPath}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n )}\n </div>\n );\n};\n","/**\n * CalloutShell — renders a Fluent UI Callout anchored at `target`,\n * populated by the runtime's SectionShell so its content honors all\n * the same FormSection rendering rules as the rest of the form.\n *\n * Phase 3 milestone 2. Replaces the legacy `CalloutPreview` /\n * `CalloutControlWrapper` pair in\n * `apps/form-builder/src/components/form-preview/CalloutPreview.tsx`.\n *\n * Trigger handling, open/close state, and the activation surface live\n * in {@link CalloutAnchor}; this file only paints the open callout.\n */\n\nimport React from 'react';\nimport { Callout, DirectionalHint, PrimaryButton, DefaultButton } from '@fluentui/react';\nimport type { CalloutDefinition, CalloutDirectionalHint, FormSection } from '../types';\nimport { SectionShell } from './SectionShell';\nimport { paths, type InstrumentationMode } from '../instrumentation';\nimport type { DispatchControlInputs } from '../v8/controls/dispatcher';\n\nconst DIRECTIONAL_HINT_MAP: Record<CalloutDirectionalHint, DirectionalHint> = {\n topLeftEdge: DirectionalHint.topLeftEdge,\n topCenter: DirectionalHint.topCenter,\n topRightEdge: DirectionalHint.topRightEdge,\n topAutoEdge: DirectionalHint.topAutoEdge,\n bottomLeftEdge: DirectionalHint.bottomLeftEdge,\n bottomCenter: DirectionalHint.bottomCenter,\n bottomRightEdge: DirectionalHint.bottomRightEdge,\n bottomAutoEdge: DirectionalHint.bottomAutoEdge,\n leftTopEdge: DirectionalHint.leftTopEdge,\n leftCenter: DirectionalHint.leftCenter,\n leftBottomEdge: DirectionalHint.leftBottomEdge,\n rightTopEdge: DirectionalHint.rightTopEdge,\n rightCenter: DirectionalHint.rightCenter,\n rightBottomEdge: DirectionalHint.rightBottomEdge,\n};\n\n/** Map our string-based hint enum into Fluent's runtime enum. */\nexport function mapCalloutDirectionalHint(hint?: CalloutDirectionalHint): DirectionalHint {\n return hint ? (DIRECTIONAL_HINT_MAP[hint] ?? DirectionalHint.bottomAutoEdge) : DirectionalHint.bottomAutoEdge;\n}\n\nexport interface CalloutShellProps {\n callout: CalloutDefinition;\n target: HTMLElement;\n onDismiss: () => void;\n /** Called when the cursor enters the callout content — used by the\n * hover trigger in {@link CalloutAnchor} to cancel a pending dismiss\n * so the user can move from the anchor onto the callout without it\n * disappearing under them. */\n onContentMouseEnter?: () => void;\n /** Called when the cursor leaves the callout content. */\n onContentMouseLeave?: () => void;\n /** Parent path used to nest callout sections under their host control\n * for instrumentation. The legacy preview was uninstrumented; the\n * runtime path keeps the same surface but with element-ids so the\n * designer overlay can target callout sections too. */\n parentPath: string;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nexport const CalloutShell: React.FC<CalloutShellProps> = ({\n callout,\n target,\n onDismiss,\n onContentMouseEnter,\n onContentMouseLeave,\n parentPath,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n const hint = mapCalloutDirectionalHint(callout.directionalHint);\n const isHover = callout.trigger === 'hover';\n const actionButtons = callout.actionButtons ?? [];\n const hasButtons = actionButtons.length > 0;\n const footerJustify =\n callout.buttonAlignment === 'left'\n ? 'flex-start'\n : callout.buttonAlignment === 'center'\n ? 'center'\n : 'flex-end';\n // dismissOnClickOutside default is true — only suppress the Callout's\n // onDismiss callback when the form explicitly opted out.\n const dismissEnabled = callout.dismissOnClickOutside !== false;\n const calloutPath = paths.callout(parentPath, callout.id);\n\n return (\n <Callout\n target={target}\n onDismiss={isHover ? undefined : dismissEnabled ? onDismiss : undefined}\n preventDismissOnEvent={isHover ? () => true : undefined}\n directionalHint={hint}\n isBeakVisible={callout.isBeakVisible ?? true}\n beakWidth={callout.beakWidth ?? 16}\n gapSpace={callout.gapSpace ?? 0}\n styles={{\n root: {\n width: callout.width ?? 320,\n boxShadow: '0 3px 12px rgba(0,0,0,0.15)',\n },\n }}\n >\n <div\n style={{ padding: 16 }}\n onMouseEnter={isHover ? onContentMouseEnter : undefined}\n onMouseLeave={isHover ? onContentMouseLeave : undefined}\n >\n <div style={{ maxHeight: 400, overflowY: 'auto' }}>\n {callout.sections.map((section: FormSection) => (\n <SectionShell\n key={section.id}\n section={section}\n parentPath={calloutPath}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n ))}\n </div>\n {hasButtons && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n justifyContent: footerJustify,\n borderTop: '1px solid #edebe9',\n padding: '10px 16px 0',\n marginTop: 12,\n }}\n >\n {actionButtons.map((btn) =>\n btn.appearance === 'primary' ? (\n <PrimaryButton\n key={btn.id}\n text={btn.label}\n iconProps={btn.icon ? { iconName: btn.icon } : undefined}\n onClick={onDismiss}\n />\n ) : (\n <DefaultButton\n key={btn.id}\n text={btn.label}\n iconProps={btn.icon ? { iconName: btn.icon } : undefined}\n onClick={onDismiss}\n />\n ),\n )}\n </div>\n )}\n </div>\n </Callout>\n );\n};\n","/**\n * CalloutsContext — exposes `form.callouts` to descendants so\n * SectionShell's CellShell can look up the CalloutDefinition that a\n * control's `calloutId` references without prop-drilling the array\n * through every shell layer.\n *\n * The runtime emits a provider once, at the FormRuntime mount point;\n * shells use {@link useCallout} to resolve an id to its definition (or\n * undefined when no provider is mounted, when the array is empty, or\n * when the id doesn't match — all of which should render the host\n * control without callout chrome).\n */\n\nimport React, { createContext, useContext, useMemo } from 'react';\nimport type { CalloutDefinition } from '../types';\n\ninterface CalloutsContextValue {\n /** Map from callout id -> definition for O(1) lookup. */\n byId: Map<string, CalloutDefinition>;\n}\n\nconst EMPTY: CalloutsContextValue = { byId: new Map() };\n\nconst CalloutsContext = createContext<CalloutsContextValue>(EMPTY);\nCalloutsContext.displayName = 'CalloutsContext';\n\nexport interface CalloutsProviderProps {\n callouts?: CalloutDefinition[];\n children: React.ReactNode;\n}\n\nexport const CalloutsProvider: React.FC<CalloutsProviderProps> = ({ callouts, children }) => {\n const value = useMemo<CalloutsContextValue>(() => {\n if (!callouts || callouts.length === 0) return EMPTY;\n return { byId: new Map(callouts.map((c) => [c.id, c])) };\n }, [callouts]);\n return <CalloutsContext.Provider value={value}>{children}</CalloutsContext.Provider>;\n};\n\n/**\n * Look up a callout by id. Returns undefined when no provider is\n * mounted, when the id is undefined, or when no callout with that id\n * exists — all should render the host control without chrome.\n */\nexport function useCallout(id: string | undefined): CalloutDefinition | undefined {\n const ctx = useContext(CalloutsContext);\n if (!id) return undefined;\n return ctx.byId.get(id);\n}\n","/**\n * RuleStatesContext — exposes business-rule evaluation outputs\n * (fieldStates / sectionStates / tabStates) to the runtime's shells so\n * they can gate visibility and override control props (readOnly,\n * required) at render time.\n *\n * The runtime does NOT own the rule engine — that's editor/host state.\n * It only consumes pre-computed state maps. The form-builder's\n * `useRuleExecutionStore` feeds these in via FormRuntime's `ruleStates`\n * prop; generated apps pass equivalent maps from their host integration.\n *\n * Missing entries are treated as \"no rule constraint\" — the underlying\n * control's own props (hidden / readOnly / required) take effect. This\n * matches the legacy SectionPreview's fallthrough behavior.\n */\n\nimport React, { createContext, useContext, useMemo } from 'react';\nimport type { FieldState, SectionState, TabState } from '../types/businessRules';\n\nexport interface RuleStatesContextValue {\n fieldStates: Record<string, FieldState>;\n sectionStates: Record<string, SectionState>;\n tabStates: Record<string, TabState>;\n}\n\nconst EMPTY: RuleStatesContextValue = {\n fieldStates: {},\n sectionStates: {},\n tabStates: {},\n};\n\nconst RuleStatesContext = createContext<RuleStatesContextValue>(EMPTY);\nRuleStatesContext.displayName = 'RuleStatesContext';\n\nexport interface RuleStatesProviderProps {\n fieldStates?: Record<string, FieldState>;\n sectionStates?: Record<string, SectionState>;\n tabStates?: Record<string, TabState>;\n children: React.ReactNode;\n}\n\nexport const RuleStatesProvider: React.FC<RuleStatesProviderProps> = ({\n fieldStates,\n sectionStates,\n tabStates,\n children,\n}) => {\n const value = useMemo<RuleStatesContextValue>(\n () => ({\n fieldStates: fieldStates ?? {},\n sectionStates: sectionStates ?? {},\n tabStates: tabStates ?? {},\n }),\n [fieldStates, sectionStates, tabStates],\n );\n return <RuleStatesContext.Provider value={value}>{children}</RuleStatesContext.Provider>;\n};\n\n/**\n * Returns the full rule-state maps. Use this when you need to walk\n * multiple field/section ids in a single render pass (e.g. RowShell\n * checking \"is every cell in this row hidden\") — avoids violating\n * the rules of hooks by calling useFieldState in a loop.\n */\nexport function useRuleStates(): RuleStatesContextValue {\n return useContext(RuleStatesContext);\n}\n\n/** Returns the field's rule state, or undefined if no rule has set one. */\nexport function useFieldState(controlName: string | undefined): FieldState | undefined {\n const ctx = useContext(RuleStatesContext);\n if (!controlName) return undefined;\n return ctx.fieldStates[controlName];\n}\n\n/** Returns the section's rule state, or undefined if no rule has set one. */\nexport function useSectionState(sectionId: string): SectionState | undefined {\n return useContext(RuleStatesContext).sectionStates[sectionId];\n}\n\n/** Returns the tab's rule state, or undefined if no rule has set one. */\nexport function useTabState(tabId: string): TabState | undefined {\n return useContext(RuleStatesContext).tabStates[tabId];\n}\n","/**\n * TabContentSlotsContext — pluggable render slots for non-main tabs\n * (related-records, audit-history). The runtime ships a placeholder\n * for these tab types because they depend on host-specific concerns\n * (dataverse queries, related-record metadata) that don't belong in\n * the runtime itself.\n *\n * Hosts that want full fidelity (form-builder preview, generated\n * apps) provide render functions for these slots via\n * `TabContentSlotsProvider`. TabsShell consumes them via\n * `useTabContentSlots()`; missing slots fall through to the\n * placeholder.\n *\n * Phase 3 m6 — replaces the legacy preview's direct imports of\n * RelatedTabPreview / AuditTabPreview without making the runtime\n * depend on either component.\n */\n\nimport React, { createContext, useContext, useMemo } from 'react';\nimport type { RelatedFormTab, AuditFormTab } from '../types';\n\nexport interface TabContentSlots {\n /** Render override for related-records tabs. */\n renderRelatedTab?: (tab: RelatedFormTab) => React.ReactNode;\n /** Render override for audit-history tabs. */\n renderAuditTab?: (tab: AuditFormTab) => React.ReactNode;\n}\n\nconst EMPTY: TabContentSlots = {};\n\nconst TabContentSlotsContext = createContext<TabContentSlots>(EMPTY);\nTabContentSlotsContext.displayName = 'TabContentSlotsContext';\n\nexport interface TabContentSlotsProviderProps {\n slots?: TabContentSlots;\n children: React.ReactNode;\n}\n\nexport const TabContentSlotsProvider: React.FC<TabContentSlotsProviderProps> = ({\n slots,\n children,\n}) => {\n const value = useMemo<TabContentSlots>(() => slots ?? EMPTY, [slots]);\n return <TabContentSlotsContext.Provider value={value}>{children}</TabContentSlotsContext.Provider>;\n};\n\nexport function useTabContentSlots(): TabContentSlots {\n return useContext(TabContentSlotsContext);\n}\n","import {\n DEFAULT_FORM_GRID_LAYOUT,\n FormDefinition,\n FormGridLayout,\n FormSection,\n isMainTab,\n} from '../types';\n\n/**\n * Narrow inline-style shape returned by `gridPositionStyle`. Structurally\n * compatible with `React.CSSProperties` (callers spread or assign it\n * directly onto a `style={{...}}` prop), but declared locally so we don't\n * pull `@types/react` into the package's *return-type* surface. The\n * monorepo has two copies of `@types/react` resolved (one under\n * dynamics-toolkit/node_modules, one under dynamics-ui-kit/node_modules);\n * using `CSSProperties` here makes form-builder consumers see a different\n * type identity than their own `React.CSSProperties` and reject the value.\n */\nexport interface GridPositionStyle {\n gridColumn?: string;\n gridRow?: string;\n gridColumnStart?: number;\n gridColumnEnd?: string;\n gridRowStart?: number;\n gridRowEnd?: string;\n}\n\n/**\n * Shared helpers for rendering grid-mode (Dashboard) forms.\n *\n * Designer (`GridFormCanvas`) and preview (`GridFormPreview`) must stay in\n * lockstep — if one calculates section coordinates differently from the\n * other, the user sees one layout while authoring and a different one in\n * preview. Centralizing the helpers in form-runtime makes the designer\n * canvas, preview, generator emission path, and (Phase 1+) the shared\n * runtime mount-point all consume a single source of truth.\n */\n\n/**\n * Resolve the grid-mode form's section host. Grid mode hides the TabBar\n * and renders the first main tab's sections; falls back to flat\n * `form.sections` for forms migrated outside the normal wizard path.\n *\n * Returns `tabId: null` only when the form has no main tab at all — call\n * sites must check this before invoking section-mutating store actions\n * that need a target tab.\n */\nexport function pickGridTab(form: FormDefinition): {\n tabId: string | null;\n sections: FormSection[];\n} {\n const firstMain = form.tabs.find((t) => isMainTab(t));\n if (firstMain && isMainTab(firstMain)) {\n return { tabId: firstMain.id, sections: firstMain.sections };\n }\n return { tabId: null, sections: form.sections };\n}\n\n/**\n * Compute the inline grid-position style for a section.\n *\n * When `gridPosition` is absent we emit `span` values only (no\n * `grid-column-start`) and let CSS Grid auto-flow pack the tile. The\n * default span is half-width × four rows.\n *\n * `pos.w` is clamped to `layout.columns` so a wider-than-grid tile can't\n * overflow horizontally. `pos.h` and `pos.x` are clamped to non-negative\n * sane defaults so persisted-bad data doesn't crash the renderer.\n */\nexport function gridPositionStyle(\n section: FormSection,\n layout: FormGridLayout,\n): GridPositionStyle {\n const pos = section.gridPosition;\n if (!pos) {\n const halfWidth = Math.max(1, Math.floor(layout.columns / 2));\n return { gridColumn: `span ${halfWidth}`, gridRow: 'span 4' };\n }\n const w = Math.max(1, Math.min(pos.w, layout.columns));\n const h = Math.max(1, pos.h);\n const x = Math.max(0, Math.min(pos.x, Math.max(0, layout.columns - 1)));\n const y = Math.max(0, pos.y);\n return {\n gridColumnStart: x + 1,\n gridColumnEnd: `span ${w}`,\n gridRowStart: y + 1,\n gridRowEnd: `span ${h}`,\n };\n}\n\n/**\n * Resolve the effective grid layout (caller-provided or library default).\n * Use this instead of `form.gridLayout ?? DEFAULT_FORM_GRID_LAYOUT` at the\n * call site so future changes to the default-resolution rule live in one\n * place.\n */\nexport function resolveGridLayout(form: FormDefinition): FormGridLayout {\n return form.gridLayout ?? DEFAULT_FORM_GRID_LAYOUT;\n}\n","/**\n * GridShell — dashboard-layout form. Picks the grid-mode host\n * (first main tab's sections, or flat `form.sections`) and places\n * each section onto a CSS Grid using `gridLayoutUtils.gridPositionStyle`.\n */\n\nimport React from 'react';\nimport type { FormDefinition } from '../types';\nimport { DEFAULT_FORM_GRID_LAYOUT } from '../types';\nimport { pickGridTab, gridPositionStyle } from '../utils/gridLayoutUtils';\nimport { SectionShell } from './SectionShell';\nimport { instrumentAttrs, paths, type InstrumentationMode } from '../instrumentation';\nimport type { DispatchControlInputs } from '../v8/controls/dispatcher';\n\nexport interface GridShellProps {\n form: FormDefinition;\n recordData?: Record<string, unknown> | null;\n interactive: boolean;\n instrumentation: InstrumentationMode;\n onCellValueChange?: (controlName: string, next: unknown) => void;\n onButtonClick?: DispatchControlInputs['onButtonClick'];\n}\n\nexport const GridShell: React.FC<GridShellProps> = ({\n form,\n recordData,\n interactive,\n instrumentation,\n onCellValueChange,\n onButtonClick,\n}) => {\n const layout = form.gridLayout ?? DEFAULT_FORM_GRID_LAYOUT;\n const { tabId, sections } = pickGridTab(form);\n const parentPath = tabId ? paths.tab(tabId) : 'grid';\n\n return (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${layout.columns}, minmax(0, 1fr))`,\n gridAutoRows: `${layout.rowHeight ?? 80}px`,\n gap: layout.gap ?? 12,\n padding: 12,\n }}\n >\n {sections.map((section) => {\n const positionStyle = gridPositionStyle(section, layout);\n return (\n <div\n key={section.id}\n {...instrumentAttrs(instrumentation, section.id, 'gridItem', paths.gridItem(section.id))}\n style={{ ...positionStyle, minWidth: 0, minHeight: 0 }}\n >\n <SectionShell\n section={section}\n parentPath={parentPath}\n recordData={recordData}\n interactive={interactive}\n instrumentation={instrumentation}\n onCellValueChange={onCellValueChange}\n onButtonClick={onButtonClick}\n />\n </div>\n );\n })}\n </div>\n );\n};\n","/**\n * FooterShell — dialog/panel footer with action buttons.\n *\n * Phase 3 m3. Replaces the legacy DialogButtonsBlock /\n * PanelButtonsBlock and the `renderDialogButton` helpers from\n * apps/form-builder/.../form-preview/FormPreview.tsx.\n *\n * Reads buttons from `form.settings.dialogButtons` (form.type=dialog)\n * or `form.settings.panelButtons` (form.type=panel). When neither is\n * configured, falls back to a single Close button — same default as\n * the legacy `createDefaultDialogButtons()`.\n *\n * Buttons split into a left group and a right group; alignment of\n * the whole footer is controlled by `dialogButtonAlignment` /\n * `panelButtonAlignment` ('left' | 'center' | 'right'; default 'right').\n *\n * Click actions are not dispatched here. The legacy `renderDialogButton`\n * also doesn't wire onClick — actions get processed by the host. The\n * runtime exposes `onActionButtonClick` so callers (preview, host)\n * can opt in. Business-rules-driven button state lands in m4.\n */\n\nimport React from 'react';\nimport {\n PrimaryButton,\n DefaultButton,\n ActionButton,\n} from '@fluentui/react';\nimport type { DialogActionButton, FormDefinition } from '../types';\n\nexport interface FooterShellProps {\n form: FormDefinition;\n /** Optional click callback. When unset, buttons render as no-ops. */\n onActionButtonClick?: (button: DialogActionButton) => void;\n}\n\nconst DEFAULT_BUTTONS: DialogActionButton[] = [\n {\n id: '__default-close__',\n label: 'Close',\n appearance: 'default',\n position: 'right',\n order: 0,\n action: { type: 'close' },\n },\n];\n\nexport const FooterShell: React.FC<FooterShellProps> = ({ form, onActionButtonClick }) => {\n if (form.type !== 'dialog' && form.type !== 'panel') return null;\n\n const buttonsSource =\n form.type === 'dialog'\n ? form.settings.dialogButtons\n : form.settings.panelButtons;\n const alignment =\n form.type === 'dialog'\n ? form.settings.dialogButtonAlignment ?? 'right'\n : form.settings.panelButtonAlignment ?? 'right';\n\n const buttons = buttonsSource && buttonsSource.length > 0 ? buttonsSource : DEFAULT_BUTTONS;\n const sorted = [...buttons].filter((b) => !b.hidden).sort((a, b) => a.order - b.order);\n const leftButtons = sorted.filter((b) => b.position === 'left');\n const rightButtons = sorted.filter((b) => b.position === 'right');\n\n // Nothing visible to render — skip the footer chrome entirely.\n if (leftButtons.length === 0 && rightButtons.length === 0) return null;\n\n const footerJustify =\n alignment === 'left' ? 'flex-start' : alignment === 'center' ? 'center' : 'flex-end';\n\n return (\n <div\n data-runtime-chrome=\"footer\"\n data-form-type={form.type}\n style={{\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n justifyContent: footerJustify,\n alignItems: 'center',\n width: '100%',\n gap: 8,\n padding: '12px 16px',\n borderTop: '1px solid #edebe9',\n backgroundColor: '#faf9f8',\n }}\n >\n {leftButtons.length > 0 && (\n <div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 4 }}>\n {leftButtons.map((btn) => (\n <FooterButton key={btn.id} button={btn} onClick={onActionButtonClick} />\n ))}\n </div>\n )}\n {rightButtons.length > 0 && (\n <div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 4 }}>\n {rightButtons.map((btn) => (\n <FooterButton key={btn.id} button={btn} onClick={onActionButtonClick} />\n ))}\n </div>\n )}\n </div>\n );\n};\n\ninterface FooterButtonProps {\n button: DialogActionButton;\n onClick?: (button: DialogActionButton) => void;\n}\n\nconst FooterButton: React.FC<FooterButtonProps> = ({ button, onClick }) => {\n const iconProps = button.icon ? { iconName: button.icon } : undefined;\n const handleClick = onClick ? () => onClick(button) : undefined;\n switch (button.appearance) {\n case 'primary':\n return (\n <PrimaryButton\n text={button.label}\n iconProps={iconProps}\n disabled={button.disabled}\n onClick={handleClick}\n styles={{ root: { marginLeft: 8 } }}\n data-runtime-chrome=\"footer-button\"\n data-button-id={button.id}\n />\n );\n case 'subtle':\n return (\n <ActionButton\n text={button.label}\n iconProps={iconProps}\n disabled={button.disabled}\n onClick={handleClick}\n styles={{ root: { marginLeft: 8 } }}\n data-runtime-chrome=\"footer-button\"\n data-button-id={button.id}\n />\n );\n case 'default':\n default:\n return (\n <DefaultButton\n text={button.label}\n iconProps={iconProps}\n disabled={button.disabled}\n onClick={handleClick}\n styles={{ root: { marginLeft: 8 } }}\n data-runtime-chrome=\"footer-button\"\n data-button-id={button.id}\n />\n );\n }\n};\n"],"mappings":"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","names":["import_jsx_runtime","DOMPurify","React","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","opt","optIcon","optColor","iconColor","import_react","import_jsx_runtime","resolveRawOptions","newKeys","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","containerClass","isDisabled","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","getInitials","import_jsx_runtime","isDisabled","getInitials","import_react","import_jsx_runtime","FluentIconButton","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","React","import_jsx_runtime","import_react","import_jsx_runtime","emptyStateClass","FluentLink","import_react","import_jsx_runtime","import_react","import_jsx_runtime","containerClass","cardClass","detailPaneClass","emptyStateClass","getInitials","getPersonaColor","import_react","import_react","import_jsx_runtime","import_jsx_runtime","PERSON_ENTITIES","getInitials","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_react","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","EMPTY","import_jsx_runtime","import_react","import_jsx_runtime","EMPTY","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime"]}