@dataverse-kit/surface-kit 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/v9.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/v9/index.ts
@@ -24,14 +34,18 @@ __export(v9_exports, {
24
34
  BREAKPOINTS: () => BREAKPOINTS,
25
35
  CALLOUT_DEFAULT_WIDTH: () => CALLOUT_DEFAULT_WIDTH,
26
36
  CARD_REFLOW_WIDTH: () => CARD_REFLOW_WIDTH,
37
+ CE_LABEL_ABOVE_BELOW_ROW_WIDTH: () => CE_LABEL_ABOVE_BELOW_ROW_WIDTH,
38
+ CE_TAB_COLUMN_MIN_WIDTH: () => CE_TAB_COLUMN_MIN_WIDTH,
27
39
  CalloutSurface: () => CalloutSurface,
28
40
  CommandSurface: () => CommandSurface,
29
41
  DIALOG_SIZE_PX: () => DIALOG_SIZE_PX,
30
42
  DensityContext: () => DensityContext,
43
+ FieldRow: () => FieldRow,
31
44
  Footer: () => Footer,
32
45
  FormDialogSurface: () => FormDialogSurface,
33
46
  FormHeader: () => FormHeader,
34
47
  FormSurface: () => FormSurface,
48
+ LookContext: () => LookContext,
35
49
  MODAL_AUTOSIZE_MIN_WIDTH: () => MODAL_AUTOSIZE_MIN_WIDTH,
36
50
  ModalSurface: () => ModalSurface,
37
51
  PANEL_DEFAULT_WIDTH: () => PANEL_DEFAULT_WIDTH,
@@ -41,11 +55,16 @@ __export(v9_exports, {
41
55
  Section: () => Section,
42
56
  SectionCard: () => SectionCard,
43
57
  SectionHeader: () => SectionHeader,
58
+ TabColumns: () => TabColumns,
44
59
  TooltipSurface: () => TooltipSurface,
45
60
  calloutFormDefaults: () => calloutFormDefaults,
46
61
  calloutWidthPx: () => calloutWidthPx,
62
+ ceFieldRowFirstOffset: () => ceFieldRowFirstOffset,
63
+ ceForm: () => import_design_tokens.ceForm,
64
+ cePresenceBadgeStyle: () => cePresenceBadgeStyle,
47
65
  clampSpan: () => clampSpan,
48
66
  colors: () => import_design_tokens.colors,
67
+ createDynamicsCeTheme: () => import_fluent_theme.createDynamicsCeTheme,
49
68
  createDynamicsV9DarkTheme: () => import_fluent_theme.createDynamicsV9DarkTheme,
50
69
  createDynamicsV9Theme: () => import_fluent_theme.createDynamicsV9Theme,
51
70
  densityScale: () => densityScale,
@@ -53,17 +72,20 @@ __export(v9_exports, {
53
72
  dialogWidthCss: () => dialogWidthCss,
54
73
  dialogWidthPx: () => dialogWidthPx,
55
74
  dynamicsBrandRamp: () => import_fluent_theme.dynamicsBrandRamp,
75
+ dynamicsCeTheme: () => import_fluent_theme.dynamicsCeTheme,
56
76
  dynamicsV9DarkTheme: () => import_fluent_theme.dynamicsV9DarkTheme,
57
77
  dynamicsV9Theme: () => import_fluent_theme.dynamicsV9Theme,
58
78
  fieldGridStyle: () => fieldGridStyle,
59
79
  fieldRowStyle: () => fieldRowStyle,
60
80
  gridTemplateForColumns: () => gridTemplateForColumns,
61
81
  layout: () => import_design_tokens.layout,
82
+ normalizeColumnShares: () => normalizeColumnShares,
62
83
  panelCustomWidthPx: () => panelCustomWidthPx,
63
84
  panelKindFromWidth: () => panelKindFromWidth,
64
85
  radius: () => import_design_tokens.radius,
65
86
  resolveBreakpoint: () => resolveBreakpoint,
66
87
  resolveResponsiveValue: () => resolveResponsiveValue,
88
+ resolveTabColumnWidths: () => resolveTabColumnWidths,
67
89
  scaleSpacing: () => scaleSpacing,
68
90
  sectionStackingStyle: () => sectionStackingStyle,
69
91
  spacing: () => import_design_tokens.spacing,
@@ -72,6 +94,7 @@ __export(v9_exports, {
72
94
  useContainerSize: () => useContainerSize,
73
95
  useContainerWidth: () => useContainerWidth,
74
96
  useDensity: () => useDensity,
97
+ useLook: () => useLook,
75
98
  useMediaQuery: () => useMediaQuery,
76
99
  useResponsiveValue: () => useResponsiveValue
77
100
  });
@@ -123,6 +146,34 @@ function clampSpan(span, columns) {
123
146
  return Math.max(1, Math.min(Math.round(span), columns));
124
147
  }
125
148
 
149
+ // src/core/ceLayout.ts
150
+ var CE_TAB_COLUMN_MIN_WIDTH = 340;
151
+ function normalizeColumnShares(shares) {
152
+ const clean = shares.map((s) => Number.isFinite(s) && s > 0 ? s : 0);
153
+ const total = clean.reduce((a, b) => a + b, 0);
154
+ if (total <= 0) return shares.map(() => 100 / (shares.length || 1));
155
+ return clean.map((s) => s / total * 100);
156
+ }
157
+ function resolveTabColumnWidths(shares, available, minWidth = CE_TAB_COLUMN_MIN_WIDTH) {
158
+ if (shares.length === 0) return [];
159
+ shares = normalizeColumnShares(shares);
160
+ const clamped = /* @__PURE__ */ new Set();
161
+ let widths = [];
162
+ for (let pass = 0; pass <= shares.length; pass++) {
163
+ const free = available - clamped.size * minWidth;
164
+ const total = shares.reduce((sum, s, i) => clamped.has(i) ? sum : sum + Math.max(0, s), 0);
165
+ widths = shares.map((s, i) => {
166
+ if (clamped.has(i)) return minWidth;
167
+ return total > 0 ? Math.max(0, s) / total * free : free / (shares.length - clamped.size);
168
+ });
169
+ const violators = widths.map((w, i) => !clamped.has(i) && w < minWidth ? i : -1).filter((i) => i >= 0);
170
+ if (violators.length === 0) break;
171
+ violators.forEach((i) => clamped.add(i));
172
+ }
173
+ return widths;
174
+ }
175
+ var CE_LABEL_ABOVE_BELOW_ROW_WIDTH = 340;
176
+
126
177
  // src/responsive/breakpoints.ts
127
178
  var BREAKPOINTS = {
128
179
  xs: 0,
@@ -273,6 +324,11 @@ var import_react4 = require("react");
273
324
  var DensityContext = (0, import_react4.createContext)("comfortable");
274
325
  var useDensity = () => (0, import_react4.useContext)(DensityContext);
275
326
 
327
+ // src/hooks/useLook.ts
328
+ var import_react5 = require("react");
329
+ var LookContext = (0, import_react5.createContext)("default");
330
+ var useLook = () => (0, import_react5.useContext)(LookContext);
331
+
276
332
  // src/v9/theme.ts
277
333
  var import_fluent_theme = require("@dataverse-kit/fluent-theme");
278
334
 
@@ -308,10 +364,11 @@ var VIEWPORT_STACK = {
308
364
  var FormSurface = ({
309
365
  columns = 12,
310
366
  gap = 20,
311
- padding = 20,
367
+ padding,
312
368
  density = "comfortable",
313
369
  background,
314
370
  containerWidth,
371
+ look = "default",
315
372
  collapseBelow = "sm",
316
373
  maxWidth,
317
374
  className,
@@ -319,10 +376,29 @@ var FormSurface = ({
319
376
  children
320
377
  }) => {
321
378
  const styles = useStyles();
379
+ if (look === "ce") {
380
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DensityContext.Provider, { value: density, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LookContext.Provider, { value: look, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
381
+ "div",
382
+ {
383
+ className,
384
+ "data-surface-part": "form-surface",
385
+ "data-look": "ce",
386
+ style: {
387
+ display: "flow-root",
388
+ minWidth: 0,
389
+ padding: padding ?? 0,
390
+ ...background != null ? { background } : {},
391
+ ...maxWidth != null ? { maxWidth, marginLeft: "auto", marginRight: "auto" } : {},
392
+ ...style
393
+ },
394
+ children
395
+ }
396
+ ) }) });
397
+ }
322
398
  const collapsePx = BREAKPOINTS[collapseBelow];
323
399
  const forceStack = containerWidth != null && containerWidth <= collapsePx;
324
400
  const scaledGap = scaleSpacing(gap, density);
325
- const scaledPadding = scaleSpacing(padding, density);
401
+ const scaledPadding = scaleSpacing(padding ?? 20, density);
326
402
  const viewportStackSlot = containerWidth == null ? VIEWPORT_STACK[collapseBelow] : null;
327
403
  const cls = (0, import_react_components.mergeClasses)(
328
404
  styles.root,
@@ -338,7 +414,7 @@ var FormSurface = ({
338
414
  ...maxWidth != null ? { maxWidth, marginLeft: "auto", marginRight: "auto" } : {},
339
415
  ...style
340
416
  };
341
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DensityContext.Provider, { value: density, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cls, style: inlineStyle, children }) });
417
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DensityContext.Provider, { value: density, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LookContext.Provider, { value: look, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cls, style: inlineStyle, children }) }) });
342
418
  };
343
419
 
344
420
  // src/v9/containers/PageSurface.tsx
@@ -346,13 +422,237 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
346
422
  var PageSurface = ({ centered, maxWidth, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FormSurface, { maxWidth: maxWidth ?? (centered ? 1200 : void 0), ...rest });
347
423
 
348
424
  // src/v9/containers/Section.tsx
349
- var import_react5 = require("react");
350
- var import_react_components3 = require("@fluentui/react-components");
425
+ var import_react6 = __toESM(require("react"), 1);
426
+ var import_react_components4 = require("@fluentui/react-components");
351
427
 
352
- // src/v9/containers/SectionHeader.tsx
428
+ // src/v9/layouts/FieldRow.tsx
353
429
  var import_react_components2 = require("@fluentui/react-components");
354
- var import_react_icons = require("@fluentui/react-icons");
355
430
  var import_jsx_runtime3 = require("react/jsx-runtime");
431
+ var F = import_design_tokens.ceForm.field;
432
+ var CE_LABEL_BOX = 30;
433
+ var CE_LABEL_OFFSET = 4;
434
+ var CE_CONTROL_OFFSET = 2;
435
+ var CE_CONTROL_INSET_RIGHT = 2;
436
+ var CE_LABEL_TEXT_WIDTH = 176;
437
+ var CE_MARKER_GAP = 4;
438
+ var ceFieldRowFirstOffset = F.rowPaddingTop - F.rowPaddingTopFirst;
439
+ var NARROW = `@container (width < ${CE_LABEL_ABOVE_BELOW_ROW_WIDTH}px)`;
440
+ var useStyles2 = (0, import_react_components2.makeStyles)({
441
+ // ── shared ──────────────────────────────────────────────────────────────
442
+ // Span every column when placed in a grid (v9 Section's body is repeat(12, 1fr)).
443
+ spanAll: { gridColumn: "1 / -1" },
444
+ // ── ce ──────────────────────────────────────────────────────────────────
445
+ ceRow: {
446
+ paddingTop: `${F.rowPaddingTop}px`,
447
+ minWidth: 0
448
+ },
449
+ ceContainer: { containerType: "inline-size" },
450
+ ceGrid: {
451
+ display: "grid",
452
+ alignItems: "start"
453
+ },
454
+ // ★ The column template lives in CLASSES, never in an inline style: an inline
455
+ // grid-template-columns beats the @container rule, so 'auto' never flipped to 'above'
456
+ // (caught measuring a 306px row in a real browser; jsdom cannot see it). A custom labelWidth
457
+ // reaches the class through the --sk-label-col custom property.
458
+ ceGridBeside: { gridTemplateColumns: "var(--sk-label-col) minmax(0, 1fr)" },
459
+ ceGridSingle: { gridTemplateColumns: "minmax(0, 1fr)" },
460
+ ceLabelBeside: {
461
+ display: "flex",
462
+ alignItems: "center",
463
+ minHeight: `${CE_LABEL_BOX}px`,
464
+ marginTop: `${CE_LABEL_OFFSET}px`,
465
+ // 184 − 176: the measured text width. A required marker is allowed into half of it (below).
466
+ paddingRight: `${F.labelColumnWidth - CE_LABEL_TEXT_WIDTH}px`
467
+ },
468
+ ceLabelAbove: {
469
+ display: "flex",
470
+ alignItems: "center",
471
+ marginTop: `${CE_CONTROL_OFFSET}px`,
472
+ minHeight: `${F.labelLineHeight}px`
473
+ },
474
+ ceControlBeside: {
475
+ marginTop: `${CE_CONTROL_OFFSET}px`,
476
+ marginBottom: `${CE_CONTROL_OFFSET}px`,
477
+ marginRight: `${CE_CONTROL_INSET_RIGHT}px`,
478
+ minWidth: 0
479
+ },
480
+ ceControlAbove: {
481
+ marginTop: `${F.labelAboveGap}px`,
482
+ marginBottom: `${CE_CONTROL_OFFSET}px`,
483
+ marginRight: `${CE_CONTROL_INSET_RIGHT}px`,
484
+ minWidth: 0
485
+ },
486
+ // 'auto': beside by default, above when the ROW is narrower than the (provisional) switch point.
487
+ ceAutoGrid: { [NARROW]: { gridTemplateColumns: "minmax(0, 1fr)" } },
488
+ ceAutoLabel: {
489
+ [NARROW]: {
490
+ marginTop: `${CE_CONTROL_OFFSET}px`,
491
+ minHeight: `${F.labelLineHeight}px`,
492
+ paddingRight: 0
493
+ }
494
+ },
495
+ ceAutoControl: { [NARROW]: { marginTop: `${F.labelAboveGap}px` } },
496
+ ceLabelText: {
497
+ minWidth: 0,
498
+ fontSize: import_react_components2.tokens.fontSizeBase300,
499
+ lineHeight: `${F.labelLineHeight}px`,
500
+ fontWeight: import_react_components2.tokens.fontWeightRegular,
501
+ color: import_react_components2.tokens.colorNeutralForeground1,
502
+ overflowWrap: "anywhere"
503
+ },
504
+ // Beside, the text fills the column so the marker sits at the column's end (measured: marker's
505
+ // right edge 180px from the row). Above, the marker follows the text (position unmeasured).
506
+ ceLabelTextFill: { flexGrow: 1 },
507
+ ceAutoLabelText: { [NARROW]: { flexGrow: 0 } },
508
+ ceRequired: {
509
+ flexShrink: 0,
510
+ color: import_react_components2.tokens.colorPaletteRedForeground1,
511
+ paddingLeft: `${CE_MARKER_GAP}px`
512
+ },
513
+ // Beside: the marker takes half the column's 8px padding → text 168.5 + 4 + 7.5 = 176 + 4.
514
+ ceRequiredBeside: { marginRight: `-${CE_MARKER_GAP}px` },
515
+ ceAutoRequired: { [NARROW]: { marginRight: 0 } },
516
+ // ── default ─────────────────────────────────────────────────────────────
517
+ defaultBeside: {
518
+ display: "grid",
519
+ alignItems: "center",
520
+ columnGap: "8px",
521
+ minHeight: "38px",
522
+ [`@media (max-width: ${BREAKPOINTS.sm}px)`]: {
523
+ gridTemplateColumns: "1fr !important",
524
+ alignItems: "flex-start",
525
+ minHeight: 0,
526
+ rowGap: "4px"
527
+ }
528
+ },
529
+ defaultAbove: {
530
+ display: "grid",
531
+ gridTemplateColumns: "1fr",
532
+ rowGap: "2px",
533
+ minHeight: "38px"
534
+ },
535
+ defaultLabel: {
536
+ fontSize: import_react_components2.tokens.fontSizeBase200,
537
+ fontWeight: import_react_components2.tokens.fontWeightSemibold,
538
+ color: import_react_components2.tokens.colorNeutralForeground1,
539
+ lineHeight: "1.3",
540
+ overflowWrap: "anywhere"
541
+ },
542
+ // v8 FieldRow's marker: colors.danger, semibold, 2px after the text.
543
+ defaultRequired: {
544
+ color: import_design_tokens.colors.danger,
545
+ marginLeft: "2px",
546
+ fontWeight: import_react_components2.tokens.fontWeightSemibold
547
+ }
548
+ });
549
+ var toCssLength = (v) => typeof v === "number" ? `${v}px` : v;
550
+ var FieldRow = ({
551
+ label,
552
+ required,
553
+ htmlFor,
554
+ labelPosition,
555
+ labelWidth,
556
+ look: lookProp,
557
+ className,
558
+ style,
559
+ children
560
+ }) => {
561
+ const styles = useStyles2();
562
+ const ambientLook = useLook();
563
+ const look = lookProp ?? ambientLook;
564
+ const ce = look === "ce";
565
+ const position = labelPosition ?? (ce ? "auto" : "beside");
566
+ const hasLabel = label != null;
567
+ const column = toCssLength(labelWidth ?? (ce ? F.labelColumnWidth : 130));
568
+ const LabelTag = htmlFor ? "label" : "span";
569
+ if (!ce) {
570
+ const beside2 = position !== "above" && hasLabel;
571
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
572
+ "div",
573
+ {
574
+ className: (0, import_react_components2.mergeClasses)(styles.spanAll, beside2 ? styles.defaultBeside : styles.defaultAbove, className),
575
+ style: { ...beside2 ? { gridTemplateColumns: `${column} 1fr` } : {}, ...style },
576
+ "data-surface-part": "field-row",
577
+ "data-look": "default",
578
+ children: [
579
+ hasLabel && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(LabelTag, { htmlFor, className: styles.defaultLabel, "data-surface-part": "label", children: [
580
+ label,
581
+ required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: styles.defaultRequired, "aria-hidden": "true", "data-surface-part": "required", children: "*" })
582
+ ] }),
583
+ children
584
+ ]
585
+ }
586
+ );
587
+ }
588
+ const auto = position === "auto" && hasLabel;
589
+ const beside = position !== "above" && hasLabel;
590
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
591
+ "div",
592
+ {
593
+ className: (0, import_react_components2.mergeClasses)(styles.spanAll, styles.ceRow, auto && styles.ceContainer, className),
594
+ style,
595
+ "data-surface-part": "field-row",
596
+ "data-look": "ce",
597
+ "data-label-position": position,
598
+ "data-container": auto ? "inline-size" : void 0,
599
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
600
+ "div",
601
+ {
602
+ className: (0, import_react_components2.mergeClasses)(styles.ceGrid, beside ? styles.ceGridBeside : styles.ceGridSingle, auto && styles.ceAutoGrid),
603
+ style: beside ? { "--sk-label-col": column } : void 0,
604
+ "data-surface-part": "field-grid",
605
+ children: [
606
+ hasLabel && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
607
+ LabelTag,
608
+ {
609
+ htmlFor,
610
+ className: (0, import_react_components2.mergeClasses)(beside ? styles.ceLabelBeside : styles.ceLabelAbove, auto && styles.ceAutoLabel),
611
+ "data-surface-part": "label",
612
+ children: [
613
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
614
+ "span",
615
+ {
616
+ className: (0, import_react_components2.mergeClasses)(styles.ceLabelText, beside && styles.ceLabelTextFill, auto && styles.ceAutoLabelText),
617
+ "data-surface-part": "label-text",
618
+ children: label
619
+ }
620
+ ),
621
+ required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
622
+ "span",
623
+ {
624
+ className: (0, import_react_components2.mergeClasses)(styles.ceRequired, beside && styles.ceRequiredBeside, auto && styles.ceAutoRequired),
625
+ "aria-hidden": "true",
626
+ "data-surface-part": "required",
627
+ children: "*"
628
+ }
629
+ )
630
+ ]
631
+ }
632
+ ),
633
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
634
+ "div",
635
+ {
636
+ className: (0, import_react_components2.mergeClasses)(
637
+ // No label: the control sits where a beside control would (2px down), full width.
638
+ !hasLabel || beside ? styles.ceControlBeside : styles.ceControlAbove,
639
+ auto && styles.ceAutoControl
640
+ ),
641
+ "data-surface-part": "control",
642
+ children
643
+ }
644
+ )
645
+ ]
646
+ }
647
+ )
648
+ }
649
+ );
650
+ };
651
+
652
+ // src/v9/containers/SectionHeader.tsx
653
+ var import_react_components3 = require("@fluentui/react-components");
654
+ var import_react_icons = require("@fluentui/react-icons");
655
+ var import_jsx_runtime4 = require("react/jsx-runtime");
356
656
  var SectionHeader = ({
357
657
  title,
358
658
  statusText,
@@ -361,14 +661,26 @@ var SectionHeader = ({
361
661
  actions,
362
662
  collapsible,
363
663
  collapsed,
364
- onToggle
664
+ onToggle,
665
+ look: lookProp
365
666
  }) => {
667
+ const ambientLook = useLook();
668
+ const ce = (lookProp ?? ambientLook) === "ce";
669
+ const ceRootStyle = {
670
+ display: "flex",
671
+ justifyContent: "space-between",
672
+ alignItems: "center",
673
+ flexWrap: "nowrap",
674
+ paddingTop: import_design_tokens.ceForm.section.titlePaddingTop,
675
+ minHeight: import_design_tokens.ceForm.section.titleHeight - import_design_tokens.ceForm.section.titlePaddingTop,
676
+ width: "100%"
677
+ };
366
678
  const rootStyle = {
367
679
  display: "flex",
368
680
  justifyContent: "space-between",
369
681
  alignItems: "center",
370
682
  flexWrap: "nowrap",
371
- borderBottom: `1px solid ${import_react_components2.tokens.colorNeutralStroke2}`,
683
+ borderBottom: `1px solid ${import_react_components3.tokens.colorNeutralStroke2}`,
372
684
  marginBottom: 16,
373
685
  minHeight: 48,
374
686
  width: "100%"
@@ -376,27 +688,41 @@ var SectionHeader = ({
376
688
  const leftStyle = { display: "flex", alignItems: "center", gap: 8, minWidth: 0 };
377
689
  const statusStyle = {
378
690
  marginLeft: 8,
379
- fontSize: import_react_components2.tokens.fontSizeBase200,
380
- color: import_react_components2.tokens.colorNeutralForeground3
691
+ fontSize: import_react_components3.tokens.fontSizeBase200,
692
+ color: import_react_components3.tokens.colorNeutralForeground3
381
693
  };
382
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: rootStyle, children: [
383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: leftStyle, children: [
384
- collapsible && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
385
- import_react_components2.Button,
694
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: ce ? ceRootStyle : rootStyle, "data-surface-part": "section-header", children: [
695
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: leftStyle, children: [
696
+ collapsible && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
697
+ import_react_components3.Button,
386
698
  {
387
699
  appearance: "subtle",
388
700
  size: "small",
389
- icon: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_icons.ChevronRight20Regular, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_icons.ChevronDown20Regular, {}),
701
+ icon: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_icons.ChevronRight20Regular, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_icons.ChevronDown20Regular, {}),
390
702
  onClick: onToggle,
391
703
  "aria-label": collapsed ? "Expand section" : "Collapse section",
392
704
  "aria-expanded": !collapsed
393
705
  }
394
706
  ),
395
- title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_components2.Text, { weight: "semibold", size: 300, children: title }),
396
- statusText && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: statusStyle, children: statusText })
707
+ title && (ce ? (
708
+ // Rendered exactly as given: Dynamics does not uppercase section titles (the stock
709
+ // Account labels are typed uppercase; "Description" renders mixed-case).
710
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
711
+ import_react_components3.Text,
712
+ {
713
+ as: "h2",
714
+ weight: "semibold",
715
+ size: 300,
716
+ style: { margin: 0, lineHeight: `${import_design_tokens.ceForm.section.titleLineHeight}px`, color: import_react_components3.tokens.colorNeutralForeground1 },
717
+ "data-surface-part": "section-title",
718
+ children: title
719
+ }
720
+ )
721
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_components3.Text, { weight: "semibold", size: 300, children: title })),
722
+ statusText && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: statusStyle, children: statusText })
397
723
  ] }),
