@dataverse-kit/surface-kit 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/v9.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/sizePresets.ts","../src/core/columns.ts","../src/responsive/breakpoints.ts","../src/responsive/builders.ts","../src/tokens/tokens.ts","../src/tokens/density.ts","../src/hooks/useContainerSize.ts","../src/hooks/useContainerWidth.ts","../src/hooks/useContainerBreakpoint.ts","../src/hooks/useResponsiveValue.ts","../src/hooks/useMediaQuery.ts","../src/hooks/useDensity.ts","../src/v9/theme.ts","../src/v9/containers/FormSurface.tsx","../src/v9/containers/PageSurface.tsx","../src/v9/containers/Section.tsx","../src/v9/containers/SectionHeader.tsx","../src/v9/containers/SectionCard.tsx","../src/v9/containers/FormHeader.tsx","../src/v9/containers/PivotSurface.tsx","../src/v9/containers/CommandSurface.tsx","../src/v9/containers/ActionBar.tsx","../src/v9/containers/Footer.tsx","../src/v9/overlays/FormDialogSurface.tsx","../src/v9/overlays/ModalSurface.tsx","../src/v9/overlays/PanelSurface.tsx","../src/v9/overlays/CalloutSurface.tsx","../src/v9/overlays/TooltipSurface.tsx"],"sourcesContent":["// Pure-TS sizing scalars for overlay surfaces. The SINGLE SOURCE of the numbers\n// that both surface-kit's runtime overlays AND the export-engine codegen use, so a\n// Dialog is 1200px wide in exactly one place. Framework-agnostic (no react/@fluentui).\n//\n// Values mirror export-engine/src/generators/FormCodeGenerator.ts (v8 branches):\n// dialog: default width 1200; height <=100 -> `${h}vh` else '95vh'\n// panel: kind = (width ?? 480) > 500 ? 'medium' : 'custom'; custom width = width ?? 480\n// callout (form-type): default width 320; directionalHint 'bottomLeftEdge'\n// v1c wires export-engine to import these; a byte-identical emission test guards drift.\n\n// --- Dialog --------------------------------------------------------------------\n\nexport type DialogSizePreset = 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';\n\n// NOTE: only the lg = 1200 default and an explicit `width` are the shared-with-codegen\n// contract (export-engine does `width ?? 1200`). The sm/md/xl/fullscreen presets are\n// surface-kit runtime conveniences with no codegen counterpart — v1c does NOT consume them.\nexport const DIALOG_SIZE_PX = {\n sm: 600,\n md: 900,\n lg: 1200,\n xl: 1600,\n} as const;\n\n/** Resolved dialog width in px. Explicit `width` wins; else the preset (default lg = 1200, the codegen default). */\nexport function dialogWidthPx(opts: { width?: number; size?: DialogSizePreset } = {}): number {\n if (typeof opts.width === 'number') return opts.width;\n const size = opts.size ?? 'lg';\n // fullscreen is clamped by 95vw at the CSS layer; fall back to the largest preset for the px hint.\n if (size === 'fullscreen') return DIALOG_SIZE_PX.xl;\n return DIALOG_SIZE_PX[size];\n}\n\n/** Dialog width as a CSS value — '95vw' for the fullscreen preset (no explicit width), else `${px}px`. */\nexport function dialogWidthCss(opts: { width?: number; size?: DialogSizePreset } = {}): string {\n if (opts.size === 'fullscreen' && opts.width == null) return '95vw';\n return `${dialogWidthPx(opts)}px`;\n}\n\n/** Dialog height as a CSS value. <=100 is treated as a vh percentage; otherwise the 95vh cap (codegen rule). */\nexport function dialogHeightCss(height?: number): string {\n return height != null && height <= 100 ? `${height}vh` : '95vh';\n}\n\n/** Min width for an auto-sized ModalSurface (the Track-and-Ship \"min 1000, auto\" pattern). */\nexport const MODAL_AUTOSIZE_MIN_WIDTH = 1000;\n\n// --- Panel ---------------------------------------------------------------------\n\nexport type PanelKind = 'medium' | 'custom';\nexport const PANEL_DEFAULT_WIDTH = 480;\n\n/** Codegen-parity panel kind: wide panels use Fluent `medium`, narrow ones `custom` + customWidth. */\nexport function panelKindFromWidth(width?: number): PanelKind {\n return (width ?? PANEL_DEFAULT_WIDTH) > 500 ? 'medium' : 'custom';\n}\n\n/** customWidth px for a `custom` panel. */\nexport function panelCustomWidthPx(width?: number): number {\n return width ?? PANEL_DEFAULT_WIDTH;\n}\n\n// --- Callout -------------------------------------------------------------------\n\nexport const CALLOUT_DEFAULT_WIDTH = 320;\n\n/** Form-type callout defaults (the export-engine form-callout path emits width + directionalHint only). */\nexport const calloutFormDefaults = {\n width: CALLOUT_DEFAULT_WIDTH,\n directionalHint: 'bottomLeftEdge',\n} as const;\n\nexport function calloutWidthPx(width?: number): number {\n return width ?? CALLOUT_DEFAULT_WIDTH;\n}\n","// Pure-TS column helpers shared by layouts/containers and the responsive builders.\nexport type ColumnCount = 1 | 2 | 3 | 4;\n\n/** CSS grid-template-columns for an N-column layout. Matches codegen `repeat(N, 1fr)`. */\nexport function gridTemplateForColumns(columns: ColumnCount): string {\n return `repeat(${columns}, 1fr)`;\n}\n\n/** Clamp a cell column-span to the available column count (min 1). */\nexport function clampSpan(span: number, columns: ColumnCount): number {\n if (!Number.isFinite(span)) return 1;\n return Math.max(1, Math.min(Math.round(span), columns));\n}\n","// Named responsive breakpoints (px). The 480/768 cutoffs match the export-engine\n// section/field stacking; CARD_REFLOW_WIDTH (900) matches the CardGrid reflow\n// emitter (a separate cutoff). Pure-TS (no react/@fluentui).\nexport type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport const BREAKPOINTS: Record<Breakpoint, number> = {\n xs: 0,\n sm: 480,\n md: 768,\n lg: 1024,\n xl: 1366,\n};\n\n/** The card-grid reflow cutoff the codegen CardGrid emitter uses (distinct from the 480/768 field/section cutoffs). */\nexport const CARD_REFLOW_WIDTH = 900;\n\nconst DESCENDING: Breakpoint[] = ['xl', 'lg', 'md', 'sm', 'xs'];\nconst ASCENDING: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl'];\n\n/** Largest breakpoint whose min-width is <= width. */\nexport function resolveBreakpoint(width: number): Breakpoint {\n for (const bp of DESCENDING) {\n if (width >= BREAKPOINTS[bp]) return bp;\n }\n return 'xs';\n}\n\nexport type ResponsiveValue<T> = T | Partial<Record<Breakpoint, T>>;\n\nfunction isResponsiveMap<T>(v: ResponsiveValue<T>): v is Partial<Record<Breakpoint, T>> {\n return typeof v === 'object' && v !== null && ASCENDING.some((bp) => bp in (v as object));\n}\n\n/**\n * Resolve a responsive value at a breakpoint, cascading mobile-first: pick the\n * nearest defined value at or below `breakpoint`, else the nearest defined above.\n */\nexport function resolveResponsiveValue<T>(value: ResponsiveValue<T>, breakpoint: Breakpoint): T | undefined {\n if (!isResponsiveMap(value)) return value as T;\n const map = value;\n const idx = ASCENDING.indexOf(breakpoint);\n for (let i = idx; i >= 0; i--) {\n const v = map[ASCENDING[i]];\n if (v !== undefined) return v;\n }\n for (let i = idx + 1; i < ASCENDING.length; i++) {\n const v = map[ASCENDING[i]];\n if (v !== undefined) return v;\n }\n return undefined;\n}\n","// Pure-TS responsive style-object builders. Every responsive stacking decision in\n// surface-kit flows through here so viewport (`mode:'media'`) and container\n// (`mode:'container'`) stacking share the same 480/768 cutoffs. The numeric values\n// (gaps, minHeight, alignItems) mirror the export-engine fieldGrid/fieldRow/\n// tabSectionsGrid emitters so the eventual emitMode:'surface-kit' rewrite is parity.\n// Returned objects are structurally compatible with Fluent's `IStyle` (the `selectors`\n// shape) but typed locally so this layer stays framework-agnostic (no @fluentui import).\nimport { BREAKPOINTS } from './breakpoints';\nimport { gridTemplateForColumns, type ColumnCount } from '../core/columns';\n\nexport type StyleObject = Record<string, unknown>;\nexport type ResponsiveMode = 'media' | 'container';\n\nfunction atRule(mode: ResponsiveMode, maxPx: number): string {\n return mode === 'container'\n ? `@container (max-width: ${maxPx}px)`\n : `@media (max-width: ${maxPx}px)`;\n}\n\n/** N-column field grid that caps at 2 columns on tablet (<=768) and stacks to 1 on phone (<=480). */\nexport function fieldGridStyle(columns: ColumnCount, mode: ResponsiveMode = 'media'): StyleObject {\n const capped = Math.min(columns, 2) as ColumnCount;\n return {\n display: 'grid',\n gridTemplateColumns: gridTemplateForColumns(columns),\n gap: '4px 24px',\n selectors: {\n [atRule(mode, BREAKPOINTS.md)]: { gridTemplateColumns: gridTemplateForColumns(capped) },\n [atRule(mode, BREAKPOINTS.sm)]: { gridTemplateColumns: '1fr' },\n },\n };\n}\n\n/** Multi-section tab row that collapses straight to a single column on tablet (<=768). */\nexport function sectionStackingStyle(gridTemplateColumns: string, mode: ResponsiveMode = 'media'): StyleObject {\n return {\n display: 'grid',\n gridTemplateColumns,\n gap: 16,\n alignItems: 'start',\n selectors: {\n [atRule(mode, BREAKPOINTS.md)]: { gridTemplateColumns: '1fr' },\n },\n };\n}\n\n/** \"Label : input\" row that collapses the label above the input on phone (<=480). */\nexport function fieldRowStyle(labelWidth = '130px', mode: ResponsiveMode = 'media'): StyleObject {\n return {\n display: 'grid',\n gridTemplateColumns: `${labelWidth} 1fr`,\n alignItems: 'center',\n gap: 8,\n minHeight: 38,\n selectors: {\n [atRule(mode, BREAKPOINTS.sm)]: { gridTemplateColumns: '1fr', alignItems: 'flex-start', minHeight: 0, gap: 4 },\n },\n };\n}\n","// Re-exported from @dataverse-kit/design-tokens — the single canonical source of the\n// Dynamics design tokens. surface-kit no longer keeps its own copy (this retires the old\n// \"SYNCED FROM reusable-components\" duplication). The values are pure-TS (no react /\n// no @fluentui), so they remain safe to import from anywhere. `createDynamicsTheme()` and\n// `density` stay here in surface-kit (see ./theme and ./density).\nexport { colors, spacing, typography, radius, layout } from '@dataverse-kit/design-tokens';\n","// Spacing density multiplier — `comfortable` (Dynamics default) vs `compact`\n// (denser forms / embedded PCF). Pure-TS.\nexport type Density = 'comfortable' | 'compact';\n\nexport const densityScale = {\n comfortable: 1,\n compact: 0.75,\n} as const;\n\n/** Scale a base spacing value (px) by the active density. */\nexport function scaleSpacing(value: number, density: Density = 'comfortable'): number {\n return Math.round(value * densityScale[density]);\n}\n","// SYNCED FROM: shared/responsive-patterns/03-layouts/container-query/ContainerQuery.tsx (useContainerSize)\n// Inlined, not aliased: shared/responsive-patterns is outside the npm workspace. The\n// ContainerSize type is inlined here too (rather than vendoring shared/shared/types).\n// This is a React hook, so it lives in hooks/ (NOT responsive/, which must stay\n// framework-agnostic for the ./responsive subpath that export-engine inlines).\nimport * as React from 'react';\nimport { useState, useEffect } from 'react';\n\nexport interface ContainerSize {\n width: number;\n height: number;\n inlineSize: number;\n blockSize: number;\n}\n\n/** Observe an element's size via ResizeObserver. Pass a ref; returns {width,height,inlineSize,blockSize}. */\nexport function useContainerSize<T extends HTMLElement = HTMLElement>(ref: React.RefObject<T>): ContainerSize {\n const [size, setSize] = useState<ContainerSize>({ width: 0, height: 0, inlineSize: 0, blockSize: 0 });\n\n useEffect(() => {\n if (!ref.current || typeof ResizeObserver === 'undefined') return;\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect;\n const inlineSize = entry.borderBoxSize?.[0]?.inlineSize ?? width;\n const blockSize = entry.borderBoxSize?.[0]?.blockSize ?? height;\n setSize({ width, height, inlineSize, blockSize });\n }\n });\n\n observer.observe(ref.current);\n return () => observer.disconnect();\n }, [ref]);\n\n return size;\n}\n","import * as React from 'react';\nimport { useRef } from 'react';\nimport { useContainerSize } from './useContainerSize';\n\n/**\n * Create-and-return a ref plus the observed width of the element it is attached to.\n * `const [ref, width] = useContainerWidth(); return <div ref={ref}>…</div>`.\n */\nexport function useContainerWidth<T extends HTMLElement = HTMLDivElement>(): [React.RefObject<T>, number] {\n const ref = useRef<T>(null);\n const { width } = useContainerSize(ref);\n return [ref, width];\n}\n","import type * as React from 'react';\nimport { resolveBreakpoint, type Breakpoint } from '../responsive/breakpoints';\nimport { useContainerWidth } from './useContainerWidth';\n\n/**\n * Resolve the *container's* current breakpoint (not the viewport's) — the correctness\n * fix for a surface inside a PCF, where width comes from `context.allocatedWidth`.\n * Returns `[ref, breakpoint, width]`.\n */\nexport function useContainerBreakpoint<T extends HTMLElement = HTMLDivElement>(): [React.RefObject<T>, Breakpoint, number] {\n const [ref, width] = useContainerWidth<T>();\n return [ref, resolveBreakpoint(width), width];\n}\n","import type * as React from 'react';\nimport { resolveResponsiveValue, type ResponsiveValue } from '../responsive/breakpoints';\nimport { useContainerBreakpoint } from './useContainerBreakpoint';\n\n/**\n * Resolve a responsive value against the *container's* current breakpoint.\n * `const [ref, cols] = useResponsiveValue({ xs: 1, md: 2, lg: 3 });`\n */\nexport function useResponsiveValue<T, E extends HTMLElement = HTMLDivElement>(\n value: ResponsiveValue<T>,\n): [React.RefObject<E>, T | undefined] {\n const [ref, breakpoint] = useContainerBreakpoint<E>();\n return [ref, resolveResponsiveValue(value, breakpoint)];\n}\n","import { useState, useEffect } from 'react';\n\n/** Viewport media-query match — the SSR-safe / no-ResizeObserver fallback to the container hooks. */\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState<boolean>(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;\n const mql = window.matchMedia(query);\n const onChange = () => setMatches(mql.matches);\n onChange();\n mql.addEventListener('change', onChange);\n return () => mql.removeEventListener('change', onChange);\n }, [query]);\n\n return matches;\n}\n","import { createContext, useContext } from 'react';\nimport type { Density } from '../tokens/density';\n\n/**\n * Form-level spacing density. `FormSurface` provides it; `Section` (and any future\n * container) reads it via `useDensity()`, so a single `density` switch on the form\n * cascades to every section instead of being set per-section. Defaults to\n * `'comfortable'` (the Dynamics default) — `'compact'` scales spacing by 0.75.\n */\nexport const DensityContext = createContext<Density>('comfortable');\n\n/** Read the ambient spacing density (defaults to `'comfortable'` outside a provider). */\nexport const useDensity = (): Density => useContext(DensityContext);\n","// A Fluent UI v9 theme for the Dynamics surfaces. The v9 counterpart of the v8\n// `createDynamicsTheme()` (../tokens/theme.ts): where the v8 builder feeds the canonical\n// @dataverse-kit/design-tokens palette into a v8 `createTheme`, this builder feeds the\n// SAME brand triad (brand / brandHover / brandDark) into a v9 `BrandVariants` ramp and\n// `createLightTheme`. So a Dynamics-blue button is #0078d4 from ONE source across both skins.\nimport {\n createLightTheme,\n createDarkTheme,\n type BrandVariants,\n type Theme,\n} from '@fluentui/react-components';\nimport { colors } from '../tokens/tokens';\n\n// The Fluent web brand ramp (a blue family that already matches Dynamics CE), with the\n// three most-visible shades (60 pressed / 70 hover / 80 rest — the ones `createLightTheme`\n// maps to `colorBrandBackground*` and the compound-brand foreground) pinned to the canonical\n// design-tokens brand triad so the v9 brand colors come from the same source as v8's.\nexport const dynamicsBrandRamp: BrandVariants = {\n 10: '#061724',\n 20: '#082338',\n 30: '#0a2e4a',\n 40: '#0c3b5e',\n 50: '#0e4775',\n 60: colors.brandDark, // #005a9e — colorBrandBackgroundPressed\n 70: colors.brandHover, // #106ebe — colorBrandBackground(Hover/Selected)\n 80: colors.brand, // #0078d4 — colorBrandBackground + colorBrandForeground1 (the Dynamics blue)\n 90: '#2886de',\n 100: '#479ef5',\n 110: '#62abf5',\n 120: '#77b7f7',\n 130: '#96c6fa',\n 140: '#b4d6fa',\n 150: '#cfe4fa',\n 160: '#ebf3fc',\n};\n\n/**\n * Build a Fluent v9 `Theme` for the Dynamics surfaces. Defaults to the Dynamics-blue\n * brand ramp; pass a custom `BrandVariants` (e.g. from your org's brand) to override.\n * Wrap the app (or a `./v9` surface subtree) in `<FluentProvider theme={createDynamicsV9Theme()}>`.\n */\nexport function createDynamicsV9Theme(brand: BrandVariants = dynamicsBrandRamp): Theme {\n return createLightTheme(brand);\n}\n\n/** Dark-mode variant of the Dynamics v9 theme (same brand ramp). */\nexport function createDynamicsV9DarkTheme(brand: BrandVariants = dynamicsBrandRamp): Theme {\n return createDarkTheme(brand);\n}\n\n/** The default light Dynamics v9 theme (memoized module singleton). */\nexport const dynamicsV9Theme: Theme = createDynamicsV9Theme();\n","import React from 'react';\nimport { makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport type { FormSurfaceProps } from '../types';\nimport { scaleSpacing } from '../../tokens/density';\nimport { BREAKPOINTS, type Breakpoint } from '../../responsive/breakpoints';\nimport { DensityContext } from '../../hooks/useDensity';\n\n// The Fluent v9 counterpart of the v8 FormSurface: the N-column form canvas that Sections\n// sit on. Same logic — stacks children to full width below `collapseBelow`, driven by the\n// *container* width when `containerWidth` is supplied (PCF allocatedWidth), else by the\n// viewport via @media — re-skinned with griffel (makeStyles) + v9 theme tokens. The\n// density/breakpoint math is the SHARED framework-agnostic layer (scaleSpacing, BREAKPOINTS).\n\nconst useStyles = makeStyles({\n root: {\n display: 'grid',\n alignItems: 'start',\n backgroundColor: tokens.colorNeutralBackground2,\n },\n // Container forced a single column: reset every child's span the same way the @media\n // fallback does, so a Section with `columnStart` doesn't escape the stack.\n forceStackChildren: {\n '& > *': { gridColumn: '1 / -1' },\n },\n // Viewport fallbacks (used only when containerWidth is unset) — one static slot per\n // breakpoint so griffel gets literal media strings. The px come from the shared BREAKPOINTS.\n stackSm: { [`@media (max-width: ${BREAKPOINTS.sm}px)`]: { '& > *': { gridColumn: '1 / -1' } } },\n stackMd: { [`@media (max-width: ${BREAKPOINTS.md}px)`]: { '& > *': { gridColumn: '1 / -1' } } },\n stackLg: { [`@media (max-width: ${BREAKPOINTS.lg}px)`]: { '& > *': { gridColumn: '1 / -1' } } },\n stackXl: { [`@media (max-width: ${BREAKPOINTS.xl}px)`]: { '& > *': { gridColumn: '1 / -1' } } },\n});\n\nconst VIEWPORT_STACK: Record<Breakpoint, keyof ReturnType<typeof useStyles> | null> = {\n xs: null, // xs = 0px, never stacks\n sm: 'stackSm',\n md: 'stackMd',\n lg: 'stackLg',\n xl: 'stackXl',\n};\n\n/** The N-column form canvas that hosts Sections (Fluent UI v9). */\nexport const FormSurface: React.FC<FormSurfaceProps> = ({\n columns = 12,\n gap = 20,\n padding = 20,\n density = 'comfortable',\n background,\n containerWidth,\n collapseBelow = 'sm',\n maxWidth,\n className,\n style,\n children,\n}) => {\n const styles = useStyles();\n const collapsePx = BREAKPOINTS[collapseBelow];\n const forceStack = containerWidth != null && containerWidth <= collapsePx;\n // Density scales the canvas gap + padding; cascades to child Sections via context.\n const scaledGap = scaleSpacing(gap, density);\n const scaledPadding = scaleSpacing(padding, density);\n\n const viewportStackSlot = containerWidth == null ? VIEWPORT_STACK[collapseBelow] : null;\n\n const cls = mergeClasses(\n styles.root,\n forceStack && styles.forceStackChildren,\n viewportStackSlot ? styles[viewportStackSlot] : undefined,\n className,\n );\n\n const inlineStyle: React.CSSProperties = {\n gridTemplateColumns: forceStack ? '1fr' : `repeat(${columns}, 1fr)`,\n gap: scaledGap,\n padding: scaledPadding,\n ...(background != null ? { background } : {}),\n ...(maxWidth != null ? { maxWidth, marginLeft: 'auto', marginRight: 'auto' } : {}),\n ...style,\n };\n\n return (\n <DensityContext.Provider value={density}>\n <div className={cls} style={inlineStyle}>\n {children}\n </div>\n </DensityContext.Provider>\n );\n};\n\nexport default FormSurface;\n","import React from 'react';\nimport type { PageSurfaceProps } from '../types';\nimport { FormSurface } from './FormSurface';\n\n/** A full-page FormSurface (Fluent v9) — optionally centered with a comfortable max width. */\nexport const PageSurface: React.FC<PageSurfaceProps> = ({ centered, maxWidth, ...rest }) => (\n <FormSurface maxWidth={maxWidth ?? (centered ? 1200 : undefined)} {...rest} />\n);\n\nexport default PageSurface;\n","import React, { useState } from 'react';\nimport { makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport type { SectionProps } from '../types';\nimport { scaleSpacing } from '../../tokens/density';\nimport { BREAKPOINTS } from '../../responsive/breakpoints';\nimport { useDensity } from '../../hooks/useDensity';\nimport { SectionHeader } from './SectionHeader';\n\n// The Fluent v9 counterpart of the v8 Section: a grid-positioned card with a header and an\n// internal N-column field grid + the three `variant`s (card/flat/placeholder), `collapsible`,\n// and phone-stacking of the body. Chrome is inline (v9 theme `tokens` are CSS-var strings, so\n// they stay theme-reactive); only the @media child-stacking uses griffel. Density math is the\n// shared framework-agnostic layer (scaleSpacing).\n\nconst useStyles = makeStyles({\n // Phone-stack the internal field grid below `sm` (griffel — inline can't do @media).\n bodyStack: {\n [`@media (max-width: ${BREAKPOINTS.sm}px)`]: { '& > *': { gridColumn: '1 / -1' } },\n },\n});\n\n/** A Dynamics-CE form section (Fluent v9): positioned card with a header and an internal field grid. */\nexport const Section: React.FC<SectionProps> = ({\n title,\n columnSpan = 12,\n columnStart,\n rowPosition,\n internalColumns = 12,\n showCommandBar,\n commandItems,\n statusText,\n notification,\n collapsible,\n defaultCollapsed = false,\n collapsed: controlledCollapsed,\n onCollapsedChange,\n variant = 'card',\n minHeight = 80,\n density: densityProp,\n className,\n style,\n children,\n}) => {\n const styles = useStyles();\n const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed);\n const collapsed = controlledCollapsed ?? internalCollapsed;\n const toggle = () => {\n const next = !collapsed;\n if (controlledCollapsed == null) setInternalCollapsed(next);\n onCollapsedChange?.(next);\n };\n\n // Density: an explicit prop wins, else inherit the ambient FormSurface density.\n const ctxDensity = useDensity();\n const density = densityProp ?? ctxDensity;\n const cardPad = `${scaleSpacing(3, density)}px ${scaleSpacing(20, density)}px ${scaleSpacing(20, density)}px ${scaleSpacing(20, density)}px`;\n const bodyGap = scaleSpacing(7, density);\n\n const gridColumn = columnStart ? `${columnStart} / span ${columnSpan}` : `span ${columnSpan}`;\n const rootStyle: React.CSSProperties = {\n gridColumn,\n ...(rowPosition ? { gridRowStart: rowPosition } : {}),\n ...style,\n };\n\n if (variant === 'placeholder') {\n const placeholderStyle: React.CSSProperties = {\n ...rootStyle,\n border: `1px dashed ${tokens.colorNeutralStroke2}`,\n borderRadius: tokens.borderRadiusMedium,\n minHeight,\n width: '100%',\n background: 'transparent',\n };\n return <div className={className} style={placeholderStyle} />;\n }\n\n const chrome: React.CSSProperties =\n variant === 'flat'\n ? {\n backgroundColor: tokens.colorNeutralBackground1,\n borderRadius: tokens.borderRadiusMedium,\n padding: cardPad,\n minWidth: 300,\n width: '100%',\n overflow: 'hidden',\n }\n : {\n backgroundColor: tokens.colorNeutralBackground1,\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n borderRadius: tokens.borderRadiusMedium,\n boxShadow: tokens.shadow4,\n padding: cardPad,\n minWidth: 300,\n width: '100%',\n overflow: 'hidden',\n };\n\n const showHeader = Boolean(title) || showCommandBar || collapsible;\n\n const bodyStyle: React.CSSProperties = {\n display: 'grid',\n gridTemplateColumns: `repeat(${internalColumns}, 1fr)`,\n gap: bodyGap,\n alignItems: 'start',\n };\n\n return (\n <div className={className} style={{ ...chrome, ...rootStyle }}>\n {notification && <div style={{ marginBottom: scaleSpacing(8, density) }}>{notification}</div>}\n {showHeader && (\n <SectionHeader\n title={title}\n statusText={statusText}\n showCommandBar={showCommandBar}\n commandItems={commandItems}\n collapsible={collapsible}\n collapsed={collapsed}\n onToggle={toggle}\n />\n )}\n {!collapsed && (\n <div className={mergeClasses(styles.bodyStack)} style={bodyStyle}>\n {children}\n </div>\n )}\n </div>\n );\n};\n\nexport default Section;\n","import React from 'react';\nimport {\n Button,\n Text,\n Toolbar,\n ToolbarButton,\n tokens,\n} from '@fluentui/react-components';\nimport { ChevronDown20Regular, ChevronRight20Regular } from '@fluentui/react-icons';\nimport type { SectionHeaderProps } from '../types';\n\n// v9 section header: flex title + status on the left, a v9 <Toolbar> of commandItems on the\n// right (replacing the v8 CommandBar), Dynamics neutral underline, optional collapse chevron.\n\n/** Section header bar (Fluent v9): title + status (left), toolbar / actions (right), optional collapse toggle. */\nexport const SectionHeader: React.FC<SectionHeaderProps> = ({\n title,\n statusText,\n showCommandBar,\n commandItems = [],\n actions,\n collapsible,\n collapsed,\n onToggle,\n}) => {\n const rootStyle: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexWrap: 'nowrap',\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n marginBottom: 16,\n minHeight: 48,\n width: '100%',\n };\n const leftStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 };\n const statusStyle: React.CSSProperties = {\n marginLeft: 8,\n fontSize: tokens.fontSizeBase200,\n color: tokens.colorNeutralForeground3,\n };\n\n return (\n <div style={rootStyle}>\n <div style={leftStyle}>\n {collapsible && (\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={collapsed ? <ChevronRight20Regular /> : <ChevronDown20Regular />}\n onClick={onToggle}\n aria-label={collapsed ? 'Expand section' : 'Collapse section'}\n aria-expanded={!collapsed}\n />\n )}\n {title && (\n <Text weight=\"semibold\" size={300}>\n {title}\n </Text>\n )}\n {statusText && <span style={statusStyle}>{statusText}</span>}\n </div>\n {actions ? (\n <div>{actions}</div>\n ) : showCommandBar && commandItems.length > 0 ? (\n <Toolbar aria-label=\"Section commands\" size=\"small\">\n {commandItems.map((item) => (\n <ToolbarButton\n key={item.id}\n icon={item.icon}\n appearance={item.appearance === 'primary' ? 'primary' : 'subtle'}\n disabled={item.disabled}\n onClick={item.onClick}\n >\n {item.label}\n </ToolbarButton>\n ))}\n </Toolbar>\n ) : null}\n </div>\n );\n};\n\nexport default SectionHeader;\n","import React from 'react';\nimport { tokens } from '@fluentui/react-components';\nimport type { SectionCardProps } from '../types';\nimport { Section } from './Section';\n\n/**\n * A Section with the Dynamics blue accent top border (Fluent v9).\n * The accent is an inline `borderTop` so it wins over the card variant's inline `border`\n * (see Section: `style` is spread after the card chrome). Defaults to the v9 brand stroke.\n */\nexport const SectionCard: React.FC<SectionCardProps> = ({\n accentColor = tokens.colorBrandStroke1,\n accentWidth = 3,\n variant = 'card',\n style,\n ...rest\n}) => (\n <Section\n variant={variant}\n {...rest}\n style={{ borderTop: `${accentWidth}px solid ${accentColor}`, ...style }}\n />\n);\n\nexport default SectionCard;\n","import React from 'react';\nimport { Text, tokens } from '@fluentui/react-components';\nimport type { FormHeaderProps } from '../types';\n\n/** Dynamics form header (Fluent v9): persona + title/status (left), KPI/header fields (right). */\nexport const FormHeader: React.FC<FormHeaderProps> = ({\n title,\n subtitle,\n status,\n titleColor,\n subtitleColor,\n persona,\n actions,\n className,\n}) => {\n const rootStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n padding: '12px 24px',\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n };\n const mainStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', gap: 12, minWidth: 0 };\n const titleRowStyle: React.CSSProperties = { display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' };\n const statusStyle: React.CSSProperties = { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 };\n const subtitleStyle: React.CSSProperties = {\n fontSize: tokens.fontSizeBase200,\n color: subtitleColor || tokens.colorNeutralForeground3,\n marginTop: 2,\n };\n\n return (\n <div className={className} style={rootStyle}>\n <div style={mainStyle}>\n {persona}\n <div>\n <div style={titleRowStyle}>\n {title != null && (\n <Text weight=\"semibold\" size={400} style={titleColor ? { color: titleColor } : undefined}>\n {title}\n </Text>\n )}\n {status != null && <span style={statusStyle}>{status}</span>}\n </div>\n {subtitle != null && <div style={subtitleStyle}>{subtitle}</div>}\n </div>\n </div>\n {actions != null && <div>{actions}</div>}\n </div>\n );\n};\n\nexport default FormHeader;\n","import React, { useState } from 'react';\nimport { TabList, Tab, type SelectTabData, type SelectTabEvent } from '@fluentui/react-components';\nimport type { PivotSurfaceProps } from '../types';\n\n/** Tabbed surface (Fluent v9 `TabList`). Controlled via `selectedId`/`onTabChange` or uncontrolled. */\nexport const PivotSurface: React.FC<PivotSurfaceProps> = ({\n tabs,\n selectedId,\n defaultSelectedId,\n onTabChange,\n appearance = 'transparent',\n size = 'medium',\n className,\n}) => {\n // Seed to the requested default, else the first *enabled* tab (don't open a disabled one).\n const firstEnabledId = tabs.find((t) => !t.disabled)?.id ?? tabs[0]?.id;\n const [internal, setInternal] = useState<string | undefined>(defaultSelectedId ?? firstEnabledId);\n const selected = selectedId ?? internal;\n\n const handleSelect = (_e: SelectTabEvent, data: SelectTabData) => {\n const id = String(data.value);\n if (selectedId == null) setInternal(id);\n onTabChange?.(id);\n };\n\n const active = tabs.find((t) => t.id === selected) ?? tabs[0];\n\n return (\n <div className={className}>\n <TabList selectedValue={selected} onTabSelect={handleSelect} appearance={appearance} size={size}>\n {tabs.map((t) => (\n <Tab key={t.id} value={t.id} icon={t.icon} disabled={t.disabled}>\n {t.label}\n </Tab>\n ))}\n </TabList>\n <div>{active?.content}</div>\n </div>\n );\n};\n\nexport default PivotSurface;\n","import React from 'react';\nimport {\n Toolbar,\n ToolbarButton,\n Menu,\n MenuTrigger,\n MenuPopover,\n MenuList,\n MenuItem,\n} from '@fluentui/react-components';\nimport { MoreHorizontal20Regular } from '@fluentui/react-icons';\nimport type { CommandSurfaceProps, SurfaceToolbarItem } from '../types';\n\nfunction renderToolbarButton(item: SurfaceToolbarItem): React.ReactElement {\n return (\n <ToolbarButton\n key={item.id}\n icon={item.icon}\n appearance={item.appearance === 'primary' ? 'primary' : 'subtle'}\n disabled={item.disabled}\n onClick={item.onClick}\n >\n {item.label}\n </ToolbarButton>\n );\n}\n\n/** A Dynamics-style command bar (Fluent v9 `Toolbar`), with an optional overflow menu + far items. */\nexport const CommandSurface: React.FC<CommandSurfaceProps> = ({\n items,\n overflowItems,\n farItems,\n size = 'small',\n className,\n}) => {\n const hasFar = Boolean(farItems && farItems.length > 0);\n const hasOverflow = Boolean(overflowItems && overflowItems.length > 0);\n\n const hasPrimary = items.length > 0 || hasOverflow;\n\n return (\n <div className={className} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {hasPrimary && (\n <Toolbar aria-label=\"Commands\" size={size}>\n {items.map(renderToolbarButton)}\n {hasOverflow && (\n <Menu>\n <MenuTrigger disableButtonEnhancement>\n <ToolbarButton aria-label=\"More commands\" icon={<MoreHorizontal20Regular />} />\n </MenuTrigger>\n <MenuPopover>\n <MenuList>\n {overflowItems!.map((item) => (\n <MenuItem key={item.id} icon={item.icon} disabled={item.disabled} onClick={item.onClick}>\n {item.label}\n </MenuItem>\n ))}\n </MenuList>\n </MenuPopover>\n </Menu>\n )}\n </Toolbar>\n )}\n {hasFar && (\n // marginLeft:auto keeps far items right-aligned whether or not a primary toolbar renders.\n <Toolbar aria-label=\"Secondary commands\" size={size} style={{ marginLeft: 'auto' }}>\n {farItems!.map(renderToolbarButton)}\n </Toolbar>\n )}\n </div>\n );\n};\n\nexport default CommandSurface;\n","import React from 'react';\nimport { Button, tokens } from '@fluentui/react-components';\nimport type { ActionBarProps, SurfaceActionButton } from '../types';\n\nfunction renderButton(b: SurfaceActionButton): React.ReactElement {\n // v9 appearance: primary → primary, subtle → subtle, default → secondary.\n const appearance = b.appearance === 'primary' ? 'primary' : b.appearance === 'subtle' ? 'subtle' : 'secondary';\n return (\n <Button key={b.id} appearance={appearance} icon={b.icon} disabled={b.disabled} onClick={b.onClick}>\n {b.label}\n </Button>\n );\n}\n\n/** A sticky footer bar of action buttons (Fluent v9), with optional left-aligned buttons. */\nexport const ActionBar: React.FC<ActionBarProps> = ({ buttons, alignment = 'right', sticky = true, className }) => {\n const justify = alignment === 'left' ? 'flex-start' : alignment === 'center' ? 'center' : 'flex-end';\n const visible = buttons.filter((b) => !b.hidden);\n const left = visible.filter((b) => b.position === 'left');\n const right = visible.filter((b) => b.position !== 'left');\n\n const rootStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: left.length ? 'space-between' : justify,\n gap: 8,\n padding: '12px 24px',\n borderTop: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n ...(sticky ? { position: 'sticky', bottom: 0, zIndex: 1 } : {}),\n };\n\n return (\n <div className={className} style={rootStyle}>\n {left.length > 0 && <div style={{ display: 'flex', gap: 8 }}>{left.map(renderButton)}</div>}\n <div style={{ display: 'flex', gap: 8, justifyContent: justify }}>{right.map(renderButton)}</div>\n </div>\n );\n};\n\nexport default ActionBar;\n","import React from 'react';\nimport { tokens } from '@fluentui/react-components';\nimport type { FooterProps } from '../types';\n\n/** A sticky footer region (free-form children, Fluent v9) — e.g. for dialog/panel actions. */\nexport const Footer: React.FC<FooterProps> = ({ sticky = true, align = 'right', className, children }) => {\n const justify = align === 'left' ? 'flex-start' : align === 'center' ? 'center' : 'flex-end';\n const rootStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: justify,\n gap: 8,\n padding: '12px 24px',\n borderTop: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n ...(sticky ? { position: 'sticky', bottom: 0, zIndex: 1 } : {}),\n };\n return (\n <div className={className} style={rootStyle}>\n {children}\n </div>\n );\n};\n\nexport default Footer;\n","import React from 'react';\nimport { Dialog, DialogSurface, Button, Text, tokens } from '@fluentui/react-components';\nimport { Dismiss20Regular } from '@fluentui/react-icons';\nimport type { FormDialogSurfaceProps } from '../types';\nimport { dialogWidthCss, dialogHeightCss } from '../../core/sizePresets';\n\n// The Fluent v9 counterpart of the v8 FormDialogSurface (a `<Modal>`): a controlled\n// `<Dialog>` + `<DialogSurface>` sized from the SHARED sizing scalars (dialogWidthCss /\n// dialogHeightCss — the same 1200 / 95vh contract the v8 skin and the codegen use), with a\n// custom header (title/subheader | counter + close), a scrolling content region, and a\n// sticky footer. Content is rendered directly in DialogSurface (padding managed here) so the\n// flex-column scroll layout matches the v8 Modal main/scrollableContent.\n\n/**\n * Full Dynamics form-dialog (Fluent v9 `Dialog`). Default width 1200 (lg), height 95vh.\n * `onDismiss` is the close affordance — when omitted, no close button renders. `isBlocking`\n * maps to the dialog `modalType` (`modal` vs `non-modal`).\n */\nexport const FormDialogSurface: React.FC<FormDialogSurfaceProps> = ({\n isOpen,\n onDismiss,\n title,\n subheader,\n size,\n width,\n height,\n isBlocking = true,\n recordCounter,\n footer,\n className,\n children,\n}) => {\n const widthCss = dialogWidthCss({ width, size });\n const heightCss = dialogHeightCss(height);\n const showHeader = Boolean(title) || Boolean(recordCounter) || Boolean(onDismiss);\n\n const headerStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n padding: '12px 20px',\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n };\n const counterStyle: React.CSSProperties = { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 };\n\n return (\n <Dialog\n open={isOpen}\n modalType={isBlocking ? 'modal' : 'non-modal'}\n onOpenChange={(_e, data) => {\n if (!data.open) onDismiss?.();\n }}\n >\n <DialogSurface\n className={className}\n style={{\n maxWidth: '95vw',\n width: widthCss,\n height: heightCss,\n maxHeight: '95vh',\n display: 'flex',\n flexDirection: 'column',\n padding: 0,\n }}\n >\n {showHeader && (\n <div style={headerStyle}>\n <div style={{ display: 'flex', flexDirection: 'column', minWidth: 0 }}>\n {title && (\n <Text weight=\"semibold\" size={400}>\n {title}\n </Text>\n )}\n {subheader && (\n <span style={{ fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3, marginTop: 2 }}>\n {subheader}\n </span>\n )}\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {recordCounter && (\n <span style={counterStyle}>\n {recordCounter.current} of {recordCounter.total}\n </span>\n )}\n {onDismiss && (\n <Button appearance=\"subtle\" aria-label=\"Close\" icon={<Dismiss20Regular />} onClick={onDismiss} />\n )}\n </div>\n </div>\n )}\n <div style={{ flex: 1, minHeight: 0, overflow: 'auto', padding: 20 }}>{children}</div>\n {footer && (\n <div style={{ borderTop: `1px solid ${tokens.colorNeutralStroke2}`, padding: '12px 20px' }}>{footer}</div>\n )}\n </DialogSurface>\n </Dialog>\n );\n};\n\nexport default FormDialogSurface;\n","import React from 'react';\nimport { Dialog, DialogSurface, Text, tokens } from '@fluentui/react-components';\nimport type { ModalSurfaceProps } from '../types';\nimport { dialogWidthPx, MODAL_AUTOSIZE_MIN_WIDTH } from '../../core/sizePresets';\n\n/** A generic modal (Fluent v9 `Dialog`) — title + content + optional footer; lighter than FormDialogSurface. */\nexport const ModalSurface: React.FC<ModalSurfaceProps> = ({\n isOpen,\n onDismiss,\n title,\n size,\n width,\n isBlocking = true,\n autoSize,\n footer,\n className,\n children,\n}) => {\n const sizing: React.CSSProperties = autoSize\n ? { width: 'auto', minWidth: MODAL_AUTOSIZE_MIN_WIDTH, maxWidth: '100%' }\n : { maxWidth: '95vw', width: `${dialogWidthPx({ width, size })}px` };\n\n return (\n <Dialog\n open={isOpen}\n modalType={isBlocking ? 'modal' : 'non-modal'}\n onOpenChange={(_e, data) => {\n if (!data.open) onDismiss?.();\n }}\n >\n <DialogSurface className={className} style={{ ...sizing, padding: 0 }}>\n {title && (\n <div style={{ padding: '16px 20px 0' }}>\n <Text weight=\"semibold\" size={500}>\n {title}\n </Text>\n </div>\n )}\n <div style={{ padding: 20 }}>{children}</div>\n {footer && (\n <div\n style={{\n borderTop: `1px solid ${tokens.colorNeutralStroke2}`,\n padding: '12px 20px',\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n }}\n >\n {footer}\n </div>\n )}\n </DialogSurface>\n </Dialog>\n );\n};\n\nexport default ModalSurface;\n","import React from 'react';\nimport {\n OverlayDrawer,\n DrawerHeader,\n DrawerHeaderTitle,\n DrawerBody,\n Button,\n} from '@fluentui/react-components';\nimport { Dismiss24Regular } from '@fluentui/react-icons';\nimport type { PanelSurfaceProps } from '../types';\n\n// The Fluent v9 counterpart of the v8 PanelSurface (a `<Panel>`): a right-edge\n// `<OverlayDrawer>`. The v8 medium-vs-custom width heuristic (>500 → medium) maps to the\n// v9 Drawer `size`; an explicit `width` renders a custom-width drawer. `isLightDismiss`\n// controls backdrop-click dismissal (Esc still closes); `isNonModal` drops the blocking overlay.\n\n/** A Dynamics side panel (Fluent v9 `OverlayDrawer`). */\nexport const PanelSurface: React.FC<PanelSurfaceProps> = ({\n isOpen,\n onDismiss,\n title,\n drawerSize,\n width,\n hasCloseButton = true,\n isLightDismiss = true,\n isNonModal = false,\n footer,\n children,\n}) => {\n const size = drawerSize ?? (width != null && width > 500 ? 'medium' : 'small');\n const customWidthStyle = width != null ? ({ width: `${width}px` } as React.CSSProperties) : undefined;\n\n return (\n <OverlayDrawer\n open={isOpen}\n position=\"end\"\n size={size}\n modalType={isNonModal ? 'non-modal' : 'modal'}\n style={customWidthStyle}\n onOpenChange={(_e, data) => {\n if (data.open) return;\n // Honor isLightDismiss for backdrop clicks; Esc + explicit close always dismiss.\n if (data.type === 'backdropClick' && !isLightDismiss) return;\n onDismiss?.();\n }}\n >\n <DrawerHeader>\n <DrawerHeaderTitle\n action={\n hasCloseButton && onDismiss ? (\n <Button appearance=\"subtle\" aria-label=\"Close\" icon={<Dismiss24Regular />} onClick={onDismiss} />\n ) : undefined\n }\n >\n {title}\n </DrawerHeaderTitle>\n </DrawerHeader>\n <DrawerBody>\n <div style={{ padding: '12px 0' }}>{children}</div>\n {footer && <div style={{ marginTop: 'auto', paddingTop: 12 }}>{footer}</div>}\n </DrawerBody>\n </OverlayDrawer>\n );\n};\n\nexport default PanelSurface;\n","import React from 'react';\nimport { Popover, PopoverSurface, type PositioningShorthand } from '@fluentui/react-components';\nimport type { CalloutSurfaceProps } from '../types';\nimport { calloutWidthPx } from '../../core/sizePresets';\n\n// The Fluent v9 counterpart of the v8 CalloutSurface (a `<Callout>`): a controlled,\n// target-anchored `<Popover>` + `<PopoverSurface>`. v8's `target` (selector / element / ref)\n// is resolved to an element and passed via `positioning.target`; there is no PopoverTrigger\n// because anchoring comes from the target (matching the v8 target-based API). `isBeakVisible`\n// maps to `withArrow`.\n\nfunction resolveTarget(target: CalloutSurfaceProps['target']): HTMLElement | null {\n if (!target) return null;\n if (typeof target === 'string') return document.querySelector<HTMLElement>(target);\n if ('current' in target) return (target.current as HTMLElement | null) ?? null;\n return target as HTMLElement;\n}\n\n/** A lightweight contextual callout (Fluent v9 `Popover`) anchored to a target. */\nexport const CalloutSurface: React.FC<CalloutSurfaceProps> = ({\n target,\n isOpen = true,\n onDismiss,\n width,\n position = 'below',\n align = 'start',\n isBeakVisible = true,\n className,\n children,\n}) => {\n if (!isOpen) return null;\n const el = resolveTarget(target);\n // If the target can't be resolved (selector miss / target={null}), the Popover renders\n // unanchored (position defaults apply) rather than throwing — an intentional soft fallback.\n const positioning: PositioningShorthand = { position, align, ...(el ? { target: el } : {}) };\n\n return (\n <Popover\n open\n trapFocus={false}\n withArrow={isBeakVisible}\n positioning={positioning}\n onOpenChange={(_e, data) => {\n if (!data.open) onDismiss?.();\n }}\n >\n <PopoverSurface className={className} style={{ width: calloutWidthPx(width), padding: 16 }}>\n {children}\n </PopoverSurface>\n </Popover>\n );\n};\n\nexport default CalloutSurface;\n","import React from 'react';\nimport { Tooltip } from '@fluentui/react-components';\nimport type { TooltipSurfaceProps } from '../types';\n\nconst DELAY_MS: Record<NonNullable<TooltipSurfaceProps['delay']>, number> = {\n zero: 0,\n medium: 250,\n long: 500,\n};\n\n/** A tooltip wrapper (Fluent v9 `Tooltip`). */\nexport const TooltipSurface: React.FC<TooltipSurfaceProps> = ({\n content,\n position = 'above',\n delay = 'medium',\n relationship = 'label',\n children,\n}) => (\n <Tooltip content={content} relationship={relationship} positioning={position} showDelay={DELAY_MS[delay]}>\n {children}\n </Tooltip>\n);\n\nexport default TooltipSurface;\n"],"mappings":"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","names":["useState","useEffect","jsx","useState","makeStyles","mergeClasses","tokens","tokens","jsx","jsx","jsxs","useStyles","makeStyles","useState","tokens","mergeClasses","tokens","jsx","tokens","Text","tokens","jsx","jsxs","useState","jsx","jsxs","Toolbar","ToolbarButton","jsx","jsxs","Button","tokens","jsx","jsxs","tokens","jsx","Button","Text","tokens","jsx","jsxs","tokens","Text","Button","Dialog","DialogSurface","Text","tokens","jsx","jsxs","Dialog","DialogSurface","Text","tokens","Button","jsx","jsxs","jsx","jsx"]}
1
+ {"version":3,"sources":["../src/core/sizePresets.ts","../src/core/columns.ts","../src/core/ceLayout.ts","../src/responsive/breakpoints.ts","../src/responsive/builders.ts","../src/tokens/tokens.ts","../src/tokens/density.ts","../src/hooks/useContainerSize.ts","../src/hooks/useContainerWidth.ts","../src/hooks/useContainerBreakpoint.ts","../src/hooks/useResponsiveValue.ts","../src/hooks/useMediaQuery.ts","../src/hooks/useDensity.ts","../src/hooks/useLook.ts","../src/v9/theme.ts","../src/v9/containers/FormSurface.tsx","../src/v9/containers/PageSurface.tsx","../src/v9/containers/Section.tsx","../src/v9/layouts/FieldRow.tsx","../src/v9/containers/SectionHeader.tsx","../src/v9/containers/SectionCard.tsx","../src/v9/containers/FormHeader.tsx","../src/v9/containers/PivotSurface.tsx","../src/v9/containers/CommandSurface.tsx","../src/v9/containers/ActionBar.tsx","../src/v9/containers/Footer.tsx","../src/v9/layouts/TabColumns.tsx","../src/v9/overlays/FormDialogSurface.tsx","../src/v9/overlays/ModalSurface.tsx","../src/v9/overlays/PanelSurface.tsx","../src/v9/overlays/CalloutSurface.tsx","../src/v9/overlays/TooltipSurface.tsx"],"sourcesContent":["// Pure-TS sizing scalars for overlay surfaces. The SINGLE SOURCE of the numbers\n// that both surface-kit's runtime overlays AND the export-engine codegen use, so a\n// Dialog is 1200px wide in exactly one place. Framework-agnostic (no react/@fluentui).\n//\n// Values mirror export-engine/src/generators/FormCodeGenerator.ts (v8 branches):\n// dialog: default width 1200; height <=100 -> `${h}vh` else '95vh'\n// panel: kind = (width ?? 480) > 500 ? 'medium' : 'custom'; custom width = width ?? 480\n// callout (form-type): default width 320; directionalHint 'bottomLeftEdge'\n// v1c wires export-engine to import these; a byte-identical emission test guards drift.\n\n// --- Dialog --------------------------------------------------------------------\n\nexport type DialogSizePreset = 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';\n\n// NOTE: only the lg = 1200 default and an explicit `width` are the shared-with-codegen\n// contract (export-engine does `width ?? 1200`). The sm/md/xl/fullscreen presets are\n// surface-kit runtime conveniences with no codegen counterpart — v1c does NOT consume them.\nexport const DIALOG_SIZE_PX = {\n sm: 600,\n md: 900,\n lg: 1200,\n xl: 1600,\n} as const;\n\n/** Resolved dialog width in px. Explicit `width` wins; else the preset (default lg = 1200, the codegen default). */\nexport function dialogWidthPx(opts: { width?: number; size?: DialogSizePreset } = {}): number {\n if (typeof opts.width === 'number') return opts.width;\n const size = opts.size ?? 'lg';\n // fullscreen is clamped by 95vw at the CSS layer; fall back to the largest preset for the px hint.\n if (size === 'fullscreen') return DIALOG_SIZE_PX.xl;\n return DIALOG_SIZE_PX[size];\n}\n\n/** Dialog width as a CSS value — '95vw' for the fullscreen preset (no explicit width), else `${px}px`. */\nexport function dialogWidthCss(opts: { width?: number; size?: DialogSizePreset } = {}): string {\n if (opts.size === 'fullscreen' && opts.width == null) return '95vw';\n return `${dialogWidthPx(opts)}px`;\n}\n\n/** Dialog height as a CSS value. <=100 is treated as a vh percentage; otherwise the 95vh cap (codegen rule). */\nexport function dialogHeightCss(height?: number): string {\n return height != null && height <= 100 ? `${height}vh` : '95vh';\n}\n\n/** Min width for an auto-sized ModalSurface (the Track-and-Ship \"min 1000, auto\" pattern). */\nexport const MODAL_AUTOSIZE_MIN_WIDTH = 1000;\n\n// --- Panel ---------------------------------------------------------------------\n\nexport type PanelKind = 'medium' | 'custom';\nexport const PANEL_DEFAULT_WIDTH = 480;\n\n/** Codegen-parity panel kind: wide panels use Fluent `medium`, narrow ones `custom` + customWidth. */\nexport function panelKindFromWidth(width?: number): PanelKind {\n return (width ?? PANEL_DEFAULT_WIDTH) > 500 ? 'medium' : 'custom';\n}\n\n/** customWidth px for a `custom` panel. */\nexport function panelCustomWidthPx(width?: number): number {\n return width ?? PANEL_DEFAULT_WIDTH;\n}\n\n// --- Callout -------------------------------------------------------------------\n\nexport const CALLOUT_DEFAULT_WIDTH = 320;\n\n/** Form-type callout defaults (the export-engine form-callout path emits width + directionalHint only). */\nexport const calloutFormDefaults = {\n width: CALLOUT_DEFAULT_WIDTH,\n directionalHint: 'bottomLeftEdge',\n} as const;\n\nexport function calloutWidthPx(width?: number): number {\n return width ?? CALLOUT_DEFAULT_WIDTH;\n}\n","// Pure-TS column helpers shared by layouts/containers and the responsive builders.\nexport type ColumnCount = 1 | 2 | 3 | 4;\n\n/** CSS grid-template-columns for an N-column layout. Matches codegen `repeat(N, 1fr)`. */\nexport function gridTemplateForColumns(columns: ColumnCount): string {\n return `repeat(${columns}, 1fr)`;\n}\n\n/** Clamp a cell column-span to the available column count (min 1). */\nexport function clampSpan(span: number, columns: ColumnCount): number {\n if (!Number.isFinite(span)) return 1;\n return Math.max(1, Math.min(Math.round(span), columns));\n}\n","// Pure-TS layout rules MEASURED on a live Dynamics 365 CE model-driven form (the UCI \"new look\").\n// Evidence: dynamics-ui-kit apps/ce-parity/reference/ (captures + ce-layout-reference.json).\n// No React / Fluent imports: this file is inlined by export-engine like the rest of core/.\n\n/** The appearance family a surface renders in: the kit's existing look, or the measured CE form. */\nexport type SurfaceLook = 'default' | 'ce';\n\n/**\n * A Dynamics tab column never renders narrower than this (px). Measured: a 25% column in a\n * 1106px tab body renders 340, not 276.5.\n */\nexport const CE_TAB_COLUMN_MIN_WIDTH = 340;\n\n/**\n * Normalise declared column shares so they sum to 100: negative or non-finite shares count as 0,\n * and all-zero (or empty-of-positive) input becomes equal shares. `TabColumns` renders the\n * NORMALISED shares, and `resolveTabColumnWidths` normalises too, so the CSS and this function\n * always agree. (CSS flexbox treats a flex-grow sum below 1 differently — it leaves free space\n * unused — and never grows a flex-grow-0 item; normalising removes both divergences.)\n */\nexport function normalizeColumnShares(shares: readonly number[]): number[] {\n const clean = shares.map((s) => (Number.isFinite(s) && s > 0 ? s : 0));\n const total = clean.reduce((a, b) => a + b, 0);\n if (total <= 0) return shares.map(() => 100 / (shares.length || 1));\n return clean.map((s) => (s / total) * 100);\n}\n\n/**\n * Resolve the rendered width of each tab column, the way Dynamics does.\n *\n * Each column takes its declared share (the formxml column `width`, e.g. 33 / 42 / 25) of the\n * space left after the gaps, but never goes below `minWidth`. The shortfall of a clamped column is\n * taken from the unclamped columns in proportion to their declared shares. That is CSS flexbox\n * with `flex: <share> 1 0` and `min-width` over NORMALISED shares (see normalizeColumnShares),\n * which is how `TabColumns` renders it.\n * This function exists so the rule can be tested and used where there is no DOM (e.g. sizing\n * from a PCF `allocatedWidth`).\n *\n * Verified against every measured layout: 33/42/25 at a 1450, 1240 and 1106px row gives\n * 478.5/609/362.5, 396/504/340 and 340/426/340; 34/33/33 at 1450 gives 493/478.5/478.5.\n *\n * @param shares Declared column shares (percentages are the usual case; they are normalised).\n * @param available Row width in px AFTER subtracting the gaps between columns.\n * @param minWidth Minimum rendered column width. Defaults to the measured 340.\n * @returns Widths in px, in column order. If every column hits the floor the widths sum to more\n * than `available`; the caller wraps or scrolls (Dynamics' behaviour there is unmeasured).\n */\nexport function resolveTabColumnWidths(\n shares: readonly number[],\n available: number,\n minWidth: number = CE_TAB_COLUMN_MIN_WIDTH,\n): number[] {\n if (shares.length === 0) return [];\n shares = normalizeColumnShares(shares);\n const clamped = new Set<number>();\n let widths: number[] = [];\n // Resolve like the flexbox algorithm: distribute, freeze violators, redistribute, until none violate.\n for (let pass = 0; pass <= shares.length; pass++) {\n const free = available - clamped.size * minWidth;\n const total = shares.reduce((sum, s, i) => (clamped.has(i) ? sum : sum + Math.max(0, s)), 0);\n widths = shares.map((s, i) => {\n if (clamped.has(i)) return minWidth;\n return total > 0 ? (Math.max(0, s) / total) * free : free / (shares.length - clamped.size);\n });\n // CSS Flexbox §9.7: when the total violation is positive (only min-width constraints exist\n // here, so it always is), freeze EVERY min-violating item at once, then redistribute.\n const violators = widths.map((w, i) => (!clamped.has(i) && w < minWidth ? i : -1)).filter((i) => i >= 0);\n if (violators.length === 0) break;\n violators.forEach((i) => clamped.add(i));\n }\n return widths;\n}\n\n/**\n * Row width (px) below which a field label declared \"beside\" (formxml `Left`) is drawn ABOVE its\n * input instead.\n *\n * ★ PROVISIONAL. Measured only as a bracket: beside at a 362px row, above at a 306px row. 340 is\n * the column floor and sits inside the bracket, but the exact switch point has NOT been\n * observed. It is an open item in the reference; re-measure before relying on the exact value.\n */\nexport const CE_LABEL_ABOVE_BELOW_ROW_WIDTH = 340;\n","// Named responsive breakpoints (px). The 480/768 cutoffs match the export-engine\n// section/field stacking; CARD_REFLOW_WIDTH (900) matches the CardGrid reflow\n// emitter (a separate cutoff). Pure-TS (no react/@fluentui).\nexport type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport const BREAKPOINTS: Record<Breakpoint, number> = {\n xs: 0,\n sm: 480,\n md: 768,\n lg: 1024,\n xl: 1366,\n};\n\n/** The card-grid reflow cutoff the codegen CardGrid emitter uses (distinct from the 480/768 field/section cutoffs). */\nexport const CARD_REFLOW_WIDTH = 900;\n\nconst DESCENDING: Breakpoint[] = ['xl', 'lg', 'md', 'sm', 'xs'];\nconst ASCENDING: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl'];\n\n/** Largest breakpoint whose min-width is <= width. */\nexport function resolveBreakpoint(width: number): Breakpoint {\n for (const bp of DESCENDING) {\n if (width >= BREAKPOINTS[bp]) return bp;\n }\n return 'xs';\n}\n\nexport type ResponsiveValue<T> = T | Partial<Record<Breakpoint, T>>;\n\nfunction isResponsiveMap<T>(v: ResponsiveValue<T>): v is Partial<Record<Breakpoint, T>> {\n return typeof v === 'object' && v !== null && ASCENDING.some((bp) => bp in (v as object));\n}\n\n/**\n * Resolve a responsive value at a breakpoint, cascading mobile-first: pick the\n * nearest defined value at or below `breakpoint`, else the nearest defined above.\n */\nexport function resolveResponsiveValue<T>(value: ResponsiveValue<T>, breakpoint: Breakpoint): T | undefined {\n if (!isResponsiveMap(value)) return value as T;\n const map = value;\n const idx = ASCENDING.indexOf(breakpoint);\n for (let i = idx; i >= 0; i--) {\n const v = map[ASCENDING[i]];\n if (v !== undefined) return v;\n }\n for (let i = idx + 1; i < ASCENDING.length; i++) {\n const v = map[ASCENDING[i]];\n if (v !== undefined) return v;\n }\n return undefined;\n}\n","// Pure-TS responsive style-object builders. Every responsive stacking decision in\n// surface-kit flows through here so viewport (`mode:'media'`) and container\n// (`mode:'container'`) stacking share the same 480/768 cutoffs. The numeric values\n// (gaps, minHeight, alignItems) mirror the export-engine fieldGrid/fieldRow/\n// tabSectionsGrid emitters so the eventual emitMode:'surface-kit' rewrite is parity.\n// Returned objects are structurally compatible with Fluent's `IStyle` (the `selectors`\n// shape) but typed locally so this layer stays framework-agnostic (no @fluentui import).\nimport { BREAKPOINTS } from './breakpoints';\nimport { gridTemplateForColumns, type ColumnCount } from '../core/columns';\n\nexport type StyleObject = Record<string, unknown>;\nexport type ResponsiveMode = 'media' | 'container';\n\nfunction atRule(mode: ResponsiveMode, maxPx: number): string {\n return mode === 'container'\n ? `@container (max-width: ${maxPx}px)`\n : `@media (max-width: ${maxPx}px)`;\n}\n\n/** N-column field grid that caps at 2 columns on tablet (<=768) and stacks to 1 on phone (<=480). */\nexport function fieldGridStyle(columns: ColumnCount, mode: ResponsiveMode = 'media'): StyleObject {\n const capped = Math.min(columns, 2) as ColumnCount;\n return {\n display: 'grid',\n gridTemplateColumns: gridTemplateForColumns(columns),\n gap: '4px 24px',\n selectors: {\n [atRule(mode, BREAKPOINTS.md)]: { gridTemplateColumns: gridTemplateForColumns(capped) },\n [atRule(mode, BREAKPOINTS.sm)]: { gridTemplateColumns: '1fr' },\n },\n };\n}\n\n/** Multi-section tab row that collapses straight to a single column on tablet (<=768). */\nexport function sectionStackingStyle(gridTemplateColumns: string, mode: ResponsiveMode = 'media'): StyleObject {\n return {\n display: 'grid',\n gridTemplateColumns,\n gap: 16,\n alignItems: 'start',\n selectors: {\n [atRule(mode, BREAKPOINTS.md)]: { gridTemplateColumns: '1fr' },\n },\n };\n}\n\n/** \"Label : input\" row that collapses the label above the input on phone (<=480). */\nexport function fieldRowStyle(labelWidth = '130px', mode: ResponsiveMode = 'media'): StyleObject {\n return {\n display: 'grid',\n gridTemplateColumns: `${labelWidth} 1fr`,\n alignItems: 'center',\n gap: 8,\n minHeight: 38,\n selectors: {\n [atRule(mode, BREAKPOINTS.sm)]: { gridTemplateColumns: '1fr', alignItems: 'flex-start', minHeight: 0, gap: 4 },\n },\n };\n}\n","// Re-exported from @dataverse-kit/design-tokens — the single canonical source of the\n// Dynamics design tokens. surface-kit no longer keeps its own copy (this retires the old\n// \"SYNCED FROM reusable-components\" duplication). The values are pure-TS (no react /\n// no @fluentui), so they remain safe to import from anywhere. `createDynamicsTheme()` and\n// `density` stay here in surface-kit (see ./theme and ./density).\nexport { colors, spacing, typography, radius, layout, ceForm } from '@dataverse-kit/design-tokens';\n","// Spacing density multiplier — `comfortable` (Dynamics default) vs `compact`\n// (denser forms / embedded PCF). Pure-TS.\nexport type Density = 'comfortable' | 'compact';\n\nexport const densityScale = {\n comfortable: 1,\n compact: 0.75,\n} as const;\n\n/** Scale a base spacing value (px) by the active density. */\nexport function scaleSpacing(value: number, density: Density = 'comfortable'): number {\n return Math.round(value * densityScale[density]);\n}\n","// SYNCED FROM: shared/responsive-patterns/03-layouts/container-query/ContainerQuery.tsx (useContainerSize)\n// Inlined, not aliased: shared/responsive-patterns is outside the npm workspace. The\n// ContainerSize type is inlined here too (rather than vendoring shared/shared/types).\n// This is a React hook, so it lives in hooks/ (NOT responsive/, which must stay\n// framework-agnostic for the ./responsive subpath that export-engine inlines).\nimport * as React from 'react';\nimport { useState, useEffect } from 'react';\n\nexport interface ContainerSize {\n width: number;\n height: number;\n inlineSize: number;\n blockSize: number;\n}\n\n/** Observe an element's size via ResizeObserver. Pass a ref; returns {width,height,inlineSize,blockSize}. */\nexport function useContainerSize<T extends HTMLElement = HTMLElement>(ref: React.RefObject<T>): ContainerSize {\n const [size, setSize] = useState<ContainerSize>({ width: 0, height: 0, inlineSize: 0, blockSize: 0 });\n\n useEffect(() => {\n if (!ref.current || typeof ResizeObserver === 'undefined') return;\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect;\n const inlineSize = entry.borderBoxSize?.[0]?.inlineSize ?? width;\n const blockSize = entry.borderBoxSize?.[0]?.blockSize ?? height;\n setSize({ width, height, inlineSize, blockSize });\n }\n });\n\n observer.observe(ref.current);\n return () => observer.disconnect();\n }, [ref]);\n\n return size;\n}\n","import * as React from 'react';\nimport { useRef } from 'react';\nimport { useContainerSize } from './useContainerSize';\n\n/**\n * Create-and-return a ref plus the observed width of the element it is attached to.\n * `const [ref, width] = useContainerWidth(); return <div ref={ref}>…</div>`.\n */\nexport function useContainerWidth<T extends HTMLElement = HTMLDivElement>(): [React.RefObject<T>, number] {\n const ref = useRef<T>(null);\n const { width } = useContainerSize(ref);\n return [ref, width];\n}\n","import type * as React from 'react';\nimport { resolveBreakpoint, type Breakpoint } from '../responsive/breakpoints';\nimport { useContainerWidth } from './useContainerWidth';\n\n/**\n * Resolve the *container's* current breakpoint (not the viewport's) — the correctness\n * fix for a surface inside a PCF, where width comes from `context.allocatedWidth`.\n * Returns `[ref, breakpoint, width]`.\n */\nexport function useContainerBreakpoint<T extends HTMLElement = HTMLDivElement>(): [React.RefObject<T>, Breakpoint, number] {\n const [ref, width] = useContainerWidth<T>();\n return [ref, resolveBreakpoint(width), width];\n}\n","import type * as React from 'react';\nimport { resolveResponsiveValue, type ResponsiveValue } from '../responsive/breakpoints';\nimport { useContainerBreakpoint } from './useContainerBreakpoint';\n\n/**\n * Resolve a responsive value against the *container's* current breakpoint.\n * `const [ref, cols] = useResponsiveValue({ xs: 1, md: 2, lg: 3 });`\n */\nexport function useResponsiveValue<T, E extends HTMLElement = HTMLDivElement>(\n value: ResponsiveValue<T>,\n): [React.RefObject<E>, T | undefined] {\n const [ref, breakpoint] = useContainerBreakpoint<E>();\n return [ref, resolveResponsiveValue(value, breakpoint)];\n}\n","import { useState, useEffect } from 'react';\n\n/** Viewport media-query match — the SSR-safe / no-ResizeObserver fallback to the container hooks. */\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState<boolean>(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;\n const mql = window.matchMedia(query);\n const onChange = () => setMatches(mql.matches);\n onChange();\n mql.addEventListener('change', onChange);\n return () => mql.removeEventListener('change', onChange);\n }, [query]);\n\n return matches;\n}\n","import { createContext, useContext } from 'react';\nimport type { Density } from '../tokens/density';\n\n/**\n * Form-level spacing density. `FormSurface` provides it; `Section` (and any future\n * container) reads it via `useDensity()`, so a single `density` switch on the form\n * cascades to every section instead of being set per-section. Defaults to\n * `'comfortable'` (the Dynamics default) — `'compact'` scales spacing by 0.75.\n */\nexport const DensityContext = createContext<Density>('comfortable');\n\n/** Read the ambient spacing density (defaults to `'comfortable'` outside a provider). */\nexport const useDensity = (): Density => useContext(DensityContext);\n","import { createContext, useContext } from 'react';\nimport type { SurfaceLook } from '../core/ceLayout';\n\n/**\n * Form-level appearance: `'default'` (the kit's existing look) or `'ce'` (the measured Dynamics CE\n * model-driven form). `FormSurface` provides it and layouts read it, the same way `DensityContext`\n * cascades density, so a single `look` on the form reaches every row and column.\n */\nexport const LookContext = createContext<SurfaceLook>('default');\n\n/** Read the ambient surface look (defaults to `'default'` outside a provider). */\nexport const useLook = (): SurfaceLook => useContext(LookContext);\n","// The Dynamics CE Fluent v9 theme now lives in ONE place: @dataverse-kit/fluent-theme.\n//\n// ★ This file used to DECLARE the ramp and the three builders. So did grid-kit's copy\n// (or surface-kit's — whichever you are not reading), byte-identical across all sixteen\n// slots, each with a docstring claiming to be canonical. That is verification-lessons.md\n// §4 exactly: \"a fix applied to one of N copies leaves the other N-1 actively defended by\n// their own docstrings.\" Both are now re-exports of the single declaration.\n//\n// ★ Kept as a module rather than deleted so the ten internal `./theme` / `../theme` import\n// sites (stories, tests, the v9 barrel) and this package's public API are unchanged.\nexport {\n dynamicsBrandRamp,\n createDynamicsV9Theme,\n createDynamicsV9DarkTheme,\n dynamicsV9Theme,\n dynamicsV9DarkTheme,\n createDynamicsCeTheme,\n dynamicsCeTheme,\n} from '@dataverse-kit/fluent-theme';\n","import React from 'react';\nimport { makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport type { FormSurfaceProps } from '../types';\nimport { scaleSpacing } from '../../tokens/density';\nimport { BREAKPOINTS, type Breakpoint } from '../../responsive/breakpoints';\nimport { DensityContext } from '../../hooks/useDensity';\nimport { LookContext } from '../../hooks/useLook';\n\n// The Fluent v9 counterpart of the v8 FormSurface: the N-column form canvas that Sections\n// sit on. Same logic — stacks children to full width below `collapseBelow`, driven by the\n// *container* width when `containerWidth` is supplied (PCF allocatedWidth), else by the\n// viewport via @media — re-skinned with griffel (makeStyles) + v9 theme tokens. The\n// density/breakpoint math is the SHARED framework-agnostic layer (scaleSpacing, BREAKPOINTS).\n\nconst useStyles = makeStyles({\n root: {\n display: 'grid',\n alignItems: 'start',\n backgroundColor: tokens.colorNeutralBackground2,\n },\n // Container forced a single column: reset every child's span the same way the @media\n // fallback does, so a Section with `columnStart` doesn't escape the stack.\n forceStackChildren: {\n '& > *': { gridColumn: '1 / -1' },\n },\n // Viewport fallbacks (used only when containerWidth is unset) — one static slot per\n // breakpoint so griffel gets literal media strings. The px come from the shared BREAKPOINTS.\n stackSm: { [`@media (max-width: ${BREAKPOINTS.sm}px)`]: { '& > *': { gridColumn: '1 / -1' } } },\n stackMd: { [`@media (max-width: ${BREAKPOINTS.md}px)`]: { '& > *': { gridColumn: '1 / -1' } } },\n stackLg: { [`@media (max-width: ${BREAKPOINTS.lg}px)`]: { '& > *': { gridColumn: '1 / -1' } } },\n stackXl: { [`@media (max-width: ${BREAKPOINTS.xl}px)`]: { '& > *': { gridColumn: '1 / -1' } } },\n});\n\nconst VIEWPORT_STACK: Record<Breakpoint, keyof ReturnType<typeof useStyles> | null> = {\n xs: null, // xs = 0px, never stacks\n sm: 'stackSm',\n md: 'stackMd',\n lg: 'stackLg',\n xl: 'stackXl',\n};\n\n/** The N-column form canvas that hosts Sections (Fluent UI v9). */\nexport const FormSurface: React.FC<FormSurfaceProps> = ({\n columns = 12,\n gap = 20,\n padding,\n density = 'comfortable',\n background,\n containerWidth,\n look = 'default',\n collapseBelow = 'sm',\n maxWidth,\n className,\n style,\n children,\n}) => {\n const styles = useStyles();\n if (look === 'ce') {\n // A plain block (see FormSurfaceProps.look): the CE page is chrome stacked top to bottom and\n // its columns are TabColumns'. As a grid it put CommandSurface/TabColumns into ONE of 12\n // tracks, and `1fr` tracks (min-width: auto) let no-wrap header content widen the page.\n return (\n <DensityContext.Provider value={density}>\n <LookContext.Provider value={look}>\n <div\n className={className}\n data-surface-part=\"form-surface\"\n data-look=\"ce\"\n style={{\n display: 'flow-root',\n minWidth: 0,\n padding: padding ?? 0,\n ...(background != null ? { background } : {}),\n ...(maxWidth != null ? { maxWidth, marginLeft: 'auto', marginRight: 'auto' } : {}),\n ...style,\n }}\n >\n {children}\n </div>\n </LookContext.Provider>\n </DensityContext.Provider>\n );\n }\n const collapsePx = BREAKPOINTS[collapseBelow];\n const forceStack = containerWidth != null && containerWidth <= collapsePx;\n // Density scales the canvas gap + padding; cascades to child Sections via context.\n const scaledGap = scaleSpacing(gap, density);\n const scaledPadding = scaleSpacing(padding ?? 20, density);\n\n const viewportStackSlot = containerWidth == null ? VIEWPORT_STACK[collapseBelow] : null;\n\n const cls = mergeClasses(\n styles.root,\n forceStack && styles.forceStackChildren,\n viewportStackSlot ? styles[viewportStackSlot] : undefined,\n className,\n );\n\n const inlineStyle: React.CSSProperties = {\n gridTemplateColumns: forceStack ? '1fr' : `repeat(${columns}, 1fr)`,\n gap: scaledGap,\n padding: scaledPadding,\n ...(background != null ? { background } : {}),\n ...(maxWidth != null ? { maxWidth, marginLeft: 'auto', marginRight: 'auto' } : {}),\n ...style,\n };\n\n return (\n <DensityContext.Provider value={density}>\n <LookContext.Provider value={look}>\n <div className={cls} style={inlineStyle}>\n {children}\n </div>\n </LookContext.Provider>\n </DensityContext.Provider>\n );\n};\n\nexport default FormSurface;\n","import React from 'react';\nimport type { PageSurfaceProps } from '../types';\nimport { FormSurface } from './FormSurface';\n\n/** A full-page FormSurface (Fluent v9) — optionally centered with a comfortable max width. */\nexport const PageSurface: React.FC<PageSurfaceProps> = ({ centered, maxWidth, ...rest }) => (\n <FormSurface maxWidth={maxWidth ?? (centered ? 1200 : undefined)} {...rest} />\n);\n\nexport default PageSurface;\n","import React, { useState } from 'react';\nimport { makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport type { SectionProps } from '../types';\nimport { scaleSpacing } from '../../tokens/density';\nimport { BREAKPOINTS } from '../../responsive/breakpoints';\nimport { useDensity } from '../../hooks/useDensity';\nimport { useLook } from '../../hooks/useLook';\nimport { ceForm } from '../../tokens';\nimport { ceFieldRowFirstOffset } from '../layouts/FieldRow';\nimport { SectionHeader } from './SectionHeader';\n\n// ★ look=\"ce\" is the MEASURED Dynamics section (dynamics-ui-kit apps/ce-parity/reference):\n// shadow4 card, 8px radius, padding 4/16/16/16, the title as given, and a gap-free body that\n// pulls rows up by ceFieldRowFirstOffset so the first FieldRow sits at Dynamics' 8px. A\n// multi-column CE section takes ONE CHILD PER COLUMN (section → columns → rows, as in formxml):\n// equal columns, no gap, 21px right gutter on every column but the last (captured on a\n// formxml columns=\"11\" section). Density is ignored under ce: its spacing is measured.\n\nconst px = (v: readonly number[]) => v.map((n) => `${n}px`).join(' ');\n\n/** Flatten children positionally (arrays expanded, empty slots dropped), like TabColumns. */\nfunction columnsOf(children: React.ReactNode): React.ReactNode[] {\n const out: React.ReactNode[] = [];\n const walk = (n: React.ReactNode) => {\n if (Array.isArray(n)) n.forEach(walk);\n else if (!(n === null || n === undefined || typeof n === 'boolean' || n === '')) out.push(n);\n };\n walk(children);\n return out;\n}\n\n// The Fluent v9 counterpart of the v8 Section: a grid-positioned card with a header and an\n// internal N-column field grid + the three `variant`s (card/flat/placeholder), `collapsible`,\n// and phone-stacking of the body. Chrome is inline (v9 theme `tokens` are CSS-var strings, so\n// they stay theme-reactive); only the @media child-stacking uses griffel. Density math is the\n// shared framework-agnostic layer (scaleSpacing).\n\nconst useStyles = makeStyles({\n // Phone-stack the internal field grid below `sm` (griffel — inline can't do @media).\n bodyStack: {\n [`@media (max-width: ${BREAKPOINTS.sm}px)`]: { '& > *': { gridColumn: '1 / -1' } },\n },\n});\n\n/** A Dynamics-CE form section (Fluent v9): positioned card with a header and an internal field grid. */\nexport const Section: React.FC<SectionProps> = ({\n title,\n columnSpan = 12,\n columnStart,\n rowPosition,\n internalColumns: internalColumnsProp,\n showCommandBar,\n commandItems,\n statusText,\n notification,\n collapsible,\n defaultCollapsed = false,\n collapsed: controlledCollapsed,\n onCollapsedChange,\n variant = 'card',\n minHeight = 80,\n density: densityProp,\n look: lookProp,\n className,\n style,\n children,\n}) => {\n const styles = useStyles();\n // Default look: 12. (The ce default, 1, is resolved in the ce branch below.)\n const internalColumns = internalColumnsProp ?? 12;\n const ambientLook = useLook();\n const ce = (lookProp ?? ambientLook) === 'ce' && variant === 'card';\n const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed);\n const collapsed = controlledCollapsed ?? internalCollapsed;\n const toggle = () => {\n const next = !collapsed;\n if (controlledCollapsed == null) setInternalCollapsed(next);\n onCollapsedChange?.(next);\n };\n\n // Density: an explicit prop wins, else inherit the ambient FormSurface density.\n const ctxDensity = useDensity();\n const density = densityProp ?? ctxDensity;\n const cardPad = `${scaleSpacing(3, density)}px ${scaleSpacing(20, density)}px ${scaleSpacing(20, density)}px ${scaleSpacing(20, density)}px`;\n const bodyGap = scaleSpacing(7, density);\n\n const gridColumn = columnStart ? `${columnStart} / span ${columnSpan}` : `span ${columnSpan}`;\n const rootStyle: React.CSSProperties = {\n gridColumn,\n ...(rowPosition ? { gridRowStart: rowPosition } : {}),\n ...style,\n };\n\n if (variant === 'placeholder') {\n const placeholderStyle: React.CSSProperties = {\n ...rootStyle,\n border: `1px dashed ${tokens.colorNeutralStroke2}`,\n borderRadius: tokens.borderRadiusMedium,\n minHeight,\n width: '100%',\n background: 'transparent',\n };\n return <div className={className} style={placeholderStyle} />;\n }\n\n const chrome: React.CSSProperties =\n variant === 'flat'\n ? {\n backgroundColor: tokens.colorNeutralBackground1,\n borderRadius: tokens.borderRadiusMedium,\n padding: cardPad,\n minWidth: 300,\n width: '100%',\n overflow: 'hidden',\n }\n : {\n backgroundColor: tokens.colorNeutralBackground1,\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n borderRadius: tokens.borderRadiusMedium,\n boxShadow: tokens.shadow4,\n padding: cardPad,\n minWidth: 300,\n width: '100%',\n overflow: 'hidden',\n };\n\n const showHeader = Boolean(title) || showCommandBar || collapsible;\n\n if (ce) {\n // A Dynamics section is one column unless its formxml declares more.\n const n = Math.max(1, Math.round(internalColumnsProp ?? 1));\n const ceChrome: React.CSSProperties = {\n backgroundColor: tokens.colorNeutralBackground1,\n border: '1px solid transparent',\n borderRadius: tokens.borderRadiusXLarge,\n boxShadow: tokens.shadow4,\n padding: px(ceForm.section.padding),\n width: '100%',\n boxSizing: 'border-box',\n };\n const cols = n > 1 ? columnsOf(children) : null;\n // ★ Multi-column ce sections take ONE CHILD PER COLUMN. FieldRows passed straight in would each\n // become a \"column\" (every row pulled up 4px, laid out across instead of down) with no error,\n // and it is the natural thing to write when migrating from the default look's 12-column grid.\n if (cols && cols.length !== n && typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(\n `[surface-kit] Section look=\"ce\" with internalColumns={${n}} got ${cols.length} children. ` +\n 'A multi-column CE section takes ONE CHILD PER COLUMN (wrap each column\\'s FieldRows in an element).',\n );\n }\n return (\n <section className={className} style={{ ...ceChrome, ...rootStyle }} data-surface-part=\"section\" data-look=\"ce\">\n {notification && <div>{notification}</div>}\n {showHeader && (\n <SectionHeader\n look=\"ce\"\n title={title}\n statusText={statusText}\n showCommandBar={showCommandBar}\n commandItems={commandItems}\n collapsible={collapsible}\n collapsed={collapsed}\n onToggle={toggle}\n />\n )}\n {!collapsed &&\n (cols ? (\n // PROVISIONAL: below the phone breakpoint the columns stack (the default look's rule);\n // Dynamics' multi-column reflow is unmeasured.\n <div\n className={styles.bodyStack}\n style={{ display: 'grid', gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))`, alignItems: 'start' }}\n data-surface-part=\"section-body\"\n >\n {cols.map((col, i) => (\n <div\n key={React.isValidElement(col) && col.key != null ? col.key : `col-${i}`}\n style={{\n // Keyed to the COLUMN (i % n), not the list position: every column but the\n // last carries the gutter, and only the first grid row is pulled up.\n marginTop: i < n ? -ceFieldRowFirstOffset : 0,\n paddingRight: i % n < n - 1 ? ceForm.section.columnGutter : 0,\n minWidth: 0,\n }}\n data-surface-part=\"section-column\"\n >\n {col}\n </div>\n ))}\n </div>\n ) : (\n <div style={{ marginTop: -ceFieldRowFirstOffset }} data-surface-part=\"section-body\">\n {children}\n </div>\n ))}\n </section>\n );\n }\n\n const bodyStyle: React.CSSProperties = {\n display: 'grid',\n gridTemplateColumns: `repeat(${internalColumns}, 1fr)`,\n gap: bodyGap,\n alignItems: 'start',\n };\n\n return (\n <div className={className} style={{ ...chrome, ...rootStyle }}>\n {notification && <div style={{ marginBottom: scaleSpacing(8, density) }}>{notification}</div>}\n {showHeader && (\n <SectionHeader\n title={title}\n statusText={statusText}\n showCommandBar={showCommandBar}\n commandItems={commandItems}\n collapsible={collapsible}\n collapsed={collapsed}\n onToggle={toggle}\n />\n )}\n {!collapsed && (\n <div className={mergeClasses(styles.bodyStack)} style={bodyStyle}>\n {children}\n </div>\n )}\n </div>\n );\n};\n\nexport default Section;\n","import React from 'react';\nimport { makeStyles, mergeClasses, tokens } from '@fluentui/react-components';\nimport type { FieldRowProps } from '../types';\nimport { ceForm, colors } from '../../tokens';\nimport { BREAKPOINTS } from '../../responsive/breakpoints';\nimport { CE_LABEL_ABOVE_BELOW_ROW_WIDTH } from '../../core/ceLayout';\nimport { useLook } from '../../hooks/useLook';\n\n// A \"Label : control\" row (Fluent v9). Two looks:\n//\n// - `default`: the v8 FieldRow's geometry and marker (130px label column, 12px semibold label,\n// semibold `*` 2px after the text, phone-stack at 480px), so a v9 form matches the kit's v8 forms.\n// - `ce`: the MEASURED Dynamics CE row (@dataverse-kit/design-tokens `ceForm.field`; evidence in\n// dynamics-ui-kit apps/ce-parity/reference/captures). Beside: a 184px label column whose text is\n// 176px wide, the label box 4px down and 30px tall, the control 2px down and 2px short of the\n// right edge. Above: label 2px down and 20px tall, a 4px gap, then the control.\n//\n// ★ Every row pads 12px on top. Dynamics' first row in a section pads 8, so the SECTION BODY\n// pulls its content up by the difference (`ceFieldRowFirstOffset`), rather than this row keying\n// off `:first-child`, which any wrapper, hidden input or heading in the body would silently break.\n// ★ Rows span every column of a grid parent (the v9 Section body is a 12-column grid).\n// ★ `labelPosition: 'auto'` flips beside → above with a container query on the row itself, so it\n// follows the SECTION's width (what Dynamics follows), not the viewport. Only 'auto' rows become\n// containers: `container-type: inline-size` zeroes a row's intrinsic width, which would collapse\n// it inside any shrink-to-fit parent. An 'auto' row therefore needs a parent of definite width.\n\nconst F = ceForm.field;\n// Geometry measured for this component (label rect y+12/h30 and input rect y+10 in a row with 8px\n// top padding; 176px label text in a 184px column; input box 2px short of the row's right edge).\n// Not tokens: nothing else uses them.\nconst CE_LABEL_BOX = 30;\nconst CE_LABEL_OFFSET = 4;\nconst CE_CONTROL_OFFSET = 2;\nconst CE_CONTROL_INSET_RIGHT = 2;\nconst CE_LABEL_TEXT_WIDTH = 176;\nconst CE_MARKER_GAP = 4;\n\n/**\n * How far a section body must pull its rows up so the first `FieldRow` pads 8px, as Dynamics'\n * first row does, while every row itself pads 12px. `Section look=\"ce\"` applies it; a hand-built\n * body applies `marginTop: -ceFieldRowFirstOffset`.\n */\nexport const ceFieldRowFirstOffset = F.rowPaddingTop - F.rowPaddingTopFirst;\n\n// Range syntax is exact (\"narrower than 340px\"); max-width with an epsilon is off by up to a\n// LayoutUnit. Griffel passes the string through.\nconst NARROW = `@container (width < ${CE_LABEL_ABOVE_BELOW_ROW_WIDTH}px)`;\n\nconst useStyles = makeStyles({\n // ── shared ──────────────────────────────────────────────────────────────\n // Span every column when placed in a grid (v9 Section's body is repeat(12, 1fr)).\n spanAll: { gridColumn: '1 / -1' },\n // ── ce ──────────────────────────────────────────────────────────────────\n ceRow: {\n paddingTop: `${F.rowPaddingTop}px`,\n minWidth: 0,\n },\n ceContainer: { containerType: 'inline-size' },\n ceGrid: {\n display: 'grid',\n alignItems: 'start',\n },\n // ★ The column template lives in CLASSES, never in an inline style: an inline\n // grid-template-columns beats the @container rule, so 'auto' never flipped to 'above'\n // (caught measuring a 306px row in a real browser; jsdom cannot see it). A custom labelWidth\n // reaches the class through the --sk-label-col custom property.\n ceGridBeside: { gridTemplateColumns: 'var(--sk-label-col) minmax(0, 1fr)' },\n ceGridSingle: { gridTemplateColumns: 'minmax(0, 1fr)' },\n ceLabelBeside: {\n display: 'flex',\n alignItems: 'center',\n minHeight: `${CE_LABEL_BOX}px`,\n marginTop: `${CE_LABEL_OFFSET}px`,\n // 184 − 176: the measured text width. A required marker is allowed into half of it (below).\n paddingRight: `${F.labelColumnWidth - CE_LABEL_TEXT_WIDTH}px`,\n },\n ceLabelAbove: {\n display: 'flex',\n alignItems: 'center',\n marginTop: `${CE_CONTROL_OFFSET}px`,\n minHeight: `${F.labelLineHeight}px`,\n },\n ceControlBeside: {\n marginTop: `${CE_CONTROL_OFFSET}px`,\n marginBottom: `${CE_CONTROL_OFFSET}px`,\n marginRight: `${CE_CONTROL_INSET_RIGHT}px`,\n minWidth: 0,\n },\n ceControlAbove: {\n marginTop: `${F.labelAboveGap}px`,\n marginBottom: `${CE_CONTROL_OFFSET}px`,\n marginRight: `${CE_CONTROL_INSET_RIGHT}px`,\n minWidth: 0,\n },\n // 'auto': beside by default, above when the ROW is narrower than the (provisional) switch point.\n ceAutoGrid: { [NARROW]: { gridTemplateColumns: 'minmax(0, 1fr)' } },\n ceAutoLabel: {\n [NARROW]: {\n marginTop: `${CE_CONTROL_OFFSET}px`,\n minHeight: `${F.labelLineHeight}px`,\n paddingRight: 0,\n },\n },\n ceAutoControl: { [NARROW]: { marginTop: `${F.labelAboveGap}px` } },\n ceLabelText: {\n minWidth: 0,\n fontSize: tokens.fontSizeBase300,\n lineHeight: `${F.labelLineHeight}px`,\n fontWeight: tokens.fontWeightRegular,\n color: tokens.colorNeutralForeground1,\n overflowWrap: 'anywhere',\n },\n // Beside, the text fills the column so the marker sits at the column's end (measured: marker's\n // right edge 180px from the row). Above, the marker follows the text (position unmeasured).\n ceLabelTextFill: { flexGrow: 1 },\n ceAutoLabelText: { [NARROW]: { flexGrow: 0 } },\n ceRequired: {\n flexShrink: 0,\n color: tokens.colorPaletteRedForeground1,\n paddingLeft: `${CE_MARKER_GAP}px`,\n },\n // Beside: the marker takes half the column's 8px padding → text 168.5 + 4 + 7.5 = 176 + 4.\n ceRequiredBeside: { marginRight: `-${CE_MARKER_GAP}px` },\n ceAutoRequired: { [NARROW]: { marginRight: 0 } },\n // ── default ─────────────────────────────────────────────────────────────\n defaultBeside: {\n display: 'grid',\n alignItems: 'center',\n columnGap: '8px',\n minHeight: '38px',\n [`@media (max-width: ${BREAKPOINTS.sm}px)`]: {\n gridTemplateColumns: '1fr !important',\n alignItems: 'flex-start',\n minHeight: 0,\n rowGap: '4px',\n },\n },\n defaultAbove: {\n display: 'grid',\n gridTemplateColumns: '1fr',\n rowGap: '2px',\n minHeight: '38px',\n },\n defaultLabel: {\n fontSize: tokens.fontSizeBase200,\n fontWeight: tokens.fontWeightSemibold,\n color: tokens.colorNeutralForeground1,\n lineHeight: '1.3',\n overflowWrap: 'anywhere',\n },\n // v8 FieldRow's marker: colors.danger, semibold, 2px after the text.\n defaultRequired: {\n color: colors.danger,\n marginLeft: '2px',\n fontWeight: tokens.fontWeightSemibold,\n },\n});\n\nconst toCssLength = (v: number | string) => (typeof v === 'number' ? `${v}px` : v);\n\n/** A \"Label : control\" field row (Fluent UI v9). The control goes in `children`. */\nexport const FieldRow: React.FC<FieldRowProps> = ({\n label,\n required,\n htmlFor,\n labelPosition,\n labelWidth,\n look: lookProp,\n className,\n style,\n children,\n}) => {\n const styles = useStyles();\n const ambientLook = useLook();\n const look = lookProp ?? ambientLook;\n const ce = look === 'ce';\n const position = labelPosition ?? (ce ? 'auto' : 'beside');\n const hasLabel = label != null;\n const column = toCssLength(labelWidth ?? (ce ? F.labelColumnWidth : 130));\n const LabelTag = htmlFor ? 'label' : 'span';\n\n if (!ce) {\n // Under the default look 'auto' behaves as 'beside' (with the v8 phone stack at 480px).\n const beside = position !== 'above' && hasLabel;\n return (\n <div\n className={mergeClasses(styles.spanAll, beside ? styles.defaultBeside : styles.defaultAbove, className)}\n style={{ ...(beside ? { gridTemplateColumns: `${column} 1fr` } : {}), ...style }}\n data-surface-part=\"field-row\"\n data-look=\"default\"\n >\n {hasLabel && (\n <LabelTag htmlFor={htmlFor} className={styles.defaultLabel} data-surface-part=\"label\">\n {label}\n {required && (\n <span className={styles.defaultRequired} aria-hidden=\"true\" data-surface-part=\"required\">\n *\n </span>\n )}\n </LabelTag>\n )}\n {children}\n </div>\n );\n }\n\n const auto = position === 'auto' && hasLabel;\n const beside = position !== 'above' && hasLabel;\n return (\n <div\n className={mergeClasses(styles.spanAll, styles.ceRow, auto && styles.ceContainer, className)}\n style={style}\n data-surface-part=\"field-row\"\n data-look=\"ce\"\n data-label-position={position}\n data-container={auto ? 'inline-size' : undefined}\n >\n <div\n className={mergeClasses(styles.ceGrid, beside ? styles.ceGridBeside : styles.ceGridSingle, auto && styles.ceAutoGrid)}\n style={beside ? ({ '--sk-label-col': column } as React.CSSProperties) : undefined}\n data-surface-part=\"field-grid\"\n >\n {hasLabel && (\n <LabelTag\n htmlFor={htmlFor}\n className={mergeClasses(beside ? styles.ceLabelBeside : styles.ceLabelAbove, auto && styles.ceAutoLabel)}\n data-surface-part=\"label\"\n >\n <span\n className={mergeClasses(styles.ceLabelText, beside && styles.ceLabelTextFill, auto && styles.ceAutoLabelText)}\n data-surface-part=\"label-text\"\n >\n {label}\n </span>\n {required && (\n <span\n className={mergeClasses(styles.ceRequired, beside && styles.ceRequiredBeside, auto && styles.ceAutoRequired)}\n aria-hidden=\"true\"\n data-surface-part=\"required\"\n >\n *\n </span>\n )}\n </LabelTag>\n )}\n <div\n className={mergeClasses(\n // No label: the control sits where a beside control would (2px down), full width.\n !hasLabel || beside ? styles.ceControlBeside : styles.ceControlAbove,\n auto && styles.ceAutoControl,\n )}\n data-surface-part=\"control\"\n >\n {children}\n </div>\n </div>\n </div>\n );\n};\n\nexport default FieldRow;\n","import React from 'react';\nimport {\n Button,\n Text,\n Toolbar,\n ToolbarButton,\n tokens,\n} from '@fluentui/react-components';\nimport { ChevronDown20Regular, ChevronRight20Regular } from '@fluentui/react-icons';\nimport type { SectionHeaderProps } from '../types';\nimport { ceForm } from '../../tokens';\nimport { useLook } from '../../hooks/useLook';\n\n// v9 section header: flex title + status on the left, a v9 <Toolbar> of commandItems on the\n// right (replacing the v8 CommandBar), Dynamics neutral underline, optional collapse chevron.\n\n/** Section header bar (Fluent v9): title + status (left), toolbar / actions (right), optional collapse toggle. */\nexport const SectionHeader: React.FC<SectionHeaderProps> = ({\n title,\n statusText,\n showCommandBar,\n commandItems = [],\n actions,\n collapsible,\n collapsed,\n onToggle,\n look: lookProp,\n}) => {\n // Follows the ambient FormSurface look, like Section, unless given explicitly.\n const ambientLook = useLook();\n const ce = (lookProp ?? ambientLook) === 'ce';\n // CE: the measured section title is 24px tall (4px top pad + 20px line), with no rule and no\n // gap below it; the first field row follows immediately (rows own their top padding).\n const ceRootStyle: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexWrap: 'nowrap',\n paddingTop: ceForm.section.titlePaddingTop,\n minHeight: ceForm.section.titleHeight - ceForm.section.titlePaddingTop,\n width: '100%',\n };\n const rootStyle: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexWrap: 'nowrap',\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n marginBottom: 16,\n minHeight: 48,\n width: '100%',\n };\n const leftStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 };\n const statusStyle: React.CSSProperties = {\n marginLeft: 8,\n fontSize: tokens.fontSizeBase200,\n color: tokens.colorNeutralForeground3,\n };\n\n return (\n <div style={ce ? ceRootStyle : rootStyle} data-surface-part=\"section-header\">\n <div style={leftStyle}>\n {collapsible && (\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={collapsed ? <ChevronRight20Regular /> : <ChevronDown20Regular />}\n onClick={onToggle}\n aria-label={collapsed ? 'Expand section' : 'Collapse section'}\n aria-expanded={!collapsed}\n />\n )}\n {title &&\n (ce ? (\n // Rendered exactly as given: Dynamics does not uppercase section titles (the stock\n // Account labels are typed uppercase; \"Description\" renders mixed-case).\n <Text\n as=\"h2\"\n weight=\"semibold\"\n size={300}\n style={{ margin: 0, lineHeight: `${ceForm.section.titleLineHeight}px`, color: tokens.colorNeutralForeground1 }}\n data-surface-part=\"section-title\"\n >\n {title}\n </Text>\n ) : (\n <Text weight=\"semibold\" size={300}>\n {title}\n </Text>\n ))}\n {statusText && <span style={statusStyle}>{statusText}</span>}\n </div>\n {actions ? (\n <div>{actions}</div>\n ) : showCommandBar && commandItems.length > 0 ? (\n <Toolbar aria-label=\"Section commands\" size=\"small\">\n {commandItems.map((item) => (\n <ToolbarButton\n key={item.id}\n icon={item.icon}\n appearance={item.appearance === 'primary' ? 'primary' : 'subtle'}\n disabled={item.disabled}\n onClick={item.onClick}\n >\n {item.label}\n </ToolbarButton>\n ))}\n </Toolbar>\n ) : null}\n </div>\n );\n};\n\nexport default SectionHeader;\n","import React from 'react';\nimport { tokens } from '@fluentui/react-components';\nimport type { SectionCardProps } from '../types';\nimport { Section } from './Section';\n\n/**\n * A Section with the Dynamics blue accent top border (Fluent v9).\n * The accent is an inline `borderTop` so it wins over the card variant's inline `border`\n * (see Section: `style` is spread after the card chrome). Defaults to the v9 brand stroke.\n */\nexport const SectionCard: React.FC<SectionCardProps> = ({\n accentColor = tokens.colorBrandStroke1,\n accentWidth = 3,\n variant = 'card',\n style,\n ...rest\n}) => (\n <Section\n variant={variant}\n {...rest}\n style={{ borderTop: `${accentWidth}px solid ${accentColor}`, ...style }}\n />\n);\n\nexport default SectionCard;\n","import React from 'react';\nimport {\n Avatar,\n Button,\n Menu,\n MenuItemRadio,\n MenuList,\n MenuPopover,\n MenuTrigger,\n Text,\n createFocusOutlineStyle,\n makeStyles,\n tokens,\n} from '@fluentui/react-components';\nimport { ChevronDown12Regular, ChevronDown20Regular, ChevronUp20Regular } from '@fluentui/react-icons';\nimport type { FormHeaderProps, SurfaceHeaderField } from '../types';\nimport { ceForm } from '../../tokens';\nimport { useLook } from '../../hooks/useLook';\n\n// ★ look=\"ce\" is the MEASURED Dynamics record header region (dynamics-ui-kit\n// apps/ce-parity/reference/captures/account-main-summary-1710.txt, `header.*`). Everything in it\n// is a stock Fluent part laid out to the measured geometry:\n// - the record avatar is Fluent `Avatar color=\"colorful\"` hashed from the title — Fluent's hash\n// gives \"Adatum Division (Showcase)\" cranberry, exactly the measured #eeacb2 / #6e0811;\n// - the form switcher's menu is Fluent `MenuItemRadio` in a `MenuPopover` — the measured 4px\n// padding, shadow16, 32px items and 16px check slot are Fluent's own;\n// - the header-field values/labels are Fluent's 300 (14/20) and 200 (12/16) ramp steps.\n// Geometry below is measured, each constant commented with its capture.\n\nconst H = ceForm.header;\n// Header-field value top sits 4px below the region's content top (value y 137 vs 133).\nconst FIELD_TOP = 4;\n// The owner avatar sits 9px down (142 vs 133), 10px before the owner name (1440.1+32 → 1482.1).\nconst OWNER_AVATAR_TOP = 9;\nconst OWNER_NAME_GAP = 10;\n// The dot between entity name and switcher (entity ends 287+52.3=339.3, dot 347.3–350.3, switcher 358.4).\nconst SUBTITLE_DOT_SPACING = 8;\n// The switcher row sits directly under the title row (switcher top 163.5 = title-row bottom: the\n// row is 30.5 tall because the status baseline-aligns 2.5px below the title), so it has no margin.\n// The entity text then centres in the 22px row (text top 165.3 = title top + ceForm subtitleOffset).\nconst SUBTITLE_ROW_TOP = 0;\n// The expand chevron sits 18px after the owner name (1482.1+136.9=1619 → 1637).\nconst EXPAND_GAP = 18;\n// Dividers start 6px below the content top (divider y 139 vs 133).\nconst DIVIDER_TOP = 6;\n// The presence dot: an 8px dot in a 2px white ring (12 in all) hanging 2px outside the avatar's\n// bottom-right corner (dot box at +22,+22 of a 32px avatar).\nconst PRESENCE_RING = 2;\nconst PRESENCE_DOT = H.presenceSize - 2 * PRESENCE_RING;\nexport const cePresenceBadgeStyle: Readonly<React.CSSProperties> = Object.freeze({\n width: PRESENCE_DOT,\n height: PRESENCE_DOT,\n boxSizing: 'content-box',\n // Fluent's badge carries 1px padding and a 10px icon; zero the padding and clip the icon to the dot.\n padding: 0,\n overflow: 'hidden',\n border: `${PRESENCE_RING}px solid ${tokens.colorNeutralBackground1}`,\n right: -PRESENCE_RING,\n bottom: -PRESENCE_RING,\n});\n// UNMEASURED: the minimum space between the title block and the header fields (the fields are\n// right-aligned; in the capture the space was ~580px). Only matters when the header is crowded.\nconst FIELDS_MIN_GAP = 16;\n// UNMEASURED: the narrowest the title block may get before the fields yield (narrow headers only).\nconst CE_TITLE_MIN_WIDTH = 120;\n\nconst useStyles = makeStyles({\n // The owner name as a link-button: no chrome, but a VISIBLE keyboard focus ring (Fluent's).\n ownerLink: {\n background: 'none',\n border: 'none',\n padding: 0,\n margin: 0,\n font: 'inherit',\n color: tokens.colorBrandForegroundLink,\n cursor: 'pointer',\n ':hover': { color: tokens.colorBrandForegroundLinkHover, textDecorationLine: 'underline' },\n ...createFocusOutlineStyle(),\n },\n // Narrow headers: the title keeps a minimum width (it truncates with an ellipsis) and the fields\n // block shrinks and clips rather than pushing past the card. Dynamics moves the fields into the\n // header flyout at narrow widths (unmeasured, not modelled).\n fields: {\n display: 'flex',\n alignItems: 'flex-start',\n flexShrink: 1,\n minWidth: 0,\n overflow: 'hidden',\n },\n switcher: {\n display: 'inline-flex',\n alignItems: 'center',\n // Measured switcher 74.3 wide for \"Account\" (52.3): 2×2 padding + 2×1 border + 4 gap + 12 icon.\n gap: '4px',\n height: `${H.switcherHeight}px`,\n padding: `0 ${H.switcherPaddingX}px`,\n border: '1px solid transparent',\n borderRadius: tokens.borderRadiusMedium,\n background: 'transparent',\n color: tokens.colorNeutralForeground2,\n fontFamily: 'inherit',\n fontSize: tokens.fontSizeBase300,\n fontWeight: tokens.fontWeightSemibold,\n lineHeight: tokens.lineHeightBase300,\n cursor: 'pointer',\n ':hover': { backgroundColor: tokens.colorSubtleBackgroundHover },\n ...createFocusOutlineStyle(),\n // Measured OPEN: fill #e0e0e0 = colorSubtleBackgroundPressed (Fluent's MenuButton would use\n // Selected, #ebebeb — so this is set explicitly) and text #242424 = colorNeutralForeground1\n // (idle is #424242). ★ The open state must also win over :hover — the pointer is still on the\n // trigger after the click that opened it, and hover's #f5f5f5 was what showed. The ce-parity\n // gate checks the open trigger with the pointer on it AND away from it.\n '&[aria-expanded=\"true\"], &[aria-expanded=\"true\"]:hover': {\n backgroundColor: tokens.colorSubtleBackgroundPressed,\n color: tokens.colorNeutralForeground1,\n },\n },\n});\n\nconst isEmpty = (v: unknown) => v === null || v === undefined || v === '';\n\nfunction FieldTile({ field }: { field: SurfaceHeaderField }) {\n return (\n <div style={{ display: 'flex', flexDirection: 'column', paddingTop: FIELD_TOP, minWidth: 0 }} data-surface-part=\"header-field\">\n <Text weight=\"semibold\" size={300} wrap={false} style={{ color: tokens.colorNeutralForeground1 }} data-surface-part=\"header-field-value\">\n {isEmpty(field.value) ? '---' : field.value}\n </Text>\n <Text size={200} wrap={false} style={{ color: tokens.colorNeutralForeground1 }} data-surface-part=\"header-field-label\">\n {field.label}\n </Text>\n </div>\n );\n}\n\nfunction Divider() {\n return (\n <div\n aria-hidden=\"true\"\n style={{\n width: H.dividerWidth,\n height: H.dividerHeight,\n margin: `${DIVIDER_TOP}px ${H.dividerSpacing}px 0`,\n backgroundColor: tokens.colorNeutralStroke2,\n flexShrink: 0,\n }}\n data-surface-part=\"header-divider\"\n />\n );\n}\n\nfunction CeFormHeader(props: FormHeaderProps) {\n const {\n title,\n subtitle,\n status,\n titleColor,\n persona,\n actions,\n className,\n entityName,\n forms,\n activeFormId,\n onFormChange,\n headerFields,\n owner,\n onExpand,\n expanded,\n titleAs,\n } = props;\n const styles = useStyles();\n const activeForm = forms?.find((f) => f.id === activeFormId) ?? forms?.[0];\n const entity = entityName ?? subtitle;\n // Decorative: the title is announced by the heading right after it.\n const avatar =\n persona ?? (typeof title === 'string' ? <Avatar name={title} color=\"colorful\" size={H.avatarSize} aria-hidden /> : null);\n const TitleTag = titleAs ?? 'h1';\n\n return (\n <div\n className={className}\n style={{ display: 'flex', alignItems: 'flex-start', padding: H.padding.map((v) => `${v}px`).join(' '), minWidth: 0 }}\n data-surface-part=\"form-header\"\n data-look=\"ce\"\n >\n {avatar && (\n // The avatar sits in a 2px transparent ring (tile 44 = 40 + 2 × 2), 14px before the title.\n <div style={{ padding: H.avatarRing, marginRight: H.avatarToTitleGap, flexShrink: 0 }} data-surface-part=\"header-avatar\">\n {avatar}\n </div>\n )}\n <div style={{ minWidth: CE_TITLE_MIN_WIDTH, flex: '1 1 auto' }}>\n <div style={{ display: 'flex', alignItems: 'baseline', minWidth: 0 }}>\n {title != null && (\n <Text\n as={TitleTag}\n weight=\"semibold\"\n size={500}\n truncate\n wrap={false}\n style={{ margin: 0, lineHeight: `${H.titleLineHeight}px`, color: titleColor ?? tokens.colorNeutralForeground1 }}\n data-surface-part=\"header-title\"\n >\n {title}\n </Text>\n )}\n {status != null && (\n <span\n style={{\n paddingLeft: H.statusPaddingLeft,\n fontSize: tokens.fontSizeBase300,\n lineHeight: `${H.titleLineHeight}px`,\n color: tokens.colorNeutralForeground3,\n whiteSpace: 'nowrap',\n }}\n data-surface-part=\"header-status\"\n >\n - {status}\n </span>\n )}\n </div>\n {(entity != null || activeForm) && (\n <div style={{ display: 'flex', alignItems: 'center', height: H.switcherHeight, marginTop: SUBTITLE_ROW_TOP }} data-surface-part=\"header-subtitle\">\n {entity != null && (\n <span style={{ fontSize: tokens.fontSizeBase300, fontWeight: tokens.fontWeightSemibold, color: tokens.colorNeutralForeground2 }}>\n {entity}\n </span>\n )}\n {entity != null && activeForm && (\n <span aria-hidden=\"true\" style={{ margin: `0 ${SUBTITLE_DOT_SPACING}px`, color: tokens.colorNeutralForeground2, lineHeight: '20px' }}>\n ·\n </span>\n )}\n {activeForm &&\n (forms && forms.length > 1 ? (\n <Menu\n checkedValues={{ form: [activeForm.id] }}\n onCheckedValueChange={(_e, data) => {\n const id = data.checkedItems[0];\n if (id && id !== activeForm.id) onFormChange?.(id);\n }}\n >\n <MenuTrigger disableButtonEnhancement>\n <button type=\"button\" className={styles.switcher} aria-label={`Form: ${activeForm.label}`} data-surface-part=\"form-switcher\">\n {activeForm.label}\n <ChevronDown12Regular />\n </button>\n </MenuTrigger>\n <MenuPopover>\n <MenuList>\n {forms.map((f) => (\n <MenuItemRadio key={f.id} name=\"form\" value={f.id}>\n {f.label}\n </MenuItemRadio>\n ))}\n </MenuList>\n </MenuPopover>\n </Menu>\n ) : (\n <span style={{ fontSize: tokens.fontSizeBase300, fontWeight: tokens.fontWeightSemibold, color: tokens.colorNeutralForeground2 }}>\n {activeForm.label}\n </span>\n ))}\n </div>\n )}\n </div>\n {(headerFields?.length || owner || actions) && (\n <div className={styles.fields} style={{ marginLeft: FIELDS_MIN_GAP }} data-surface-part=\"header-fields\">\n {headerFields?.map((f, i) => (\n <React.Fragment key={f.id ?? `${f.label}-${i}`}>\n {i > 0 && <Divider />}\n <FieldTile field={f} />\n </React.Fragment>\n ))}\n {owner && (\n <>\n {headerFields?.length ? <Divider /> : null}\n <div style={{ display: 'flex', alignItems: 'flex-start' }} data-surface-part=\"header-owner\">\n <div style={{ paddingTop: OWNER_AVATAR_TOP, marginRight: OWNER_NAME_GAP }}>\n {owner.avatar ?? (\n <Avatar\n name={owner.name}\n color=\"colorful\"\n size={H.ownerAvatarSize}\n // Only when supplied: a badge is announced (\"… available\"), so never assume one.\n badge={owner.presence ? { status: owner.presence, size: 'extra-small', style: cePresenceBadgeStyle } : undefined}\n />\n )}\n </div>\n <FieldTile\n field={{\n label: owner.label ?? 'Owner',\n value: owner.onClick ? (\n <button type=\"button\" onClick={owner.onClick} className={styles.ownerLink} data-surface-part=\"header-owner-link\">\n {owner.name}\n </button>\n ) : (\n <span style={{ color: tokens.colorBrandForegroundLink }}>{owner.name}</span>\n ),\n }}\n />\n </div>\n </>\n )}\n {actions != null && <div>{actions}</div>}\n </div>\n )}\n {onExpand && (\n <Button\n appearance=\"subtle\"\n icon={expanded ? <ChevronUp20Regular /> : <ChevronDown20Regular />}\n aria-label={expanded ? 'Collapse header' : 'Expand header'}\n aria-expanded={!!expanded}\n onClick={onExpand}\n style={{ marginLeft: EXPAND_GAP, flexShrink: 0, minWidth: H.expandButtonSize, width: H.expandButtonSize, height: H.expandButtonSize }}\n data-surface-part=\"header-expand\"\n />\n )}\n </div>\n );\n}\n\n/** Dynamics form header (Fluent v9): persona + title/status (left), KPI/header fields (right). */\nexport const FormHeader: React.FC<FormHeaderProps> = (props) => {\n const ambientLook = useLook();\n if ((props.look ?? ambientLook) === 'ce') return <CeFormHeader {...props} />;\n\n const { title, subtitle, status, titleColor, subtitleColor, persona, actions, className } = props;\n const rootStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n padding: '12px 24px',\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n };\n const mainStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', gap: 12, minWidth: 0 };\n const titleRowStyle: React.CSSProperties = { display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' };\n const statusStyle: React.CSSProperties = { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 };\n const subtitleStyle: React.CSSProperties = {\n fontSize: tokens.fontSizeBase200,\n color: subtitleColor || tokens.colorNeutralForeground3,\n marginTop: 2,\n };\n\n return (\n <div className={className} style={rootStyle}>\n <div style={mainStyle}>\n {persona}\n <div>\n <div style={titleRowStyle}>\n {title != null && (\n <Text weight=\"semibold\" size={400} style={titleColor ? { color: titleColor } : undefined}>\n {title}\n </Text>\n )}\n {status != null && <span style={statusStyle}>{status}</span>}\n </div>\n {subtitle != null && <div style={subtitleStyle}>{subtitle}</div>}\n </div>\n </div>\n {actions != null && <div>{actions}</div>}\n </div>\n );\n};\n\nexport default FormHeader;\n","import React, { useId, useState } from 'react';\nimport {\n TabList,\n Tab,\n makeStyles,\n tabClassNames,\n tokens,\n type SelectTabData,\n type SelectTabEvent,\n} from '@fluentui/react-components';\nimport type { PivotSurfaceProps } from '../types';\nimport { ceForm } from '../../tokens';\n\n// ★ The ce look is OPT-IN here (`look=\"ce\"`), not inherited from FormSurface: it is page-level\n// chrome (a header card with page insets), so a pivot nested inside a ce Section must not become\n// a second header card. `appearance`/`size` are ignored under ce (transparent/large, measured).\n\n/** Fluent's private class for the hidden semibold copy that reserves a tab's width. It is NOT\n * exported by @fluentui/react-components; a test asserts it still exists after a Fluent bump. */\nexport const FLUENT_TAB_RESERVED_SPACE_CLASS = 'fui-Tab__content--reserved-space';\n\n// ★ look=\"ce\" is the MEASURED Dynamics header card + tab body (dynamics-ui-kit\n// apps/ce-parity/reference, `header.card`, `tabs.*`, `tabBody.*`): one card (shadow4, 8px\n// radius) holding the `header` region and the tab strip (padding 14/144/0/21, 45px tabs, 20px\n// apart, 16px text on a 28px line — NOT a Fluent ramp step — 600 when selected, a 3px brand\n// underline with 2px radius 5px above the tab's bottom edge). The selected tab's content renders\n// BELOW the card in the tab body (16px top, 21px bottom). The page insets (8px left, 20px right)\n// apply to card and body alike, as they do in Dynamics.\n\nconst T = ceForm.tabs;\n// The underline's bottom edge sits 5px above the tab box's bottom (underline 236.5–239.5 in a tab\n// box 199.5–244.5; the tab's measured padding-bottom is 5).\nconst UNDERLINE_BOTTOM = 5;\n\nconst useStyles = makeStyles({\n ceCard: {\n minWidth: 0,\n backgroundColor: tokens.colorNeutralBackground1,\n border: '1px solid transparent',\n borderRadius: tokens.borderRadiusXLarge,\n boxShadow: tokens.shadow4,\n },\n ceStrip: {\n padding: T.stripPadding.map((v) => `${v}px`).join(' '),\n columnGap: `${T.gap}px`,\n // PROVISIONAL: tabs that don't fit are clipped. Dynamics folds them into a \"Related ▾\" /\n // overflow menu, which is unmeasured and not modelled.\n overflow: 'hidden',\n },\n ceTab: {\n height: `${T.tabHeight}px`,\n padding: `0 0 ${UNDERLINE_BOTTOM}px`,\n alignItems: 'flex-end',\n fontSize: `${T.fontSize}px`,\n lineHeight: `${T.lineHeight}px`,\n color: tokens.colorNeutralForeground1,\n [`& .${tabClassNames.content}`]: {\n padding: 0,\n fontSize: `${T.fontSize}px`,\n lineHeight: `${T.lineHeight}px`,\n // Idle labels are the measured #242424 too (Fluent's transparent appearance would use\n // foreground2, #424242).\n color: tokens.colorNeutralForeground1,\n },\n // Dynamics, like Fluent, reserves each tab's SEMIBOLD width (a hidden zero-height copy of the\n // label), so tabs don't shift on selection: an unselected \"Web API Probe\" is 109.6 wide, its\n // semibold width in the same Segoe UI Web file. Fluent's reserved copy keeps its own 2px side\n // padding, which made it 113.6 — zero it like the visible content.\n [`& .${FLUENT_TAB_RESERVED_SPACE_CLASS}`]: {\n padding: 0,\n fontSize: `${T.fontSize}px`,\n },\n // Fluent draws the selected (and hover) indicator on ::after / ::before; move both to the\n // measured position and shape.\n '::after': {\n left: 0,\n right: 0,\n bottom: `${UNDERLINE_BOTTOM}px`,\n height: `${T.underlineHeight}px`,\n borderRadius: `${T.underlineRadius}px`,\n },\n '::before': {\n left: 0,\n right: 0,\n bottom: `${UNDERLINE_BOTTOM}px`,\n height: `${T.underlineHeight}px`,\n borderRadius: `${T.underlineRadius}px`,\n },\n // Fluent's hover/pressed indicator sets a circular radius at higher specificity; match it.\n ':hover::before': { borderRadius: `${T.underlineRadius}px` },\n ':active::before': { borderRadius: `${T.underlineRadius}px` },\n },\n});\n\n/** Tabbed surface (Fluent v9 `TabList`). Controlled via `selectedId`/`onTabChange` or uncontrolled. */\nexport const PivotSurface: React.FC<PivotSurfaceProps> = ({\n tabs,\n selectedId,\n defaultSelectedId,\n onTabChange,\n appearance = 'transparent',\n size = 'medium',\n className,\n look: lookProp,\n header,\n}) => {\n const styles = useStyles();\n const ce = lookProp === 'ce';\n // Tab ↔ panel wiring (role=tabpanel, aria-controls/labelledby) — Fluent's TabList does not do it.\n const baseId = useId();\n const tabId = (id: string) => `${baseId}-tab-${id}`;\n const panelId = `${baseId}-panel`;\n // Seed to the requested default, else the first *enabled* tab (don't open a disabled one).\n const firstEnabledId = tabs.find((t) => !t.disabled)?.id ?? tabs[0]?.id;\n const [internal, setInternal] = useState<string | undefined>(defaultSelectedId ?? firstEnabledId);\n const selected = selectedId ?? internal;\n\n const handleSelect = (_e: SelectTabEvent, data: SelectTabData) => {\n const id = String(data.value);\n if (selectedId == null) setInternal(id);\n onTabChange?.(id);\n };\n\n const active = tabs.find((t) => t.id === selected) ?? tabs[0];\n\n if (ce) {\n const [bodyTop, , bodyBottom] = ceForm.tabBody.padding;\n return (\n <div\n className={className}\n // minWidth 0: as a grid/flex child (FormSurface), the header's no-wrap content must not\n // widen the track — the card shrinks and the header clips/truncates inside it instead.\n style={{ padding: `0 ${ceForm.page.insetRight}px 0 ${ceForm.page.insetLeft}px`, minWidth: 0 }}\n data-surface-part=\"pivot\"\n data-look=\"ce\"\n >\n <div className={styles.ceCard} data-surface-part=\"header-card\">\n {header}\n <TabList\n className={styles.ceStrip}\n selectedValue={selected}\n onTabSelect={handleSelect}\n appearance=\"transparent\"\n size=\"large\"\n data-surface-part=\"tab-strip\"\n >\n {tabs.map((t) => (\n <Tab\n key={t.id}\n value={t.id}\n icon={t.icon}\n disabled={t.disabled}\n className={styles.ceTab}\n id={tabId(t.id)}\n aria-controls={t.id === active?.id ? panelId : undefined}\n >\n {t.label}\n </Tab>\n ))}\n </TabList>\n </div>\n <div\n role=\"tabpanel\"\n id={panelId}\n aria-labelledby={active ? tabId(active.id) : undefined}\n style={{ paddingTop: bodyTop, paddingBottom: bodyBottom }}\n data-surface-part=\"tab-body\"\n >\n {active?.content}\n </div>\n </div>\n );\n }\n\n return (\n <div className={className}>\n {header}\n <TabList selectedValue={selected} onTabSelect={handleSelect} appearance={appearance} size={size}>\n {tabs.map((t) => (\n <Tab\n key={t.id}\n value={t.id}\n icon={t.icon}\n disabled={t.disabled}\n id={tabId(t.id)}\n aria-controls={t.id === active?.id ? panelId : undefined}\n >\n {t.label}\n </Tab>\n ))}\n </TabList>\n <div role=\"tabpanel\" id={panelId} aria-labelledby={active ? tabId(active.id) : undefined} data-surface-part=\"tab-body\">\n {active?.content}\n </div>\n </div>\n );\n};\n\nexport default PivotSurface;\n","import React from 'react';\nimport {\n Button,\n Toolbar,\n ToolbarButton,\n ToolbarDivider,\n Menu,\n MenuTrigger,\n MenuPopover,\n MenuList,\n MenuItem,\n buttonClassNames,\n makeStyles,\n mergeClasses,\n tokens,\n} from '@fluentui/react-components';\nimport {\n ArrowLeft20Regular,\n ChevronDown12Regular,\n ChevronDown16Regular,\n MoreHorizontal20Regular,\n MoreVertical16Regular,\n WindowNew20Regular,\n} from '@fluentui/react-icons';\nimport type { CommandSurfaceProps, SurfaceToolbarItem } from '../types';\nimport { ceForm } from '../../tokens';\n\n/** A menu of `items` behind `trigger` — shared by both looks. Nested `menuItems` are not rendered. */\nfunction ItemMenu({ items, trigger }: { items: SurfaceToolbarItem[]; trigger: React.ReactElement }) {\n return (\n <Menu>\n <MenuTrigger disableButtonEnhancement>{trigger}</MenuTrigger>\n <MenuPopover>\n <MenuList>\n {items.map((m) => (\n <MenuItem key={m.id} icon={m.icon} disabled={m.disabled} onClick={m.onClick}>\n {m.label}\n </MenuItem>\n ))}\n </MenuList>\n </MenuPopover>\n </Menu>\n );\n}\n\nfunction renderToolbarButton(item: SurfaceToolbarItem): React.ReactElement {\n const button = (\n <ToolbarButton\n key={item.id}\n icon={item.icon}\n appearance={item.appearance === 'primary' ? 'primary' : 'subtle'}\n disabled={item.disabled}\n onClick={item.menuItems?.length ? undefined : item.onClick}\n >\n {item.label}\n </ToolbarButton>\n );\n if (!item.menuItems?.length) return button;\n // The default look honours `menuItems` and `split` too, so neither the menu nor a split item's\n // onClick is ever silently dropped. (Only the ce look carries the measured split geometry.)\n if (!item.split) return <ItemMenu key={item.id} items={item.menuItems} trigger={button} />;\n return (\n <React.Fragment key={item.id}>\n {React.cloneElement(button, { onClick: item.onClick })}\n <ItemMenu\n items={item.menuItems}\n trigger={\n <ToolbarButton\n appearance=\"subtle\"\n aria-label={`More ${item.label} options`}\n icon={<ChevronDown16Regular />}\n disabled={item.disabled}\n />\n }\n />\n </React.Fragment>\n );\n}\n\n// ★ look=\"ce\" is the MEASURED Dynamics command bar (dynamics-ui-kit\n// apps/ce-parity/reference/captures/account-main-commandbar-1710.txt, coordinates relative to\n// the card). All geometry comes from @dataverse-kit/design-tokens `ceForm.commandBar`, which the\n// reference check compares with that capture. Stock Fluent parts (Toolbar, ToolbarButton,\n// ToolbarDivider — the org's dividers ARE Fluent Dividers, #d1d1d1 — Menu, Button).\n// ★ OPT-IN (`look=\"ce\"`), like PivotSurface: it is page chrome (page insets, a card, the gap to\n// the header card), so a CommandSurface used as a toolbar inside a ce form must stay plain.\n\nconst CB = ceForm.commandBar;\n// Fluent buttons keep a 1px transparent border (focus/hover); Dynamics' measured paddings INCLUDE\n// the edge, so horizontal paddings/zones subtract it to land on the measured widths.\nconst FLUENT_BORDER = 1;\n// Room for Fluent's forced-colors outline (2px, drawn outside the button) inside the clipping row.\nconst FOCUS_ROOM = 2;\n\nconst useStyles = makeStyles({\n root: {\n minWidth: 0,\n // Page insets (16 left / 20 right), 8px from the top, 16px gap to the header card. A class\n // (not an inline style) so a host's className can override it.\n padding: `${CB.marginTop}px ${ceForm.page.insetRight}px ${ceForm.header.marginTop}px ${ceForm.page.commandBarInsetLeft}px`,\n },\n card: {\n display: 'flex',\n alignItems: 'center',\n minWidth: 0,\n boxSizing: 'border-box',\n height: `${CB.cardHeight}px`,\n backgroundColor: tokens.colorNeutralBackground1,\n border: '1px solid transparent',\n borderRadius: tokens.borderRadiusXLarge,\n boxShadow: tokens.shadow4,\n },\n group: { display: 'flex', alignItems: 'center', flexShrink: 0 },\n nav: { marginLeft: `${CB.navInsetLeft}px` },\n navButton: {\n height: `${CB.buttonHeight}px`,\n minWidth: 0,\n // Fluent caps icon-only buttons at 32px; the measured back/pop-out/overflow are wider.\n maxWidth: 'none',\n padding: 0,\n flexShrink: 0,\n },\n divider: {\n flexGrow: 0,\n height: `${CB.dividerHeight}px`,\n padding: 0,\n // Measured line colour #d1d1d1 = colorNeutralStroke1 (ToolbarDivider has no `appearance`\n // prop, so the Divider's pseudo-element halves are recoloured; both sides, for RTL).\n '::before': { borderRightColor: tokens.colorNeutralStroke1, borderLeftColor: tokens.colorNeutralStroke1 },\n '::after': { borderRightColor: tokens.colorNeutralStroke1, borderLeftColor: tokens.colorNeutralStroke1 },\n },\n splitDivider: { height: `${CB.splitDividerHeight}px` },\n commands: {\n flex: '1 1 auto',\n minWidth: 0,\n columnGap: 0,\n // Commands past the edge are clipped (Dynamics folds them into ⋮ by an unmeasured rule — pass\n // overflowItems). The FOCUS_ROOM padding/negative margin keeps forced-colors outlines visible.\n overflow: 'hidden',\n padding: `${FOCUS_ROOM}px ${CB.commandsPaddingRight}px ${FOCUS_ROOM}px ${FOCUS_ROOM}px`,\n margin: `-${FOCUS_ROOM}px 0 -${FOCUS_ROOM}px -${FOCUS_ROOM}px`,\n },\n command: {\n height: `${CB.buttonHeight}px`,\n minWidth: 0,\n flexShrink: 0,\n padding: `1px ${CB.buttonPaddingX - FLUENT_BORDER}px`,\n fontSize: tokens.fontSizeBase300,\n fontWeight: tokens.fontWeightRegular,\n lineHeight: '21px',\n [`& .${buttonClassNames.icon}`]: {\n width: `${CB.iconSize}px`,\n height: `${CB.iconSize}px`,\n fontSize: `${CB.iconSize}px`,\n marginRight: `${CB.iconGap}px`,\n },\n },\n // Measured colours — NOT applied to primary commands, whose on-brand colours Fluent owns.\n commandColors: {\n color: tokens.colorNeutralForeground1,\n [`& .${buttonClassNames.icon}`]: { color: tokens.colorNeutralForeground2 },\n },\n menuCommand: { paddingRight: 0 },\n chevronZone: {\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: `${CB.chevronZone - FLUENT_BORDER}px`,\n flexShrink: 0,\n },\n splitMain: { marginRight: `${CB.splitGap}px` },\n iconOnly: {\n height: `${CB.buttonHeight}px`,\n minWidth: 0,\n maxWidth: 'none',\n flexShrink: 0,\n padding: 0,\n color: tokens.colorNeutralForeground1,\n },\n far: { padding: `0 ${CB.farPadding}px` },\n farButton: {\n height: `${CB.shareHeight}px`,\n minWidth: 0,\n // Share's border is a real 1px #d1d1d1 border in Dynamics too (bl=1 alongside p=1,8).\n padding: `1px ${CB.sharePaddingX}px`,\n fontSize: `${CB.shareFontSize}px`,\n lineHeight: `${CB.shareLineHeight}px`,\n fontWeight: tokens.fontWeightRegular,\n color: tokens.colorNeutralForeground2,\n borderTopColor: tokens.colorNeutralStroke1,\n borderRightColor: tokens.colorNeutralStroke1,\n borderBottomColor: tokens.colorNeutralStroke1,\n borderLeftColor: tokens.colorNeutralStroke1,\n [`& .${buttonClassNames.icon}`]: {\n width: `${CB.shareIconSize}px`,\n height: `${CB.shareIconSize}px`,\n fontSize: `${CB.shareIconSize}px`,\n marginRight: '4px',\n },\n },\n});\n\nfunction CeCommandSurface({ items, overflowItems, farItems, className, onBack, onPopOut }: CommandSurfaceProps) {\n const styles = useStyles();\n // ONE site decides whether the measured neutral colours apply: primary keeps Fluent's brand colours.\n // The data attribute exposes the same decision (jsdom cannot compute griffel colours).\n const measuredColors = (item: SurfaceToolbarItem) => item.appearance !== 'primary';\n const commandClass = (item: SurfaceToolbarItem, ...extra: (string | false)[]) =>\n mergeClasses(styles.command, measuredColors(item) && styles.commandColors, ...extra);\n const commandPart = (item: SurfaceToolbarItem) => ({\n 'data-surface-part': 'command',\n 'data-measured-colors': measuredColors(item) ? 'true' : undefined,\n });\n const appearanceOf = (item: SurfaceToolbarItem) => (item.appearance === 'primary' ? 'primary' : 'subtle');\n\n const command = (item: SurfaceToolbarItem) => {\n if (item.menuItems?.length && item.split) {\n return (\n <React.Fragment key={item.id}>\n <ToolbarButton\n appearance={appearanceOf(item)}\n icon={item.icon}\n disabled={item.disabled}\n onClick={item.onClick}\n className={commandClass(item, styles.splitMain)}\n {...commandPart(item)}\n >\n {item.label}\n </ToolbarButton>\n <ToolbarDivider className={mergeClasses(styles.divider, styles.splitDivider)} />\n <ItemMenu\n items={item.menuItems}\n trigger={\n <ToolbarButton\n appearance=\"subtle\"\n aria-label={`More ${item.label} options`}\n icon={<ChevronDown16Regular />}\n disabled={item.disabled}\n className={styles.iconOnly}\n // The chevron renders chevronZone wide but its SLOT is overhang narrower (measured).\n style={{ width: CB.chevronZone, marginRight: -CB.splitChevronOverhang }}\n data-surface-part=\"command-split-chevron\"\n />\n }\n />\n </React.Fragment>\n );\n }\n if (item.menuItems?.length) {\n return (\n <ItemMenu\n key={item.id}\n items={item.menuItems}\n trigger={\n <ToolbarButton\n appearance={appearanceOf(item)}\n icon={item.icon}\n disabled={item.disabled}\n className={commandClass(item, styles.menuCommand)}\n {...commandPart(item)}\n >\n {item.label}\n <span className={styles.chevronZone} aria-hidden=\"true\">\n <ChevronDown12Regular />\n </span>\n </ToolbarButton>\n }\n />\n );\n }\n return (\n <ToolbarButton\n key={item.id}\n appearance={appearanceOf(item)}\n icon={item.icon}\n disabled={item.disabled}\n onClick={item.onClick}\n className={commandClass(item)}\n {...commandPart(item)}\n >\n {item.label}\n </ToolbarButton>\n );\n };\n\n return (\n <div className={mergeClasses(styles.root, className)} data-surface-part=\"command-bar\" data-look=\"ce\">\n <div className={styles.card} data-surface-part=\"command-card\">\n {(onBack || onPopOut) && (\n <div role=\"group\" aria-label=\"Navigation\" className={mergeClasses(styles.group, styles.nav)} data-surface-part=\"command-nav\">\n {onBack && (\n <>\n <Button\n appearance=\"subtle\"\n icon={<ArrowLeft20Regular />}\n aria-label=\"Back\"\n onClick={onBack}\n className={styles.navButton}\n style={{ width: CB.backWidth }}\n data-surface-part=\"command-back\"\n />\n <ToolbarDivider className={styles.divider} />\n </>\n )}\n {onPopOut && (\n <>\n <Button\n appearance=\"subtle\"\n icon={<WindowNew20Regular />}\n aria-label=\"Open in new window\"\n onClick={onPopOut}\n className={styles.navButton}\n style={{ width: CB.popOutWidth }}\n data-surface-part=\"command-popout\"\n />\n <ToolbarDivider className={styles.divider} />\n </>\n )}\n </div>\n )}\n <Toolbar aria-label=\"Commands\" className={styles.commands} data-surface-part=\"command-list\">\n {items.map(command)}\n {overflowItems && overflowItems.length > 0 && (\n <ItemMenu\n items={overflowItems}\n trigger={\n <ToolbarButton\n appearance=\"subtle\"\n aria-label=\"More commands\"\n icon={<MoreVertical16Regular />}\n className={styles.iconOnly}\n style={{ width: CB.overflowWidth }}\n data-surface-part=\"command-overflow\"\n />\n }\n />\n )}\n </Toolbar>\n {farItems && farItems.length > 0 && (\n <div role=\"group\" aria-label=\"Secondary commands\" className={mergeClasses(styles.group, styles.far)} data-surface-part=\"command-far\">\n {farItems.map((f) => {\n const btn = (\n <Button\n key={f.id}\n appearance=\"outline\"\n icon={f.icon}\n disabled={f.disabled}\n onClick={f.menuItems?.length ? undefined : f.onClick}\n className={styles.farButton}\n data-surface-part=\"command-far-button\"\n >\n {f.label}\n {f.menuItems?.length ? <ChevronDown12Regular style={{ marginLeft: 4 }} aria-hidden /> : null}\n </Button>\n );\n return f.menuItems?.length ? <ItemMenu key={f.id} items={f.menuItems} trigger={btn} /> : btn;\n })}\n </div>\n )}\n </div>\n </div>\n );\n}\n\n/** A Dynamics-style command bar (Fluent v9 `Toolbar`), with an optional overflow menu + far items. */\nexport const CommandSurface: React.FC<CommandSurfaceProps> = (props) => {\n if (props.look === 'ce') return <CeCommandSurface {...props} />;\n\n const { items, overflowItems, farItems, size = 'small', className } = props;\n const hasFar = Boolean(farItems && farItems.length > 0);\n const hasOverflow = Boolean(overflowItems && overflowItems.length > 0);\n\n const hasPrimary = items.length > 0 || hasOverflow;\n\n return (\n <div className={className} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {hasPrimary && (\n <Toolbar aria-label=\"Commands\" size={size}>\n {items.map(renderToolbarButton)}\n {hasOverflow && (\n <Menu>\n <MenuTrigger disableButtonEnhancement>\n <ToolbarButton aria-label=\"More commands\" icon={<MoreHorizontal20Regular />} />\n </MenuTrigger>\n <MenuPopover>\n <MenuList>\n {overflowItems!.map((item) => (\n <MenuItem key={item.id} icon={item.icon} disabled={item.disabled} onClick={item.onClick}>\n {item.label}\n </MenuItem>\n ))}\n </MenuList>\n </MenuPopover>\n </Menu>\n )}\n </Toolbar>\n )}\n {hasFar && (\n // marginLeft:auto keeps far items right-aligned whether or not a primary toolbar renders.\n <Toolbar aria-label=\"Secondary commands\" size={size} style={{ marginLeft: 'auto' }}>\n {farItems!.map(renderToolbarButton)}\n </Toolbar>\n )}\n </div>\n );\n};\n\nexport default CommandSurface;\n","import React from 'react';\nimport { Button, tokens } from '@fluentui/react-components';\nimport type { ActionBarProps, SurfaceActionButton } from '../types';\n\nfunction renderButton(b: SurfaceActionButton): React.ReactElement {\n // v9 appearance: primary → primary, subtle → subtle, default → secondary.\n const appearance = b.appearance === 'primary' ? 'primary' : b.appearance === 'subtle' ? 'subtle' : 'secondary';\n return (\n <Button key={b.id} appearance={appearance} icon={b.icon} disabled={b.disabled} onClick={b.onClick}>\n {b.label}\n </Button>\n );\n}\n\n/** A sticky footer bar of action buttons (Fluent v9), with optional left-aligned buttons. */\nexport const ActionBar: React.FC<ActionBarProps> = ({ buttons, alignment = 'right', sticky = true, className }) => {\n const justify = alignment === 'left' ? 'flex-start' : alignment === 'center' ? 'center' : 'flex-end';\n const visible = buttons.filter((b) => !b.hidden);\n const left = visible.filter((b) => b.position === 'left');\n const right = visible.filter((b) => b.position !== 'left');\n\n const rootStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: left.length ? 'space-between' : justify,\n gap: 8,\n padding: '12px 24px',\n borderTop: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n ...(sticky ? { position: 'sticky', bottom: 0, zIndex: 1 } : {}),\n };\n\n return (\n <div className={className} style={rootStyle}>\n {left.length > 0 && <div style={{ display: 'flex', gap: 8 }}>{left.map(renderButton)}</div>}\n <div style={{ display: 'flex', gap: 8, justifyContent: justify }}>{right.map(renderButton)}</div>\n </div>\n );\n};\n\nexport default ActionBar;\n","import React from 'react';\nimport { tokens } from '@fluentui/react-components';\nimport type { FooterProps } from '../types';\n\n/** A sticky footer region (free-form children, Fluent v9) — e.g. for dialog/panel actions. */\nexport const Footer: React.FC<FooterProps> = ({ sticky = true, align = 'right', className, children }) => {\n const justify = align === 'left' ? 'flex-start' : align === 'center' ? 'center' : 'flex-end';\n const rootStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: justify,\n gap: 8,\n padding: '12px 24px',\n borderTop: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: tokens.colorNeutralBackground1,\n ...(sticky ? { position: 'sticky', bottom: 0, zIndex: 1 } : {}),\n };\n return (\n <div className={className} style={rootStyle}>\n {children}\n </div>\n );\n};\n\nexport default Footer;\n","import React from 'react';\nimport { makeStyles, mergeClasses } from '@fluentui/react-components';\nimport type { TabColumnsProps } from '../types';\nimport { ceForm } from '../../tokens';\nimport { normalizeColumnShares } from '../../core/ceLayout';\nimport { useLook } from '../../hooks/useLook';\n\n// A tab body's columns (Fluent v9), laid out the way Dynamics lays out a formxml tab.\n//\n// Each column is `flex: <normalised share> 1 0` with a `min-width`, so CSS flexbox resolves the\n// widths itself: every column gets its share of the row, none goes below the floor, and a clamped\n// column's shortfall is taken from the others by share. That is the measured Dynamics rule; core\n// `resolveTabColumnWidths` returns the same numbers without a DOM (both normalise the shares).\n// Sections stack inside a column with the same gap. Columns wrap onto a new line once even the\n// floors do not fit, and the floor never exceeds the container (`min(floor, 100%)`) so a narrow\n// host degrades to one full-width column instead of overflowing. Dynamics' behaviour in both\n// cases is unmeasured.\n//\n// ★ Columns are POSITIONAL, like formxml: `widths[i]` belongs to the i-th child slot even when an\n// earlier child is `null`/`false` (a conditional column), so a hidden column never hands its\n// share to its neighbour.\n\nconst useStyles = makeStyles({\n row: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'flex-start',\n },\n column: {\n display: 'flex',\n flexDirection: 'column',\n boxSizing: 'border-box',\n },\n});\n\n/** Flatten top-level children positionally: arrays are expanded; empty slots are kept as null. */\nfunction positional(children: React.ReactNode): React.ReactNode[] {\n const out: React.ReactNode[] = [];\n const walk = (node: React.ReactNode) => {\n if (Array.isArray(node)) node.forEach(walk);\n else out.push(node);\n };\n walk(children);\n return out;\n}\nconst isEmpty = (n: React.ReactNode) => n === null || n === undefined || typeof n === 'boolean' || n === '';\n\n/** Tab-body columns with declared shares and a width floor (Fluent UI v9). One child per column. */\nexport const TabColumns: React.FC<TabColumnsProps> = ({\n widths,\n minColumnWidth,\n gap,\n look: lookProp,\n className,\n style,\n children,\n}) => {\n const styles = useStyles();\n const ambientLook = useLook();\n const ce = (lookProp ?? ambientLook) === 'ce';\n const floor = minColumnWidth ?? (ce ? ceForm.tabBody.columnMinWidth : 300);\n const spacing = gap ?? (ce ? ceForm.tabBody.columnGap : 20);\n const slots = positional(children);\n // Shares are resolved over the VISIBLE columns (a hidden column takes no space), each keeping\n // its own declared share.\n const visible = slots.map((s, i) => ({ node: s, i })).filter(({ node }) => !isEmpty(node));\n const shares = normalizeColumnShares(visible.map(({ i }) => widths?.[i] ?? 1));\n\n return (\n <div\n className={mergeClasses(styles.row, className)}\n style={{ gap: spacing, ...style }}\n data-surface-part=\"tab-columns\"\n data-look={ce ? 'ce' : 'default'}\n >\n {visible.map(({ node, i }, v) => (\n <div\n key={React.isValidElement(node) && node.key != null ? node.key : i}\n className={styles.column}\n style={{ flex: `${shares[v]} 1 0`, minWidth: `min(${floor}px, 100%)`, gap: ce ? ceForm.tabBody.sectionGap : spacing }}\n data-surface-part=\"tab-column\"\n data-column-index={i}\n >\n {node}\n </div>\n ))}\n </div>\n );\n};\n\nexport default TabColumns;\n","import React from 'react';\nimport { Dialog, DialogSurface, Button, Text, tokens } from '@fluentui/react-components';\nimport { Dismiss20Regular } from '@fluentui/react-icons';\nimport type { FormDialogSurfaceProps } from '../types';\nimport { dialogWidthCss, dialogHeightCss } from '../../core/sizePresets';\n\n// The Fluent v9 counterpart of the v8 FormDialogSurface (a `<Modal>`): a controlled\n// `<Dialog>` + `<DialogSurface>` sized from the SHARED sizing scalars (dialogWidthCss /\n// dialogHeightCss — the same 1200 / 95vh contract the v8 skin and the codegen use), with a\n// custom header (title/subheader | counter + close), a scrolling content region, and a\n// sticky footer. Content is rendered directly in DialogSurface (padding managed here) so the\n// flex-column scroll layout matches the v8 Modal main/scrollableContent.\n\n/**\n * Full Dynamics form-dialog (Fluent v9 `Dialog`). Default width 1200 (lg), height 95vh.\n * `onDismiss` is the close affordance — when omitted, no close button renders. `isBlocking`\n * maps to the dialog `modalType` (`modal` vs `non-modal`).\n */\nexport const FormDialogSurface: React.FC<FormDialogSurfaceProps> = ({\n isOpen,\n onDismiss,\n title,\n subheader,\n size,\n width,\n height,\n isBlocking = true,\n recordCounter,\n footer,\n className,\n children,\n}) => {\n const widthCss = dialogWidthCss({ width, size });\n const heightCss = dialogHeightCss(height);\n const showHeader = Boolean(title) || Boolean(recordCounter) || Boolean(onDismiss);\n\n const headerStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n padding: '12px 20px',\n borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,\n };\n const counterStyle: React.CSSProperties = { fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3 };\n\n return (\n <Dialog\n open={isOpen}\n modalType={isBlocking ? 'modal' : 'non-modal'}\n onOpenChange={(_e, data) => {\n if (!data.open) onDismiss?.();\n }}\n >\n <DialogSurface\n className={className}\n style={{\n maxWidth: '95vw',\n width: widthCss,\n height: heightCss,\n maxHeight: '95vh',\n display: 'flex',\n flexDirection: 'column',\n padding: 0,\n }}\n >\n {showHeader && (\n <div style={headerStyle}>\n <div style={{ display: 'flex', flexDirection: 'column', minWidth: 0 }}>\n {title && (\n <Text weight=\"semibold\" size={400}>\n {title}\n </Text>\n )}\n {subheader && (\n <span style={{ fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground3, marginTop: 2 }}>\n {subheader}\n </span>\n )}\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {recordCounter && (\n <span style={counterStyle}>\n {recordCounter.current} of {recordCounter.total}\n </span>\n )}\n {onDismiss && (\n <Button appearance=\"subtle\" aria-label=\"Close\" icon={<Dismiss20Regular />} onClick={onDismiss} />\n )}\n </div>\n </div>\n )}\n <div style={{ flex: 1, minHeight: 0, overflow: 'auto', padding: 20 }}>{children}</div>\n {footer && (\n <div style={{ borderTop: `1px solid ${tokens.colorNeutralStroke2}`, padding: '12px 20px' }}>{footer}</div>\n )}\n </DialogSurface>\n </Dialog>\n );\n};\n\nexport default FormDialogSurface;\n","import React from 'react';\nimport { Dialog, DialogSurface, Text, tokens } from '@fluentui/react-components';\nimport type { ModalSurfaceProps } from '../types';\nimport { dialogWidthPx, MODAL_AUTOSIZE_MIN_WIDTH } from '../../core/sizePresets';\n\n/** A generic modal (Fluent v9 `Dialog`) — title + content + optional footer; lighter than FormDialogSurface. */\nexport const ModalSurface: React.FC<ModalSurfaceProps> = ({\n isOpen,\n onDismiss,\n title,\n size,\n width,\n isBlocking = true,\n autoSize,\n footer,\n className,\n children,\n}) => {\n const sizing: React.CSSProperties = autoSize\n ? { width: 'auto', minWidth: MODAL_AUTOSIZE_MIN_WIDTH, maxWidth: '100%' }\n : { maxWidth: '95vw', width: `${dialogWidthPx({ width, size })}px` };\n\n return (\n <Dialog\n open={isOpen}\n modalType={isBlocking ? 'modal' : 'non-modal'}\n onOpenChange={(_e, data) => {\n if (!data.open) onDismiss?.();\n }}\n >\n <DialogSurface className={className} style={{ ...sizing, padding: 0 }}>\n {title && (\n <div style={{ padding: '16px 20px 0' }}>\n <Text weight=\"semibold\" size={500}>\n {title}\n </Text>\n </div>\n )}\n <div style={{ padding: 20 }}>{children}</div>\n {footer && (\n <div\n style={{\n borderTop: `1px solid ${tokens.colorNeutralStroke2}`,\n padding: '12px 20px',\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n }}\n >\n {footer}\n </div>\n )}\n </DialogSurface>\n </Dialog>\n );\n};\n\nexport default ModalSurface;\n","import React from 'react';\nimport {\n OverlayDrawer,\n DrawerHeader,\n DrawerHeaderTitle,\n DrawerBody,\n Button,\n} from '@fluentui/react-components';\nimport { Dismiss24Regular } from '@fluentui/react-icons';\nimport type { PanelSurfaceProps } from '../types';\n\n// The Fluent v9 counterpart of the v8 PanelSurface (a `<Panel>`): a right-edge\n// `<OverlayDrawer>`. The v8 medium-vs-custom width heuristic (>500 → medium) maps to the\n// v9 Drawer `size`; an explicit `width` renders a custom-width drawer. `isLightDismiss`\n// controls backdrop-click dismissal (Esc still closes); `isNonModal` drops the blocking overlay.\n\n/** A Dynamics side panel (Fluent v9 `OverlayDrawer`). */\nexport const PanelSurface: React.FC<PanelSurfaceProps> = ({\n isOpen,\n onDismiss,\n title,\n drawerSize,\n width,\n hasCloseButton = true,\n isLightDismiss = true,\n isNonModal = false,\n footer,\n children,\n}) => {\n const size = drawerSize ?? (width != null && width > 500 ? 'medium' : 'small');\n const customWidthStyle = width != null ? ({ width: `${width}px` } as React.CSSProperties) : undefined;\n\n return (\n <OverlayDrawer\n open={isOpen}\n position=\"end\"\n size={size}\n modalType={isNonModal ? 'non-modal' : 'modal'}\n style={customWidthStyle}\n onOpenChange={(_e, data) => {\n if (data.open) return;\n // Honor isLightDismiss for backdrop clicks; Esc + explicit close always dismiss.\n if (data.type === 'backdropClick' && !isLightDismiss) return;\n onDismiss?.();\n }}\n >\n <DrawerHeader>\n <DrawerHeaderTitle\n action={\n hasCloseButton && onDismiss ? (\n <Button appearance=\"subtle\" aria-label=\"Close\" icon={<Dismiss24Regular />} onClick={onDismiss} />\n ) : undefined\n }\n >\n {title}\n </DrawerHeaderTitle>\n </DrawerHeader>\n <DrawerBody>\n <div style={{ padding: '12px 0' }}>{children}</div>\n {footer && <div style={{ marginTop: 'auto', paddingTop: 12 }}>{footer}</div>}\n </DrawerBody>\n </OverlayDrawer>\n );\n};\n\nexport default PanelSurface;\n","import React from 'react';\nimport { Popover, PopoverSurface, type PositioningShorthand } from '@fluentui/react-components';\nimport type { CalloutSurfaceProps } from '../types';\nimport { calloutWidthPx } from '../../core/sizePresets';\n\n// The Fluent v9 counterpart of the v8 CalloutSurface (a `<Callout>`): a controlled,\n// target-anchored `<Popover>` + `<PopoverSurface>`. v8's `target` (selector / element / ref)\n// is resolved to an element and passed via `positioning.target`; there is no PopoverTrigger\n// because anchoring comes from the target (matching the v8 target-based API). `isBeakVisible`\n// maps to `withArrow`.\n\nfunction resolveTarget(target: CalloutSurfaceProps['target']): HTMLElement | null {\n if (!target) return null;\n if (typeof target === 'string') return document.querySelector<HTMLElement>(target);\n if ('current' in target) return (target.current as HTMLElement | null) ?? null;\n return target as HTMLElement;\n}\n\n/** A lightweight contextual callout (Fluent v9 `Popover`) anchored to a target. */\nexport const CalloutSurface: React.FC<CalloutSurfaceProps> = ({\n target,\n isOpen = true,\n onDismiss,\n width,\n position = 'below',\n align = 'start',\n isBeakVisible = true,\n className,\n children,\n}) => {\n if (!isOpen) return null;\n const el = resolveTarget(target);\n // If the target can't be resolved (selector miss / target={null}), the Popover renders\n // unanchored (position defaults apply) rather than throwing — an intentional soft fallback.\n const positioning: PositioningShorthand = { position, align, ...(el ? { target: el } : {}) };\n\n return (\n <Popover\n open\n trapFocus={false}\n withArrow={isBeakVisible}\n positioning={positioning}\n onOpenChange={(_e, data) => {\n if (!data.open) onDismiss?.();\n }}\n >\n <PopoverSurface className={className} style={{ width: calloutWidthPx(width), padding: 16 }}>\n {children}\n </PopoverSurface>\n </Popover>\n );\n};\n\nexport default CalloutSurface;\n","import React from 'react';\nimport { Tooltip } from '@fluentui/react-components';\nimport type { TooltipSurfaceProps } from '../types';\n\nconst DELAY_MS: Record<NonNullable<TooltipSurfaceProps['delay']>, number> = {\n zero: 0,\n medium: 250,\n long: 500,\n};\n\n/** A tooltip wrapper (Fluent v9 `Tooltip`). */\nexport const TooltipSurface: React.FC<TooltipSurfaceProps> = ({\n content,\n position = 'above',\n delay = 'medium',\n relationship = 'label',\n children,\n}) => (\n <Tooltip content={content} relationship={relationship} positioning={position} showDelay={DELAY_MS[delay]}>\n {children}\n </Tooltip>\n);\n\nexport default TooltipSurface;\n"],"mappings":"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","names":["useState","useEffect","createContext","useContext","jsx","useState","makeStyles","mergeClasses","tokens","makeStyles","mergeClasses","tokens","jsx","useStyles","makeStyles","tokens","beside","mergeClasses","tokens","jsx","jsxs","tokens","jsx","jsxs","useStyles","makeStyles","useState","tokens","mergeClasses","tokens","jsx","tokens","React","Button","Text","makeStyles","tokens","ChevronDown20Regular","jsx","jsxs","tokens","useStyles","makeStyles","Text","React","Button","ChevronDown20Regular","useState","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","useState","React","Button","Toolbar","ToolbarButton","Menu","MenuTrigger","MenuPopover","MenuList","makeStyles","mergeClasses","tokens","ChevronDown12Regular","Fragment","jsx","jsxs","Menu","MenuTrigger","MenuPopover","MenuList","ToolbarButton","React","useStyles","makeStyles","tokens","mergeClasses","ChevronDown12Regular","Button","Toolbar","Button","tokens","jsx","jsxs","tokens","jsx","React","makeStyles","mergeClasses","jsx","useStyles","makeStyles","isEmpty","spacing","mergeClasses","React","Button","Text","tokens","jsx","jsxs","tokens","Text","Button","Dialog","DialogSurface","Text","tokens","jsx","jsxs","Dialog","DialogSurface","Text","tokens","Button","jsx","jsxs","jsx","jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dataverse-kit/surface-kit",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "license": "MIT",
5
5
  "description": "Shared, responsive surfaces / containers / layouts for Dynamics 365. Form shells, sections, tabs, and overlay surfaces (Dialog/Modal/Panel/Callout/Tooltip) that match Dynamics CE and host grid-kit grids, in both Fluent UI v8 (the default `.` entry) and Fluent UI v9 (the `./v9` entry). The pure-TS ./core (sizing) and ./responsive (breakpoint builders) subpaths are framework-agnostic and shared by both skins and the export-engine codegen.",
6
6
  "type": "module",
@@ -51,7 +51,8 @@
51
51
  "clean": "rimraf dist coverage tsconfig.tsbuildinfo storybook-static"
52
52
  },
53
53
  "dependencies": {
54
- "@dataverse-kit/design-tokens": "^0.1.1"
54
+ "@dataverse-kit/design-tokens": "^0.2.0",
55
+ "@dataverse-kit/fluent-theme": "^0.3.0"
55
56
  },
56
57
  "peerDependencies": {
57
58
  "@fluentui/react": "^8.115.6",