@dataverse-kit/surface-kit 0.4.0 → 0.5.0

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