398
- actions ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: actions }) : showCommandBar && commandItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_components2.Toolbar, { "aria-label": "Section commands", size: "small", children: commandItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
399
- import_react_components2.ToolbarButton,
724
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { children: actions }) : showCommandBar && commandItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_components3.Toolbar, { "aria-label": "Section commands", size: "small", children: commandItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
725
+ import_react_components3.ToolbarButton,
400
726
  {
401
727
  icon: item.icon,
402
728
  appearance: item.appearance === "primary" ? "primary" : "subtle",
@@ -410,8 +736,18 @@ var SectionHeader = ({
410
736
  };
411
737
 
412
738
  // src/v9/containers/Section.tsx
413
- var import_jsx_runtime4 = require("react/jsx-runtime");
414
- var useStyles2 = (0, import_react_components3.makeStyles)({
739
+ var import_jsx_runtime5 = require("react/jsx-runtime");
740
+ var px = (v) => v.map((n) => `${n}px`).join(" ");
741
+ function columnsOf(children) {
742
+ const out = [];
743
+ const walk = (n) => {
744
+ if (Array.isArray(n)) n.forEach(walk);
745
+ else if (!(n === null || n === void 0 || typeof n === "boolean" || n === "")) out.push(n);
746
+ };
747
+ walk(children);
748
+ return out;
749
+ }
750
+ var useStyles3 = (0, import_react_components4.makeStyles)({
415
751
  // Phone-stack the internal field grid below `sm` (griffel — inline can't do @media).
416
752
  bodyStack: {
417
753
  [`@media (max-width: ${BREAKPOINTS.sm}px)`]: { "& > *": { gridColumn: "1 / -1" } }
@@ -422,7 +758,7 @@ var Section = ({
422
758
  columnSpan = 12,
423
759
  columnStart,
424
760
  rowPosition,
425
- internalColumns = 12,
761
+ internalColumns: internalColumnsProp,
426
762
  showCommandBar,
427
763
  commandItems,
428
764
  statusText,
@@ -434,12 +770,16 @@ var Section = ({
434
770
  variant = "card",
435
771
  minHeight = 80,
436
772
  density: densityProp,
773
+ look: lookProp,
437
774
  className,
438
775
  style,
439
776
  children
440
777
  }) => {
441
- const styles = useStyles2();
442
- const [internalCollapsed, setInternalCollapsed] = (0, import_react5.useState)(defaultCollapsed);
778
+ const styles = useStyles3();
779
+ const internalColumns = internalColumnsProp ?? 12;
780
+ const ambientLook = useLook();
781
+ const ce = (lookProp ?? ambientLook) === "ce" && variant === "card";
782
+ const [internalCollapsed, setInternalCollapsed] = (0, import_react6.useState)(defaultCollapsed);
443
783
  const collapsed = controlledCollapsed ?? internalCollapsed;
444
784
  const toggle = () => {
445
785
  const next = !collapsed;
@@ -459,41 +799,102 @@ var Section = ({
459
799
  if (variant === "placeholder") {
460
800
  const placeholderStyle = {
461
801
  ...rootStyle,
462
- border: `1px dashed ${import_react_components3.tokens.colorNeutralStroke2}`,
463
- borderRadius: import_react_components3.tokens.borderRadiusMedium,
802
+ border: `1px dashed ${import_react_components4.tokens.colorNeutralStroke2}`,
803
+ borderRadius: import_react_components4.tokens.borderRadiusMedium,
464
804
  minHeight,
465
805
  width: "100%",
466
806
  background: "transparent"
467
807
  };
468
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className, style: placeholderStyle });
808
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className, style: placeholderStyle });
469
809
  }
470
810
  const chrome = variant === "flat" ? {
471
- backgroundColor: import_react_components3.tokens.colorNeutralBackground1,
472
- borderRadius: import_react_components3.tokens.borderRadiusMedium,
811
+ backgroundColor: import_react_components4.tokens.colorNeutralBackground1,
812
+ borderRadius: import_react_components4.tokens.borderRadiusMedium,
473
813
  padding: cardPad,
474
814
  minWidth: 300,
475
815
  width: "100%",
476
816
  overflow: "hidden"
477
817
  } : {
478
- backgroundColor: import_react_components3.tokens.colorNeutralBackground1,
479
- border: `1px solid ${import_react_components3.tokens.colorNeutralStroke2}`,
480
- borderRadius: import_react_components3.tokens.borderRadiusMedium,
481
- boxShadow: import_react_components3.tokens.shadow4,
818
+ backgroundColor: import_react_components4.tokens.colorNeutralBackground1,
819
+ border: `1px solid ${import_react_components4.tokens.colorNeutralStroke2}`,
820
+ borderRadius: import_react_components4.tokens.borderRadiusMedium,
821
+ boxShadow: import_react_components4.tokens.shadow4,
482
822
  padding: cardPad,
483
823
  minWidth: 300,
484
824
  width: "100%",
485
825
  overflow: "hidden"
486
826
  };
487
827
  const showHeader = Boolean(title) || showCommandBar || collapsible;
828
+ if (ce) {
829
+ const n = Math.max(1, Math.round(internalColumnsProp ?? 1));
830
+ const ceChrome = {
831
+ backgroundColor: import_react_components4.tokens.colorNeutralBackground1,
832
+ border: "1px solid transparent",
833
+ borderRadius: import_react_components4.tokens.borderRadiusXLarge,
834
+ boxShadow: import_react_components4.tokens.shadow4,
835
+ padding: px(import_design_tokens.ceForm.section.padding),
836
+ width: "100%",
837
+ boxSizing: "border-box"
838
+ };
839
+ const cols = n > 1 ? columnsOf(children) : null;
840
+ if (cols && cols.length !== n && typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
841
+ console.warn(
842
+ `[surface-kit] Section look="ce" with internalColumns={${n}} got ${cols.length} children. A multi-column CE section takes ONE CHILD PER COLUMN (wrap each column's FieldRows in an element).`
843
+ );
844
+ }
845
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className, style: { ...ceChrome, ...rootStyle }, "data-surface-part": "section", "data-look": "ce", children: [
846
+ notification && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: notification }),
847
+ showHeader && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
848
+ SectionHeader,
849
+ {
850
+ look: "ce",
851
+ title,
852
+ statusText,
853
+ showCommandBar,
854
+ commandItems,
855
+ collapsible,
856
+ collapsed,
857
+ onToggle: toggle
858
+ }
859
+ ),
860
+ !collapsed && (cols ? (
861
+ // PROVISIONAL: below the phone breakpoint the columns stack (the default look's rule);
862
+ // Dynamics' multi-column reflow is unmeasured.
863
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
864
+ "div",
865
+ {
866
+ className: styles.bodyStack,
867
+ style: { display: "grid", gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))`, alignItems: "start" },
868
+ "data-surface-part": "section-body",
869
+ children: cols.map((col, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
870
+ "div",
871
+ {
872
+ style: {
873
+ // Keyed to the COLUMN (i % n), not the list position: every column but the
874
+ // last carries the gutter, and only the first grid row is pulled up.
875
+ marginTop: i < n ? -ceFieldRowFirstOffset : 0,
876
+ paddingRight: i % n < n - 1 ? import_design_tokens.ceForm.section.columnGutter : 0,
877
+ minWidth: 0
878
+ },
879
+ "data-surface-part": "section-column",
880
+ children: col
881
+ },
882
+ import_react6.default.isValidElement(col) && col.key != null ? col.key : `col-${i}`
883
+ ))
884
+ }
885
+ )
886
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { marginTop: -ceFieldRowFirstOffset }, "data-surface-part": "section-body", children }))
887
+ ] });
888
+ }
488
889
  const bodyStyle = {
489
890
  display: "grid",
490
891
  gridTemplateColumns: `repeat(${internalColumns}, 1fr)`,
491
892
  gap: bodyGap,
492
893
  alignItems: "start"
493
894
  };
494
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className, style: { ...chrome, ...rootStyle }, children: [
495
- notification && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginBottom: scaleSpacing(8, density) }, children: notification }),
496
- showHeader && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
895
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className, style: { ...chrome, ...rootStyle }, children: [
896
+ notification && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { marginBottom: scaleSpacing(8, density) }, children: notification }),
897
+ showHeader && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
497
898
  SectionHeader,
498
899
  {
499
900
  title,
@@ -505,20 +906,20 @@ var Section = ({
505
906
  onToggle: toggle
506
907
  }
507
908
  ),
508
- !collapsed && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: (0, import_react_components3.mergeClasses)(styles.bodyStack), style: bodyStyle, children })
909
+ !collapsed && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: (0, import_react_components4.mergeClasses)(styles.bodyStack), style: bodyStyle, children })
509
910
  ] });
510
911
  };
511
912
 
512
913
  // src/v9/containers/SectionCard.tsx
513
- var import_react_components4 = require("@fluentui/react-components");
514
- var import_jsx_runtime5 = require("react/jsx-runtime");
914
+ var import_react_components5 = require("@fluentui/react-components");
915
+ var import_jsx_runtime6 = require("react/jsx-runtime");
515
916
  var SectionCard = ({
516
- accentColor = import_react_components4.tokens.colorBrandStroke1,
917
+ accentColor = import_react_components5.tokens.colorBrandStroke1,
517
918
  accentWidth = 3,
518
919
  variant = "card",
519
920
  style,
520
921
  ...rest
521
- }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
922
+ }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
522
923
  Section,
523
924
  {
524
925
  variant,
@@ -528,54 +929,345 @@ var SectionCard = ({
528
929
  );
529
930
 
530
931
  // src/v9/containers/FormHeader.tsx
531
- var import_react_components5 = require("@fluentui/react-components");
532
- var import_jsx_runtime6 = require("react/jsx-runtime");
533
- var FormHeader = ({
534
- title,
535
- subtitle,
536
- status,
537
- titleColor,
538
- subtitleColor,
539
- persona,
540
- actions,
541
- className
542
- }) => {
932
+ var import_react7 = __toESM(require("react"), 1);
933
+ var import_react_components6 = require("@fluentui/react-components");
934
+ var import_react_icons2 = require("@fluentui/react-icons");
935
+ var import_jsx_runtime7 = require("react/jsx-runtime");
936
+ var H = import_design_tokens.ceForm.header;
937
+ var FIELD_TOP = 4;
938
+ var OWNER_AVATAR_TOP = 9;
939
+ var OWNER_NAME_GAP = 10;
940
+ var SUBTITLE_DOT_SPACING = 8;
941
+ var SUBTITLE_ROW_TOP = 0;
942
+ var EXPAND_GAP = 18;
943
+ var DIVIDER_TOP = 6;
944
+ var PRESENCE_RING = 2;
945
+ var PRESENCE_DOT = H.presenceSize - 2 * PRESENCE_RING;
946
+ var cePresenceBadgeStyle = Object.freeze({
947
+ width: PRESENCE_DOT,
948
+ height: PRESENCE_DOT,
949
+ boxSizing: "content-box",
950
+ // Fluent's badge carries 1px padding and a 10px icon; zero the padding and clip the icon to the dot.
951
+ padding: 0,
952
+ overflow: "hidden",
953
+ border: `${PRESENCE_RING}px solid ${import_react_components6.tokens.colorNeutralBackground1}`,
954
+ right: -PRESENCE_RING,
955
+ bottom: -PRESENCE_RING
956
+ });
957
+ var FIELDS_MIN_GAP = 16;
958
+ var CE_TITLE_MIN_WIDTH = 120;
959
+ var useStyles4 = (0, import_react_components6.makeStyles)({
960
+ // The owner name as a link-button: no chrome, but a VISIBLE keyboard focus ring (Fluent's).
961
+ ownerLink: {
962
+ background: "none",
963
+ border: "none",
964
+ padding: 0,
965
+ margin: 0,
966
+ font: "inherit",
967
+ color: import_react_components6.tokens.colorBrandForegroundLink,
968
+ cursor: "pointer",
969
+ ":hover": { color: import_react_components6.tokens.colorBrandForegroundLinkHover, textDecorationLine: "underline" },
970
+ ...(0, import_react_components6.createFocusOutlineStyle)()
971
+ },
972
+ // Narrow headers: the title keeps a minimum width (it truncates with an ellipsis) and the fields
973
+ // block shrinks and clips rather than pushing past the card. Dynamics moves the fields into the
974
+ // header flyout at narrow widths (unmeasured, not modelled).
975
+ fields: {
976
+ display: "flex",
977
+ alignItems: "flex-start",
978
+ flexShrink: 1,
979
+ minWidth: 0,
980
+ overflow: "hidden"
981
+ },
982
+ switcher: {
983
+ display: "inline-flex",
984
+ alignItems: "center",
985
+ // Measured switcher 74.3 wide for "Account" (52.3): 2×2 padding + 2×1 border + 4 gap + 12 icon.
986
+ gap: "4px",
987
+ height: `${H.switcherHeight}px`,
988
+ padding: `0 ${H.switcherPaddingX}px`,
989
+ border: "1px solid transparent",
990
+ borderRadius: import_react_components6.tokens.borderRadiusMedium,
991
+ background: "transparent",
992
+ color: import_react_components6.tokens.colorNeutralForeground2,
993
+ fontFamily: "inherit",
994
+ fontSize: import_react_components6.tokens.fontSizeBase300,
995
+ fontWeight: import_react_components6.tokens.fontWeightSemibold,
996
+ lineHeight: import_react_components6.tokens.lineHeightBase300,
997
+ cursor: "pointer",
998
+ ":hover": { backgroundColor: import_react_components6.tokens.colorSubtleBackgroundHover },
999
+ ...(0, import_react_components6.createFocusOutlineStyle)(),
1000
+ // Measured OPEN: fill #e0e0e0 = colorSubtleBackgroundPressed (Fluent's MenuButton would use
1001
+ // Selected, #ebebeb — so this is set explicitly) and text #242424 = colorNeutralForeground1
1002
+ // (idle is #424242). ★ The open state must also win over :hover — the pointer is still on the
1003
+ // trigger after the click that opened it, and hover's #f5f5f5 was what showed. The ce-parity
1004
+ // gate checks the open trigger with the pointer on it AND away from it.
1005
+ '&[aria-expanded="true"], &[aria-expanded="true"]:hover': {
1006
+ backgroundColor: import_react_components6.tokens.colorSubtleBackgroundPressed,
1007
+ color: import_react_components6.tokens.colorNeutralForeground1
1008
+ }
1009
+ }
1010
+ });
1011
+ var isEmpty = (v) => v === null || v === void 0 || v === "";
1012
+ function FieldTile({ field }) {
1013
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", paddingTop: FIELD_TOP, minWidth: 0 }, "data-surface-part": "header-field", children: [
1014
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.Text, { weight: "semibold", size: 300, wrap: false, style: { color: import_react_components6.tokens.colorNeutralForeground1 }, "data-surface-part": "header-field-value", children: isEmpty(field.value) ? "---" : field.value }),
1015
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.Text, { size: 200, wrap: false, style: { color: import_react_components6.tokens.colorNeutralForeground1 }, "data-surface-part": "header-field-label", children: field.label })
1016
+ ] });
1017
+ }
1018
+ function Divider() {
1019
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1020
+ "div",
1021
+ {
1022
+ "aria-hidden": "true",
1023
+ style: {
1024
+ width: H.dividerWidth,
1025
+ height: H.dividerHeight,
1026
+ margin: `${DIVIDER_TOP}px ${H.dividerSpacing}px 0`,
1027
+ backgroundColor: import_react_components6.tokens.colorNeutralStroke2,
1028
+ flexShrink: 0
1029
+ },
1030
+ "data-surface-part": "header-divider"
1031
+ }
1032
+ );
1033
+ }
1034
+ function CeFormHeader(props) {
1035
+ const {
1036
+ title,
1037
+ subtitle,
1038
+ status,
1039
+ titleColor,
1040
+ persona,
1041
+ actions,
1042
+ className,
1043
+ entityName,
1044
+ forms,
1045
+ activeFormId,
1046
+ onFormChange,
1047
+ headerFields,
1048
+ owner,
1049
+ onExpand,
1050
+ expanded,
1051
+ titleAs
1052
+ } = props;
1053
+ const styles = useStyles4();
1054
+ const activeForm = forms?.find((f) => f.id === activeFormId) ?? forms?.[0];
1055
+ const entity = entityName ?? subtitle;
1056
+ const avatar = persona ?? (typeof title === "string" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.Avatar, { name: title, color: "colorful", size: H.avatarSize, "aria-hidden": true }) : null);
1057
+ const TitleTag = titleAs ?? "h1";
1058
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1059
+ "div",
1060
+ {
1061
+ className,
1062
+ style: { display: "flex", alignItems: "flex-start", padding: H.padding.map((v) => `${v}px`).join(" "), minWidth: 0 },
1063
+ "data-surface-part": "form-header",
1064
+ "data-look": "ce",
1065
+ children: [
1066
+ avatar && // The avatar sits in a 2px transparent ring (tile 44 = 40 + 2 × 2), 14px before the title.
1067
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { padding: H.avatarRing, marginRight: H.avatarToTitleGap, flexShrink: 0 }, "data-surface-part": "header-avatar", children: avatar }),
1068
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { minWidth: CE_TITLE_MIN_WIDTH, flex: "1 1 auto" }, children: [
1069
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "baseline", minWidth: 0 }, children: [
1070
+ title != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1071
+ import_react_components6.Text,
1072
+ {
1073
+ as: TitleTag,
1074
+ weight: "semibold",
1075
+ size: 500,
1076
+ truncate: true,
1077
+ wrap: false,
1078
+ style: { margin: 0, lineHeight: `${H.titleLineHeight}px`, color: titleColor ?? import_react_components6.tokens.colorNeutralForeground1 },
1079
+ "data-surface-part": "header-title",
1080
+ children: title
1081
+ }
1082
+ ),
1083
+ status != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1084
+ "span",
1085
+ {
1086
+ style: {
1087
+ paddingLeft: H.statusPaddingLeft,
1088
+ fontSize: import_react_components6.tokens.fontSizeBase300,
1089
+ lineHeight: `${H.titleLineHeight}px`,
1090
+ color: import_react_components6.tokens.colorNeutralForeground3,
1091
+ whiteSpace: "nowrap"
1092
+ },
1093
+ "data-surface-part": "header-status",
1094
+ children: [
1095
+ "- ",
1096
+ status
1097
+ ]
1098
+ }
1099
+ )
1100
+ ] }),
1101
+ (entity != null || activeForm) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", height: H.switcherHeight, marginTop: SUBTITLE_ROW_TOP }, "data-surface-part": "header-subtitle", children: [
1102
+ entity != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: import_react_components6.tokens.fontSizeBase300, fontWeight: import_react_components6.tokens.fontWeightSemibold, color: import_react_components6.tokens.colorNeutralForeground2 }, children: entity }),
1103
+ entity != null && activeForm && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", style: { margin: `0 ${SUBTITLE_DOT_SPACING}px`, color: import_react_components6.tokens.colorNeutralForeground2, lineHeight: "20px" }, children: "\xB7" }),
1104
+ activeForm && (forms && forms.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1105
+ import_react_components6.Menu,
1106
+ {
1107
+ checkedValues: { form: [activeForm.id] },
1108
+ onCheckedValueChange: (_e, data) => {
1109
+ const id = data.checkedItems[0];
1110
+ if (id && id !== activeForm.id) onFormChange?.(id);
1111
+ },
1112
+ children: [
1113
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.MenuTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: styles.switcher, "aria-label": `Form: ${activeForm.label}`, "data-surface-part": "form-switcher", children: [
1114
+ activeForm.label,
1115
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_icons2.ChevronDown12Regular, {})
1116
+ ] }) }),
1117
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.MenuPopover, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.MenuList, { children: forms.map((f) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.MenuItemRadio, { name: "form", value: f.id, children: f.label }, f.id)) }) })
1118
+ ]
1119
+ }
1120
+ ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: import_react_components6.tokens.fontSizeBase300, fontWeight: import_react_components6.tokens.fontWeightSemibold, color: import_react_components6.tokens.colorNeutralForeground2 }, children: activeForm.label }))
1121
+ ] })
1122
+ ] }),
1123
+ (headerFields?.length || owner || actions) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: styles.fields, style: { marginLeft: FIELDS_MIN_GAP }, "data-surface-part": "header-fields", children: [
1124
+ headerFields?.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react7.default.Fragment, { children: [
1125
+ i > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Divider, {}),
1126
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldTile, { field: f })
1127
+ ] }, f.id ?? `${f.label}-${i}`)),
1128
+ owner && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1129
+ headerFields?.length ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Divider, {}) : null,
1130
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "flex-start" }, "data-surface-part": "header-owner", children: [
1131
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { paddingTop: OWNER_AVATAR_TOP, marginRight: OWNER_NAME_GAP }, children: owner.avatar ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1132
+ import_react_components6.Avatar,
1133
+ {
1134
+ name: owner.name,
1135
+ color: "colorful",
1136
+ size: H.ownerAvatarSize,
1137
+ badge: owner.presence ? { status: owner.presence, size: "extra-small", style: cePresenceBadgeStyle } : void 0
1138
+ }
1139
+ ) }),
1140
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1141
+ FieldTile,
1142
+ {
1143
+ field: {
1144
+ label: owner.label ?? "Owner",
1145
+ value: owner.onClick ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: owner.onClick, className: styles.ownerLink, "data-surface-part": "header-owner-link", children: owner.name }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { color: import_react_components6.tokens.colorBrandForegroundLink }, children: owner.name })
1146
+ }
1147
+ }
1148
+ )
1149
+ ] })
1150
+ ] }),
1151
+ actions != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: actions })
1152
+ ] }),
1153
+ onExpand && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1154
+ import_react_components6.Button,
1155
+ {
1156
+ appearance: "subtle",
1157
+ icon: expanded ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_icons2.ChevronUp20Regular, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_icons2.ChevronDown20Regular, {}),
1158
+ "aria-label": expanded ? "Collapse header" : "Expand header",
1159
+ "aria-expanded": !!expanded,
1160
+ onClick: onExpand,
1161
+ style: { marginLeft: EXPAND_GAP, flexShrink: 0, minWidth: H.expandButtonSize, width: H.expandButtonSize, height: H.expandButtonSize },
1162
+ "data-surface-part": "header-expand"
1163
+ }
1164
+ )
1165
+ ]
1166
+ }
1167
+ );
1168
+ }
1169
+ var FormHeader = (props) => {
1170
+ const ambientLook = useLook();
1171
+ if ((props.look ?? ambientLook) === "ce") return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CeFormHeader, { ...props });
1172
+ const { title, subtitle, status, titleColor, subtitleColor, persona, actions, className } = props;
543
1173
  const rootStyle = {
544
1174
  display: "flex",
545
1175
  alignItems: "center",
546
1176
  justifyContent: "space-between",
547
1177
  gap: 12,
548
1178
  padding: "12px 24px",
549
- borderBottom: `1px solid ${import_react_components5.tokens.colorNeutralStroke2}`,
550
- backgroundColor: import_react_components5.tokens.colorNeutralBackground1
1179
+ borderBottom: `1px solid ${import_react_components6.tokens.colorNeutralStroke2}`,
1180
+ backgroundColor: import_react_components6.tokens.colorNeutralBackground1
551
1181
  };
552
1182
  const mainStyle = { display: "flex", alignItems: "center", gap: 12, minWidth: 0 };
553
1183
  const titleRowStyle = { display: "flex", alignItems: "baseline", gap: 8, flexWrap: "wrap" };
554
- const statusStyle = { fontSize: import_react_components5.tokens.fontSizeBase200, color: import_react_components5.tokens.colorNeutralForeground3 };
1184
+ const statusStyle = { fontSize: import_react_components6.tokens.fontSizeBase200, color: import_react_components6.tokens.colorNeutralForeground3 };
555
1185
  const subtitleStyle = {
556
- fontSize: import_react_components5.tokens.fontSizeBase200,
557
- color: subtitleColor || import_react_components5.tokens.colorNeutralForeground3,
1186
+ fontSize: import_react_components6.tokens.fontSizeBase200,
1187
+ color: subtitleColor || import_react_components6.tokens.colorNeutralForeground3,
558
1188
  marginTop: 2
559
1189
  };
560
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className, style: rootStyle, children: [
561
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: mainStyle, children: [
1190
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className, style: rootStyle, children: [
1191
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: mainStyle, children: [
562
1192
  persona,
563
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
564
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: titleRowStyle, children: [
565
- title != null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_components5.Text, { weight: "semibold", size: 400, style: titleColor ? { color: titleColor } : void 0, children: title }),
566
- status != null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: statusStyle, children: status })
1193
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
1194
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: titleRowStyle, children: [
1195
+ title != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.Text, { weight: "semibold", size: 400, style: titleColor ? { color: titleColor } : void 0, children: title }),
1196
+ status != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: statusStyle, children: status })
567
1197
  ] }),
568
- subtitle != null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: subtitleStyle, children: subtitle })
1198
+ subtitle != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: subtitleStyle, children: subtitle })
569
1199
  ] })
570
1200
  ] }),
571
- actions != null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: actions })
1201
+ actions != null && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: actions })
572
1202
  ] });
573
1203
  };
574
1204
 
575
1205
  // src/v9/containers/PivotSurface.tsx
576
- var import_react6 = require("react");
577
- var import_react_components6 = require("@fluentui/react-components");
578
- var import_jsx_runtime7 = require("react/jsx-runtime");
1206
+ var import_react8 = require("react");
1207
+ var import_react_components7 = require("@fluentui/react-components");
1208
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1209
+ var FLUENT_TAB_RESERVED_SPACE_CLASS = "fui-Tab__content--reserved-space";
1210
+ var T = import_design_tokens.ceForm.tabs;
1211
+ var UNDERLINE_BOTTOM = 5;
1212
+ var useStyles5 = (0, import_react_components7.makeStyles)({
1213
+ ceCard: {
1214
+ minWidth: 0,
1215
+ backgroundColor: import_react_components7.tokens.colorNeutralBackground1,
1216
+ border: "1px solid transparent",
1217
+ borderRadius: import_react_components7.tokens.borderRadiusXLarge,
1218
+ boxShadow: import_react_components7.tokens.shadow4
1219
+ },
1220
+ ceStrip: {
1221
+ padding: T.stripPadding.map((v) => `${v}px`).join(" "),
1222
+ columnGap: `${T.gap}px`,
1223
+ // PROVISIONAL: tabs that don't fit are clipped. Dynamics folds them into a "Related ▾" /
1224
+ // overflow menu, which is unmeasured and not modelled.
1225
+ overflow: "hidden"
1226
+ },
1227
+ ceTab: {
1228
+ height: `${T.tabHeight}px`,
1229
+ padding: `0 0 ${UNDERLINE_BOTTOM}px`,
1230
+ alignItems: "flex-end",
1231
+ fontSize: `${T.fontSize}px`,
1232
+ lineHeight: `${T.lineHeight}px`,
1233
+ color: import_react_components7.tokens.colorNeutralForeground1,
1234
+ [`& .${import_react_components7.tabClassNames.content}`]: {
1235
+ padding: 0,
1236
+ fontSize: `${T.fontSize}px`,
1237
+ lineHeight: `${T.lineHeight}px`,
1238
+ // Idle labels are the measured #242424 too (Fluent's transparent appearance would use
1239
+ // foreground2, #424242).
1240
+ color: import_react_components7.tokens.colorNeutralForeground1
1241
+ },
1242
+ // Dynamics, like Fluent, reserves each tab's SEMIBOLD width (a hidden zero-height copy of the
1243
+ // label), so tabs don't shift on selection: an unselected "Web API Probe" is 109.6 wide, its
1244
+ // semibold width in the same Segoe UI Web file. Fluent's reserved copy keeps its own 2px side
1245
+ // padding, which made it 113.6 — zero it like the visible content.
1246
+ [`& .${FLUENT_TAB_RESERVED_SPACE_CLASS}`]: {
1247
+ padding: 0,
1248
+ fontSize: `${T.fontSize}px`
1249
+ },
1250
+ // Fluent draws the selected (and hover) indicator on ::after / ::before; move both to the
1251
+ // measured position and shape.
1252
+ "::after": {
1253
+ left: 0,
1254
+ right: 0,
1255
+ bottom: `${UNDERLINE_BOTTOM}px`,
1256
+ height: `${T.underlineHeight}px`,
1257
+ borderRadius: `${T.underlineRadius}px`
1258
+ },
1259
+ "::before": {
1260
+ left: 0,
1261
+ right: 0,
1262
+ bottom: `${UNDERLINE_BOTTOM}px`,
1263
+ height: `${T.underlineHeight}px`,
1264
+ borderRadius: `${T.underlineRadius}px`
1265
+ },
1266
+ // Fluent's hover/pressed indicator sets a circular radius at higher specificity; match it.
1267
+ ":hover::before": { borderRadius: `${T.underlineRadius}px` },
1268
+ ":active::before": { borderRadius: `${T.underlineRadius}px` }
1269
+ }
1270
+ });
579
1271
  var PivotSurface = ({
580
1272
  tabs,
581
1273
  selectedId,
@@ -583,10 +1275,17 @@ var PivotSurface = ({
583
1275
  onTabChange,
584
1276
  appearance = "transparent",
585
1277
  size = "medium",
586
- className
1278
+ className,
1279
+ look: lookProp,
1280
+ header
587
1281
  }) => {
1282
+ const styles = useStyles5();
1283
+ const ce = lookProp === "ce";
1284
+ const baseId = (0, import_react8.useId)();
1285
+ const tabId = (id) => `${baseId}-tab-${id}`;
1286
+ const panelId = `${baseId}-panel`;
588
1287
  const firstEnabledId = tabs.find((t) => !t.disabled)?.id ?? tabs[0]?.id;
589
- const [internal, setInternal] = (0, import_react6.useState)(defaultSelectedId ?? firstEnabledId);
1288
+ const [internal, setInternal] = (0, import_react8.useState)(defaultSelectedId ?? firstEnabledId);
590
1289
  const selected = selectedId ?? internal;
591
1290
  const handleSelect = (_e, data) => {
592
1291
  const id = String(data.value);
@@ -594,58 +1293,411 @@ var PivotSurface = ({
594
1293
  onTabChange?.(id);
595
1294
  };
596
1295
  const active = tabs.find((t) => t.id === selected) ?? tabs[0];
597
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className, children: [
598
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.TabList, { selectedValue: selected, onTabSelect: handleSelect, appearance, size, children: tabs.map((t) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_components6.Tab, { value: t.id, icon: t.icon, disabled: t.disabled, children: t.label }, t.id)) }),
599
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: active?.content })
1296
+ if (ce) {
1297
+ const [bodyTop, , bodyBottom] = import_design_tokens.ceForm.tabBody.padding;
1298
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1299
+ "div",
1300
+ {
1301
+ className,
1302
+ style: { padding: `0 ${import_design_tokens.ceForm.page.insetRight}px 0 ${import_design_tokens.ceForm.page.insetLeft}px`, minWidth: 0 },
1303
+ "data-surface-part": "pivot",
1304
+ "data-look": "ce",
1305
+ children: [
1306
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: styles.ceCard, "data-surface-part": "header-card", children: [
1307
+ header,
1308
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1309
+ import_react_components7.TabList,
1310
+ {
1311
+ className: styles.ceStrip,
1312
+ selectedValue: selected,
1313
+ onTabSelect: handleSelect,
1314
+ appearance: "transparent",
1315
+ size: "large",
1316
+ "data-surface-part": "tab-strip",
1317
+ children: tabs.map((t) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1318
+ import_react_components7.Tab,
1319
+ {
1320
+ value: t.id,
1321
+ icon: t.icon,
1322
+ disabled: t.disabled,
1323
+ className: styles.ceTab,
1324
+ id: tabId(t.id),
1325
+ "aria-controls": t.id === active?.id ? panelId : void 0,
1326
+ children: t.label
1327
+ },
1328
+ t.id
1329
+ ))
1330
+ }
1331
+ )
1332
+ ] }),
1333
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1334
+ "div",
1335
+ {
1336
+ role: "tabpanel",
1337
+ id: panelId,
1338
+ "aria-labelledby": active ? tabId(active.id) : void 0,
1339
+ style: { paddingTop: bodyTop, paddingBottom: bodyBottom },
1340
+ "data-surface-part": "tab-body",
1341
+ children: active?.content
1342
+ }
1343
+ )
1344
+ ]
1345
+ }
1346
+ );
1347
+ }
1348
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className, children: [
1349
+ header,
1350
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_components7.TabList, { selectedValue: selected, onTabSelect: handleSelect, appearance, size, children: tabs.map((t) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1351
+ import_react_components7.Tab,
1352
+ {
1353
+ value: t.id,
1354
+ icon: t.icon,
1355
+ disabled: t.disabled,
1356
+ id: tabId(t.id),
1357
+ "aria-controls": t.id === active?.id ? panelId : void 0,
1358
+ children: t.label
1359
+ },
1360
+ t.id
1361
+ )) }),
1362
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { role: "tabpanel", id: panelId, "aria-labelledby": active ? tabId(active.id) : void 0, "data-surface-part": "tab-body", children: active?.content })
600
1363
  ] });
601
1364
  };
602
1365
 
603
1366
  // src/v9/containers/CommandSurface.tsx
604
- var import_react_components7 = require("@fluentui/react-components");
605
- var import_react_icons2 = require("@fluentui/react-icons");
606
- var import_jsx_runtime8 = require("react/jsx-runtime");
1367
+ var import_react9 = __toESM(require("react"), 1);
1368
+ var import_react_components8 = require("@fluentui/react-components");
1369
+ var import_react_icons3 = require("@fluentui/react-icons");
1370
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1371
+ function ItemMenu({ items, trigger }) {
1372
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_components8.Menu, { children: [
1373
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.MenuTrigger, { disableButtonEnhancement: true, children: trigger }),
1374
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.MenuPopover, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.MenuList, { children: items.map((m) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.MenuItem, { icon: m.icon, disabled: m.disabled, onClick: m.onClick, children: m.label }, m.id)) }) })
1375
+ ] });
1376
+ }
607
1377
  function renderToolbarButton(item) {
608
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
609
- import_react_components7.ToolbarButton,
1378
+ const button = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1379
+ import_react_components8.ToolbarButton,
610
1380
  {
611
1381
  icon: item.icon,
612
1382
  appearance: item.appearance === "primary" ? "primary" : "subtle",
613
1383
  disabled: item.disabled,
614
- onClick: item.onClick,
1384
+ onClick: item.menuItems?.length ? void 0 : item.onClick,
615
1385
  children: item.label
616
1386
  },
617
1387
  item.id
618
1388
  );
1389
+ if (!item.menuItems?.length) return button;
1390
+ if (!item.split) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ItemMenu, { items: item.menuItems, trigger: button }, item.id);
1391
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react9.default.Fragment, { children: [
1392
+ import_react9.default.cloneElement(button, { onClick: item.onClick }),
1393
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1394
+ ItemMenu,
1395
+ {
1396
+ items: item.menuItems,
1397
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1398
+ import_react_components8.ToolbarButton,
1399
+ {
1400
+ appearance: "subtle",
1401
+ "aria-label": `More ${item.label} options`,
1402
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_icons3.ChevronDown16Regular, {}),
1403
+ disabled: item.disabled
1404
+ }
1405
+ )
1406
+ }
1407
+ )
1408
+ ] }, item.id);
619
1409
  }
620
- var CommandSurface = ({
621
- items,
622
- overflowItems,
623
- farItems,
624
- size = "small",
625
- className
626
- }) => {
1410
+ var CB = import_design_tokens.ceForm.commandBar;
1411
+ var FLUENT_BORDER = 1;
1412
+ var FOCUS_ROOM = 2;
1413
+ var useStyles6 = (0, import_react_components8.makeStyles)({
1414
+ root: {
1415
+ minWidth: 0,
1416
+ // Page insets (16 left / 20 right), 8px from the top, 16px gap to the header card. A class
1417
+ // (not an inline style) so a host's className can override it.
1418
+ padding: `${CB.marginTop}px ${import_design_tokens.ceForm.page.insetRight}px ${import_design_tokens.ceForm.header.marginTop}px ${import_design_tokens.ceForm.page.commandBarInsetLeft}px`
1419
+ },
1420
+ card: {
1421
+ display: "flex",
1422
+ alignItems: "center",
1423
+ minWidth: 0,
1424
+ boxSizing: "border-box",
1425
+ height: `${CB.cardHeight}px`,
1426
+ backgroundColor: import_react_components8.tokens.colorNeutralBackground1,
1427
+ border: "1px solid transparent",
1428
+ borderRadius: import_react_components8.tokens.borderRadiusXLarge,
1429
+ boxShadow: import_react_components8.tokens.shadow4
1430
+ },
1431
+ group: { display: "flex", alignItems: "center", flexShrink: 0 },
1432
+ nav: { marginLeft: `${CB.navInsetLeft}px` },
1433
+ navButton: {
1434
+ height: `${CB.buttonHeight}px`,
1435
+ minWidth: 0,
1436
+ // Fluent caps icon-only buttons at 32px; the measured back/pop-out/overflow are wider.
1437
+ maxWidth: "none",
1438
+ padding: 0,
1439
+ flexShrink: 0
1440
+ },
1441
+ divider: {
1442
+ flexGrow: 0,
1443
+ height: `${CB.dividerHeight}px`,
1444
+ padding: 0,
1445
+ // Measured line colour #d1d1d1 = colorNeutralStroke1 (ToolbarDivider has no `appearance`
1446
+ // prop, so the Divider's pseudo-element halves are recoloured; both sides, for RTL).
1447
+ "::before": { borderRightColor: import_react_components8.tokens.colorNeutralStroke1, borderLeftColor: import_react_components8.tokens.colorNeutralStroke1 },
1448
+ "::after": { borderRightColor: import_react_components8.tokens.colorNeutralStroke1, borderLeftColor: import_react_components8.tokens.colorNeutralStroke1 }
1449
+ },
1450
+ splitDivider: { height: `${CB.splitDividerHeight}px` },
1451
+ commands: {
1452
+ flex: "1 1 auto",
1453
+ minWidth: 0,
1454
+ columnGap: 0,
1455
+ // Commands past the edge are clipped (Dynamics folds them into ⋮ by an unmeasured rule — pass
1456
+ // overflowItems). The FOCUS_ROOM padding/negative margin keeps forced-colors outlines visible.
1457
+ overflow: "hidden",
1458
+ padding: `${FOCUS_ROOM}px ${CB.commandsPaddingRight}px ${FOCUS_ROOM}px ${FOCUS_ROOM}px`,
1459
+ margin: `-${FOCUS_ROOM}px 0 -${FOCUS_ROOM}px -${FOCUS_ROOM}px`
1460
+ },
1461
+ command: {
1462
+ height: `${CB.buttonHeight}px`,
1463
+ minWidth: 0,
1464
+ flexShrink: 0,
1465
+ padding: `1px ${CB.buttonPaddingX - FLUENT_BORDER}px`,
1466
+ fontSize: import_react_components8.tokens.fontSizeBase300,
1467
+ fontWeight: import_react_components8.tokens.fontWeightRegular,
1468
+ lineHeight: "21px",
1469
+ [`& .${import_react_components8.buttonClassNames.icon}`]: {
1470
+ width: `${CB.iconSize}px`,
1471
+ height: `${CB.iconSize}px`,
1472
+ fontSize: `${CB.iconSize}px`,
1473
+ marginRight: `${CB.iconGap}px`
1474
+ }
1475
+ },
1476
+ // Measured colours — NOT applied to primary commands, whose on-brand colours Fluent owns.
1477
+ commandColors: {
1478
+ color: import_react_components8.tokens.colorNeutralForeground1,
1479
+ [`& .${import_react_components8.buttonClassNames.icon}`]: { color: import_react_components8.tokens.colorNeutralForeground2 }
1480
+ },
1481
+ menuCommand: { paddingRight: 0 },
1482
+ chevronZone: {
1483
+ display: "inline-flex",
1484
+ justifyContent: "center",
1485
+ alignItems: "center",
1486
+ width: `${CB.chevronZone - FLUENT_BORDER}px`,
1487
+ flexShrink: 0
1488
+ },
1489
+ splitMain: { marginRight: `${CB.splitGap}px` },
1490
+ iconOnly: {
1491
+ height: `${CB.buttonHeight}px`,
1492
+ minWidth: 0,
1493
+ maxWidth: "none",
1494
+ flexShrink: 0,
1495
+ padding: 0,
1496
+ color: import_react_components8.tokens.colorNeutralForeground1
1497
+ },
1498
+ far: { padding: `0 ${CB.farPadding}px` },
1499
+ farButton: {
1500
+ height: `${CB.shareHeight}px`,
1501
+ minWidth: 0,
1502
+ // Share's border is a real 1px #d1d1d1 border in Dynamics too (bl=1 alongside p=1,8).
1503
+ padding: `1px ${CB.sharePaddingX}px`,
1504
+ fontSize: `${CB.shareFontSize}px`,
1505
+ lineHeight: `${CB.shareLineHeight}px`,
1506
+ fontWeight: import_react_components8.tokens.fontWeightRegular,
1507
+ color: import_react_components8.tokens.colorNeutralForeground2,
1508
+ borderTopColor: import_react_components8.tokens.colorNeutralStroke1,
1509
+ borderRightColor: import_react_components8.tokens.colorNeutralStroke1,
1510
+ borderBottomColor: import_react_components8.tokens.colorNeutralStroke1,
1511
+ borderLeftColor: import_react_components8.tokens.colorNeutralStroke1,
1512
+ [`& .${import_react_components8.buttonClassNames.icon}`]: {
1513
+ width: `${CB.shareIconSize}px`,
1514
+ height: `${CB.shareIconSize}px`,
1515
+ fontSize: `${CB.shareIconSize}px`,
1516
+ marginRight: "4px"
1517
+ }
1518
+ }
1519
+ });
1520
+ function CeCommandSurface({ items, overflowItems, farItems, className, onBack, onPopOut }) {
1521
+ const styles = useStyles6();
1522
+ const measuredColors = (item) => item.appearance !== "primary";
1523
+ const commandClass = (item, ...extra) => (0, import_react_components8.mergeClasses)(styles.command, measuredColors(item) && styles.commandColors, ...extra);
1524
+ const commandPart = (item) => ({
1525
+ "data-surface-part": "command",
1526
+ "data-measured-colors": measuredColors(item) ? "true" : void 0
1527
+ });
1528
+ const appearanceOf = (item) => item.appearance === "primary" ? "primary" : "subtle";
1529
+ const command = (item) => {
1530
+ if (item.menuItems?.length && item.split) {
1531
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react9.default.Fragment, { children: [
1532
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1533
+ import_react_components8.ToolbarButton,
1534
+ {
1535
+ appearance: appearanceOf(item),
1536
+ icon: item.icon,
1537
+ disabled: item.disabled,
1538
+ onClick: item.onClick,
1539
+ className: commandClass(item, styles.splitMain),
1540
+ ...commandPart(item),
1541
+ children: item.label
1542
+ }
1543
+ ),
1544
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.ToolbarDivider, { className: (0, import_react_components8.mergeClasses)(styles.divider, styles.splitDivider) }),
1545
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1546
+ ItemMenu,
1547
+ {
1548
+ items: item.menuItems,
1549
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1550
+ import_react_components8.ToolbarButton,
1551
+ {
1552
+ appearance: "subtle",
1553
+ "aria-label": `More ${item.label} options`,
1554
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_icons3.ChevronDown16Regular, {}),
1555
+ disabled: item.disabled,
1556
+ className: styles.iconOnly,
1557
+ style: { width: CB.chevronZone, marginRight: -CB.splitChevronOverhang },
1558
+ "data-surface-part": "command-split-chevron"
1559
+ }
1560
+ )
1561
+ }
1562
+ )
1563
+ ] }, item.id);
1564
+ }
1565
+ if (item.menuItems?.length) {
1566
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1567
+ ItemMenu,
1568
+ {
1569
+ items: item.menuItems,
1570
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1571
+ import_react_components8.ToolbarButton,
1572
+ {
1573
+ appearance: appearanceOf(item),
1574
+ icon: item.icon,
1575
+ disabled: item.disabled,
1576
+ className: commandClass(item, styles.menuCommand),
1577
+ ...commandPart(item),
1578
+ children: [
1579
+ item.label,
1580
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: styles.chevronZone, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_icons3.ChevronDown12Regular, {}) })
1581
+ ]
1582
+ }
1583
+ )
1584
+ },
1585
+ item.id
1586
+ );
1587
+ }
1588
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1589
+ import_react_components8.ToolbarButton,
1590
+ {
1591
+ appearance: appearanceOf(item),
1592
+ icon: item.icon,
1593
+ disabled: item.disabled,
1594
+ onClick: item.onClick,
1595
+ className: commandClass(item),
1596
+ ...commandPart(item),
1597
+ children: item.label
1598
+ },
1599
+ item.id
1600
+ );
1601
+ };
1602
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: (0, import_react_components8.mergeClasses)(styles.root, className), "data-surface-part": "command-bar", "data-look": "ce", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: styles.card, "data-surface-part": "command-card", children: [
1603
+ (onBack || onPopOut) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { role: "group", "aria-label": "Navigation", className: (0, import_react_components8.mergeClasses)(styles.group, styles.nav), "data-surface-part": "command-nav", children: [
1604
+ onBack && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1605
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1606
+ import_react_components8.Button,
1607
+ {
1608
+ appearance: "subtle",
1609
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_icons3.ArrowLeft20Regular, {}),
1610
+ "aria-label": "Back",
1611
+ onClick: onBack,
1612
+ className: styles.navButton,
1613
+ style: { width: CB.backWidth },
1614
+ "data-surface-part": "command-back"
1615
+ }
1616
+ ),
1617
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.ToolbarDivider, { className: styles.divider })
1618
+ ] }),
1619
+ onPopOut && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1620
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1621
+ import_react_components8.Button,
1622
+ {
1623
+ appearance: "subtle",
1624
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_icons3.WindowNew20Regular, {}),
1625
+ "aria-label": "Open in new window",
1626
+ onClick: onPopOut,
1627
+ className: styles.navButton,
1628
+ style: { width: CB.popOutWidth },
1629
+ "data-surface-part": "command-popout"
1630
+ }
1631
+ ),
1632
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.ToolbarDivider, { className: styles.divider })
1633
+ ] })
1634
+ ] }),
1635
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_components8.Toolbar, { "aria-label": "Commands", className: styles.commands, "data-surface-part": "command-list", children: [
1636
+ items.map(command),
1637
+ overflowItems && overflowItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1638
+ ItemMenu,
1639
+ {
1640
+ items: overflowItems,
1641
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1642
+ import_react_components8.ToolbarButton,
1643
+ {
1644
+ appearance: "subtle",
1645
+ "aria-label": "More commands",
1646
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_icons3.MoreVertical16Regular, {}),
1647
+ className: styles.iconOnly,
1648
+ style: { width: CB.overflowWidth },
1649
+ "data-surface-part": "command-overflow"
1650
+ }
1651
+ )
1652
+ }
1653
+ )
1654
+ ] }),
1655
+ farItems && farItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { role: "group", "aria-label": "Secondary commands", className: (0, import_react_components8.mergeClasses)(styles.group, styles.far), "data-surface-part": "command-far", children: farItems.map((f) => {
1656
+ const btn = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1657
+ import_react_components8.Button,
1658
+ {
1659
+ appearance: "outline",
1660
+ icon: f.icon,
1661
+ disabled: f.disabled,
1662
+ onClick: f.menuItems?.length ? void 0 : f.onClick,
1663
+ className: styles.farButton,
1664
+ "data-surface-part": "command-far-button",
1665
+ children: [
1666
+ f.label,
1667
+ f.menuItems?.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_icons3.ChevronDown12Regular, { style: { marginLeft: 4 }, "aria-hidden": true }) : null
1668
+ ]
1669
+ },
1670
+ f.id
1671
+ );
1672
+ return f.menuItems?.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ItemMenu, { items: f.menuItems, trigger: btn }, f.id) : btn;
1673
+ }) })
1674
+ ] }) });
1675
+ }
1676
+ var CommandSurface = (props) => {
1677
+ if (props.look === "ce") return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CeCommandSurface, { ...props });
1678
+ const { items, overflowItems, farItems, size = "small", className } = props;
627
1679
  const hasFar = Boolean(farItems && farItems.length > 0);
628
1680
  const hasOverflow = Boolean(overflowItems && overflowItems.length > 0);
629
1681
  const hasPrimary = items.length > 0 || hasOverflow;
630
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className, style: { display: "flex", alignItems: "center", gap: 8 }, children: [
631
- hasPrimary && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_components7.Toolbar, { "aria-label": "Commands", size, children: [
1682
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className, style: { display: "flex", alignItems: "center", gap: 8 }, children: [
1683
+ hasPrimary && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_components8.Toolbar, { "aria-label": "Commands", size, children: [
632
1684
  items.map(renderToolbarButton),
633
- hasOverflow && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_components7.Menu, { children: [
634
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_components7.MenuTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_components7.ToolbarButton, { "aria-label": "More commands", icon: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_icons2.MoreHorizontal20Regular, {}) }) }),
635
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_components7.MenuPopover, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_components7.MenuList, { children: overflowItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_components7.MenuItem, { icon: item.icon, disabled: item.disabled, onClick: item.onClick, children: item.label }, item.id)) }) })
1685
+ hasOverflow && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_components8.Menu, { children: [
1686
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.MenuTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.ToolbarButton, { "aria-label": "More commands", icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_icons3.MoreHorizontal20Regular, {}) }) }),
1687
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.MenuPopover, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.MenuList, { children: overflowItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.MenuItem, { icon: item.icon, disabled: item.disabled, onClick: item.onClick, children: item.label }, item.id)) }) })
636
1688
  ] })
637
1689
  ] }),
638
1690
  hasFar && // marginLeft:auto keeps far items right-aligned whether or not a primary toolbar renders.
639
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_components7.Toolbar, { "aria-label": "Secondary commands", size, style: { marginLeft: "auto" }, children: farItems.map(renderToolbarButton) })
1691
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.Toolbar, { "aria-label": "Secondary commands", size, style: { marginLeft: "auto" }, children: farItems.map(renderToolbarButton) })
640
1692
  ] });
641
1693
  };
642
1694
 
643
1695
  // src/v9/containers/ActionBar.tsx
644
- var import_react_components8 = require("@fluentui/react-components");
645
- var import_jsx_runtime9 = require("react/jsx-runtime");
1696
+ var import_react_components9 = require("@fluentui/react-components");
1697
+ var import_jsx_runtime10 = require("react/jsx-runtime");
646
1698
  function renderButton(b) {
647
1699
  const appearance = b.appearance === "primary" ? "primary" : b.appearance === "subtle" ? "subtle" : "secondary";
648
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_components8.Button, { appearance, icon: b.icon, disabled: b.disabled, onClick: b.onClick, children: b.label }, b.id);
1700
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_components9.Button, { appearance, icon: b.icon, disabled: b.disabled, onClick: b.onClick, children: b.label }, b.id);
649
1701
  }
650
1702
  var ActionBar = ({ buttons, alignment = "right", sticky = true, className }) => {
651
1703
  const justify = alignment === "left" ? "flex-start" : alignment === "center" ? "center" : "flex-end";
@@ -658,19 +1710,19 @@ var ActionBar = ({ buttons, alignment = "right", sticky = true, className }) =>
658
1710
  justifyContent: left.length ? "space-between" : justify,
659
1711
  gap: 8,
660
1712
  padding: "12px 24px",
661
- borderTop: `1px solid ${import_react_components8.tokens.colorNeutralStroke2}`,
662
- backgroundColor: import_react_components8.tokens.colorNeutralBackground1,
1713
+ borderTop: `1px solid ${import_react_components9.tokens.colorNeutralStroke2}`,
1714
+ backgroundColor: import_react_components9.tokens.colorNeutralBackground1,
663
1715
  ...sticky ? { position: "sticky", bottom: 0, zIndex: 1 } : {}
664
1716
  };
665
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className, style: rootStyle, children: [
666
- left.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", gap: 8 }, children: left.map(renderButton) }),
667
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", gap: 8, justifyContent: justify }, children: right.map(renderButton) })
1717
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className, style: rootStyle, children: [
1718
+ left.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { display: "flex", gap: 8 }, children: left.map(renderButton) }),
1719
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { display: "flex", gap: 8, justifyContent: justify }, children: right.map(renderButton) })
668
1720
  ] });
669
1721
  };
670
1722
 
671
1723
  // src/v9/containers/Footer.tsx
672
- var import_react_components9 = require("@fluentui/react-components");
673
- var import_jsx_runtime10 = require("react/jsx-runtime");
1724
+ var import_react_components10 = require("@fluentui/react-components");
1725
+ var import_jsx_runtime11 = require("react/jsx-runtime");
674
1726
  var Footer = ({ sticky = true, align = "right", className, children }) => {
675
1727
  const justify = align === "left" ? "flex-start" : align === "center" ? "center" : "flex-end";
676
1728
  const rootStyle = {
@@ -679,17 +1731,82 @@ var Footer = ({ sticky = true, align = "right", className, children }) => {
679
1731
  justifyContent: justify,
680
1732
  gap: 8,
681
1733
  padding: "12px 24px",
682
- borderTop: `1px solid ${import_react_components9.tokens.colorNeutralStroke2}`,
683
- backgroundColor: import_react_components9.tokens.colorNeutralBackground1,
1734
+ borderTop: `1px solid ${import_react_components10.tokens.colorNeutralStroke2}`,
1735
+ backgroundColor: import_react_components10.tokens.colorNeutralBackground1,
684
1736
  ...sticky ? { position: "sticky", bottom: 0, zIndex: 1 } : {}
685
1737
  };
686
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className, style: rootStyle, children });
1738
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className, style: rootStyle, children });
1739
+ };
1740
+
1741
+ // src/v9/layouts/TabColumns.tsx
1742
+ var import_react10 = __toESM(require("react"), 1);
1743
+ var import_react_components11 = require("@fluentui/react-components");
1744
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1745
+ var useStyles7 = (0, import_react_components11.makeStyles)({
1746
+ row: {
1747
+ display: "flex",
1748
+ flexWrap: "wrap",
1749
+ alignItems: "flex-start"
1750
+ },
1751
+ column: {
1752
+ display: "flex",
1753
+ flexDirection: "column",
1754
+ boxSizing: "border-box"
1755
+ }
1756
+ });
1757
+ function positional(children) {
1758
+ const out = [];
1759
+ const walk = (node) => {
1760
+ if (Array.isArray(node)) node.forEach(walk);
1761
+ else out.push(node);
1762
+ };
1763
+ walk(children);
1764
+ return out;
1765
+ }
1766
+ var isEmpty2 = (n) => n === null || n === void 0 || typeof n === "boolean" || n === "";
1767
+ var TabColumns = ({
1768
+ widths,
1769
+ minColumnWidth,
1770
+ gap,
1771
+ look: lookProp,
1772
+ className,
1773
+ style,
1774
+ children
1775
+ }) => {
1776
+ const styles = useStyles7();
1777
+ const ambientLook = useLook();
1778
+ const ce = (lookProp ?? ambientLook) === "ce";
1779
+ const floor = minColumnWidth ?? (ce ? import_design_tokens.ceForm.tabBody.columnMinWidth : 300);
1780
+ const spacing2 = gap ?? (ce ? import_design_tokens.ceForm.tabBody.columnGap : 20);
1781
+ const slots = positional(children);
1782
+ const visible = slots.map((s, i) => ({ node: s, i })).filter(({ node }) => !isEmpty2(node));
1783
+ const shares = normalizeColumnShares(visible.map(({ i }) => widths?.[i] ?? 1));
1784
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1785
+ "div",
1786
+ {
1787
+ className: (0, import_react_components11.mergeClasses)(styles.row, className),
1788
+ style: { gap: spacing2, ...style },
1789
+ "data-surface-part": "tab-columns",
1790
+ "data-look": ce ? "ce" : "default",
1791
+ children: visible.map(({ node, i }, v) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1792
+ "div",
1793
+ {
1794
+ className: styles.column,
1795
+ style: { flex: `${shares[v]} 1 0`, minWidth: `min(${floor}px, 100%)`, gap: ce ? import_design_tokens.ceForm.tabBody.sectionGap : spacing2 },
1796
+ "data-surface-part": "tab-column",
1797
+ "data-column-index": i,
1798
+ children: node
1799
+ },
1800
+ import_react10.default.isValidElement(node) && node.key != null ? node.key : i
1801
+ ))
1802
+ }
1803
+ );
687
1804
  };
688
1805
 
689
1806
  // src/v9/overlays/FormDialogSurface.tsx
690
- var import_react_components10 = require("@fluentui/react-components");
691
- var import_react_icons3 = require("@fluentui/react-icons");
692
- var import_jsx_runtime11 = require("react/jsx-runtime");
1807
+ var import_react_components12 = require("@fluentui/react-components");
1808
+ var import_react_icons4 = require("@fluentui/react-icons");
1809
+ var import_jsx_runtime13 = require("react/jsx-runtime");
693
1810
  var FormDialogSurface = ({
694
1811
  isOpen,
695
1812
  onDismiss,
@@ -713,19 +1830,19 @@ var FormDialogSurface = ({
713
1830
  justifyContent: "space-between",
714
1831
  gap: 12,
715
1832
  padding: "12px 20px",
716
- borderBottom: `1px solid ${import_react_components10.tokens.colorNeutralStroke2}`
1833
+ borderBottom: `1px solid ${import_react_components12.tokens.colorNeutralStroke2}`
717
1834
  };
718
- const counterStyle = { fontSize: import_react_components10.tokens.fontSizeBase200, color: import_react_components10.tokens.colorNeutralForeground3 };
719
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
720
- import_react_components10.Dialog,
1835
+ const counterStyle = { fontSize: import_react_components12.tokens.fontSizeBase200, color: import_react_components12.tokens.colorNeutralForeground3 };
1836
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1837
+ import_react_components12.Dialog,
721
1838
  {
722
1839
  open: isOpen,
723
1840
  modalType: isBlocking ? "modal" : "non-modal",
724
1841
  onOpenChange: (_e, data) => {
725
1842
  if (!data.open) onDismiss?.();
726
1843
  },
727
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
728
- import_react_components10.DialogSurface,
1844
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1845
+ import_react_components12.DialogSurface,
729
1846
  {
730
1847
  className,
731
1848
  style: {
@@ -738,22 +1855,22 @@ var FormDialogSurface = ({
738
1855
  padding: 0
739
1856
  },
740
1857
  children: [
741
- showHeader && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: headerStyle, children: [
742
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { display: "flex", flexDirection: "column", minWidth: 0 }, children: [
743
- title && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_components10.Text, { weight: "semibold", size: 400, children: title }),
744
- subheader && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { fontSize: import_react_components10.tokens.fontSizeBase200, color: import_react_components10.tokens.colorNeutralForeground3, marginTop: 2 }, children: subheader })
1858
+ showHeader && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: headerStyle, children: [
1859
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { display: "flex", flexDirection: "column", minWidth: 0 }, children: [
1860
+ title && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_components12.Text, { weight: "semibold", size: 400, children: title }),
1861
+ subheader && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: import_react_components12.tokens.fontSizeBase200, color: import_react_components12.tokens.colorNeutralForeground3, marginTop: 2 }, children: subheader })
745
1862
  ] }),
746
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
747
- recordCounter && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { style: counterStyle, children: [
1863
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
1864
+ recordCounter && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { style: counterStyle, children: [
748
1865
  recordCounter.current,
749
1866
  " of ",
750
1867
  recordCounter.total
751
1868
  ] }),
752
- onDismiss && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_components10.Button, { appearance: "subtle", "aria-label": "Close", icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_icons3.Dismiss20Regular, {}), onClick: onDismiss })
1869
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_components12.Button, { appearance: "subtle", "aria-label": "Close", icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_icons4.Dismiss20Regular, {}), onClick: onDismiss })
753
1870
  ] })
754
1871
  ] }),
755
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { flex: 1, minHeight: 0, overflow: "auto", padding: 20 }, children }),
756
- footer && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { borderTop: `1px solid ${import_react_components10.tokens.colorNeutralStroke2}`, padding: "12px 20px" }, children: footer })
1872
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { flex: 1, minHeight: 0, overflow: "auto", padding: 20 }, children }),
1873
+ footer && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { borderTop: `1px solid ${import_react_components12.tokens.colorNeutralStroke2}`, padding: "12px 20px" }, children: footer })
757
1874
  ]
758
1875
  }
759
1876
  )
@@ -762,8 +1879,8 @@ var FormDialogSurface = ({
762
1879
  };
763
1880
 
764
1881
  // src/v9/overlays/ModalSurface.tsx
765
- var import_react_components11 = require("@fluentui/react-components");
766
- var import_jsx_runtime12 = require("react/jsx-runtime");
1882
+ var import_react_components13 = require("@fluentui/react-components");
1883
+ var import_jsx_runtime14 = require("react/jsx-runtime");
767
1884
  var ModalSurface = ({
768
1885
  isOpen,
769
1886
  onDismiss,
@@ -777,22 +1894,22 @@ var ModalSurface = ({
777
1894
  children
778
1895
  }) => {
779
1896
  const sizing = autoSize ? { width: "auto", minWidth: MODAL_AUTOSIZE_MIN_WIDTH, maxWidth: "100%" } : { maxWidth: "95vw", width: `${dialogWidthPx({ width, size })}px` };
780
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
781
- import_react_components11.Dialog,
1897
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1898
+ import_react_components13.Dialog,
782
1899
  {
783
1900
  open: isOpen,
784
1901
  modalType: isBlocking ? "modal" : "non-modal",
785
1902
  onOpenChange: (_e, data) => {
786
1903
  if (!data.open) onDismiss?.();
787
1904
  },
788
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_components11.DialogSurface, { className, style: { ...sizing, padding: 0 }, children: [
789
- title && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { padding: "16px 20px 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_components11.Text, { weight: "semibold", size: 500, children: title }) }),
790
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { padding: 20 }, children }),
791
- footer && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1905
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_components13.DialogSurface, { className, style: { ...sizing, padding: 0 }, children: [
1906
+ title && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { padding: "16px 20px 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_components13.Text, { weight: "semibold", size: 500, children: title }) }),
1907
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { padding: 20 }, children }),
1908
+ footer && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
792
1909
  "div",
793
1910
  {
794
1911
  style: {
795
- borderTop: `1px solid ${import_react_components11.tokens.colorNeutralStroke2}`,
1912
+ borderTop: `1px solid ${import_react_components13.tokens.colorNeutralStroke2}`,
796
1913
  padding: "12px 20px",
797
1914
  display: "flex",
798
1915
  justifyContent: "flex-end",
@@ -807,9 +1924,9 @@ var ModalSurface = ({
807
1924
  };
808
1925
 
809
1926
  // src/v9/overlays/PanelSurface.tsx
810
- var import_react_components12 = require("@fluentui/react-components");
811
- var import_react_icons4 = require("@fluentui/react-icons");
812
- var import_jsx_runtime13 = require("react/jsx-runtime");
1927
+ var import_react_components14 = require("@fluentui/react-components");
1928
+ var import_react_icons5 = require("@fluentui/react-icons");
1929
+ var import_jsx_runtime15 = require("react/jsx-runtime");
813
1930
  var PanelSurface = ({
814
1931
  isOpen,
815
1932
  onDismiss,
@@ -824,8 +1941,8 @@ var PanelSurface = ({
824
1941
  }) => {
825
1942
  const size = drawerSize ?? (width != null && width > 500 ? "medium" : "small");
826
1943
  const customWidthStyle = width != null ? { width: `${width}px` } : void 0;
827
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
828
- import_react_components12.OverlayDrawer,
1944
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1945
+ import_react_components14.OverlayDrawer,
829
1946
  {
830
1947
  open: isOpen,
831
1948
  position: "end",
@@ -838,16 +1955,16 @@ var PanelSurface = ({
838
1955
  onDismiss?.();
839
1956
  },
840
1957
  children: [
841
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_components12.DrawerHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
842
- import_react_components12.DrawerHeaderTitle,
1958
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_components14.DrawerHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1959
+ import_react_components14.DrawerHeaderTitle,
843
1960
  {
844
- action: hasCloseButton && onDismiss ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_components12.Button, { appearance: "subtle", "aria-label": "Close", icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_icons4.Dismiss24Regular, {}), onClick: onDismiss }) : void 0,
1961
+ action: hasCloseButton && onDismiss ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_components14.Button, { appearance: "subtle", "aria-label": "Close", icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_icons5.Dismiss24Regular, {}), onClick: onDismiss }) : void 0,
845
1962
  children: title
846
1963
  }
847
1964
  ) }),
848
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_components12.DrawerBody, { children: [
849
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { padding: "12px 0" }, children }),
850
- footer && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: "auto", paddingTop: 12 }, children: footer })
1965
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_components14.DrawerBody, { children: [
1966
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { padding: "12px 0" }, children }),
1967
+ footer && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { marginTop: "auto", paddingTop: 12 }, children: footer })
851
1968
  ] })
852
1969
  ]
853
1970
  }
@@ -855,8 +1972,8 @@ var PanelSurface = ({
855
1972
  };
856
1973
 
857
1974
  // src/v9/overlays/CalloutSurface.tsx
858
- var import_react_components13 = require("@fluentui/react-components");
859
- var import_jsx_runtime14 = require("react/jsx-runtime");
1975
+ var import_react_components15 = require("@fluentui/react-components");
1976
+ var import_jsx_runtime16 = require("react/jsx-runtime");
860
1977
  function resolveTarget(target) {
861
1978
  if (!target) return null;
862
1979
  if (typeof target === "string") return document.querySelector(target);
@@ -877,8 +1994,8 @@ var CalloutSurface = ({
877
1994
  if (!isOpen) return null;
878
1995
  const el = resolveTarget(target);
879
1996
  const positioning = { position, align, ...el ? { target: el } : {} };
880
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
881
- import_react_components13.Popover,
1997
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1998
+ import_react_components15.Popover,
882
1999
  {
883
2000
  open: true,
884
2001
  trapFocus: false,
@@ -887,14 +2004,14 @@ var CalloutSurface = ({
887
2004
  onOpenChange: (_e, data) => {
888
2005
  if (!data.open) onDismiss?.();
889
2006
  },
890
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_components13.PopoverSurface, { className, style: { width: calloutWidthPx(width), padding: 16 }, children })
2007
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_components15.PopoverSurface, { className, style: { width: calloutWidthPx(width), padding: 16 }, children })
891
2008
  }
892
2009
  );
893
2010
  };
894
2011
 
895
2012
  // src/v9/overlays/TooltipSurface.tsx
896
- var import_react_components14 = require("@fluentui/react-components");
897
- var import_jsx_runtime15 = require("react/jsx-runtime");
2013
+ var import_react_components16 = require("@fluentui/react-components");
2014
+ var import_jsx_runtime17 = require("react/jsx-runtime");
898
2015
  var DELAY_MS = {
899
2016
  zero: 0,
900
2017
  medium: 250,
@@ -906,21 +2023,25 @@ var TooltipSurface = ({
906
2023
  delay = "medium",
907
2024
  relationship = "label",
908
2025
  children
909
- }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_components14.Tooltip, { content, relationship, positioning: position, showDelay: DELAY_MS[delay], children });
2026
+ }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_components16.Tooltip, { content, relationship, positioning: position, showDelay: DELAY_MS[delay], children });
910
2027
  // Annotate the CommonJS export names for ESM import in node:
911
2028
  0 && (module.exports = {
912
2029
  ActionBar,
913
2030
  BREAKPOINTS,
914
2031
  CALLOUT_DEFAULT_WIDTH,
915
2032
  CARD_REFLOW_WIDTH,
2033
+ CE_LABEL_ABOVE_BELOW_ROW_WIDTH,
2034
+ CE_TAB_COLUMN_MIN_WIDTH,
916
2035
  CalloutSurface,
917
2036
  CommandSurface,
918
2037
  DIALOG_SIZE_PX,
919
2038
  DensityContext,
2039
+ FieldRow,
920
2040
  Footer,
921
2041
  FormDialogSurface,
922
2042
  FormHeader,
923
2043
  FormSurface,
2044
+ LookContext,
924
2045
  MODAL_AUTOSIZE_MIN_WIDTH,
925
2046
  ModalSurface,
926
2047
  PANEL_DEFAULT_WIDTH,
@@ -930,11 +2051,16 @@ var TooltipSurface = ({
930
2051
  Section,
931
2052
  SectionCard,
932
2053
  SectionHeader,
2054
+ TabColumns,
933
2055
  TooltipSurface,
934
2056
  calloutFormDefaults,
935
2057
  calloutWidthPx,
2058
+ ceFieldRowFirstOffset,
2059
+ ceForm,
2060
+ cePresenceBadgeStyle,
936
2061
  clampSpan,
937
2062
  colors,
2063
+ createDynamicsCeTheme,
938
2064
  createDynamicsV9DarkTheme,
939
2065
  createDynamicsV9Theme,
940
2066
  densityScale,
@@ -942,17 +2068,20 @@ var TooltipSurface = ({
942
2068
  dialogWidthCss,
943
2069
  dialogWidthPx,
944
2070
  dynamicsBrandRamp,
2071
+ dynamicsCeTheme,
945
2072
  dynamicsV9DarkTheme,
946
2073
  dynamicsV9Theme,
947
2074
  fieldGridStyle,
948
2075
  fieldRowStyle,
949
2076
  gridTemplateForColumns,
950
2077
  layout,
2078
+ normalizeColumnShares,
951
2079
  panelCustomWidthPx,
952
2080
  panelKindFromWidth,
953
2081
  radius,
954
2082
  resolveBreakpoint,
955
2083
  resolveResponsiveValue,
2084
+ resolveTabColumnWidths,
956
2085
  scaleSpacing,
957
2086
  sectionStackingStyle,
958
2087
  spacing,
@@ -961,6 +2090,7 @@ var TooltipSurface = ({
961
2090
  useContainerSize,
962
2091
  useContainerWidth,
963
2092
  useDensity,
2093
+ useLook,
964
2094
  useMediaQuery,
965
2095
  useResponsiveValue
966
2096
  });