@truenas/ui-components 0.1.73 → 0.1.74

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.
@@ -52,20 +52,24 @@ function kebabTestSegment(part) {
52
52
  * Normalizes the base — a single token or an array of segments — into a flat
53
53
  * segment array and appends the suffixes, producing a value that is itself a
54
54
  * valid {@link TnTestIdValue}. This is the canonical "derive a per-child id from
55
- * a parent base" operation, e.g. a dialog's close button (`[base, 'close']`) or
56
- * a select's per-option id (`[base, option.label]`). Centralizing it keeps the
57
- * `string | array` flattening contract in one place rather than re-implemented
58
- * at each call site.
55
+ * a parent base" operation, e.g. a select's per-option id
56
+ * (`[base, option.label]`) or a menu item's id (`[base, item.id]`). Centralizing
57
+ * it keeps the `string | array` flattening contract in one place rather than
58
+ * re-implemented at each call site.
59
+ *
60
+ * Note this is *base-first*: the suffix trails the base. Fixed chrome whose role
61
+ * should lead (e.g. `tn-dialog-shell`'s `button-close-<base>`) prepends the role
62
+ * manually instead of calling this.
59
63
  *
60
64
  * Falsy segments are preserved here (not filtered) so `composeTestId` can apply
61
- * its own drop/scoping rules — `scopeTestId(undefined, 'close')` yields
62
- * `[undefined, 'close']`, which `composeTestId('button', …)` renders as the
63
- * unscoped `button-close`.
65
+ * its own drop/scoping rules — `scopeTestId(undefined, 'edit')` yields
66
+ * `[undefined, 'edit']`, which `composeTestId('menu-item', …)` renders as the
67
+ * unscoped `menu-item-edit`.
64
68
  *
65
69
  * @example
66
70
  * scopeTestId('actions', 'edit') // ['actions', 'edit']
67
71
  * scopeTestId(['menu', 'main'], 'edit') // ['menu', 'main', 'edit']
68
- * scopeTestId(undefined, 'close') // [undefined, 'close']
72
+ * scopeTestId(undefined, 'edit') // [undefined, 'edit']
69
73
  */
70
74
  function scopeTestId(base, ...suffix) {
71
75
  return [...(Array.isArray(base) ? base : [base]), ...suffix];
@@ -12585,14 +12589,32 @@ class TnDialogShellComponent {
12585
12589
  /**
12586
12590
  * Optional semantic base that scopes the shell's chrome buttons. The close
12587
12591
  * and fullscreen buttons emit `button-close` / `button-fullscreen` by default,
12588
- * or `button-<testId>-close` / `-fullscreen` when a base is provided (useful
12589
- * when more than one dialog can be open).
12592
+ * or `button-close-<testId>` / `button-fullscreen-<testId>` when a base is
12593
+ * provided (useful when more than one dialog can be open).
12590
12594
  */
12591
12595
  testId = input(undefined, ...(ngDevMode ? [{ debugName: "testId" }] : []));
12592
- /** Scoped test-id segments for the close button (`button-[<base>-]close`). */
12593
- closeTestId = computed(() => scopeTestId(this.testId(), 'close'), ...(ngDevMode ? [{ debugName: "closeTestId" }] : []));
12594
- /** Scoped test-id segments for the fullscreen button (`button-[<base>-]fullscreen`). */
12595
- fullscreenTestId = computed(() => scopeTestId(this.testId(), 'fullscreen'), ...(ngDevMode ? [{ debugName: "fullscreenTestId" }] : []));
12596
+ /**
12597
+ * The `testId` base normalized to a flat segment array. Nothing is dropped
12598
+ * here `composeTestId` (via the `[tnTestId]` directive) filters falsy
12599
+ * segments, so an unset base collapses to the bare role (`button-close`).
12600
+ */
12601
+ baseSegments = computed(() => {
12602
+ const base = this.testId();
12603
+ return Array.isArray(base) ? base : [base];
12604
+ }, ...(ngDevMode ? [{ debugName: "baseSegments" }] : []));
12605
+ /**
12606
+ * Role-first test-id segments for the close button: `button-close[-<base>]`.
12607
+ *
12608
+ * The close and fullscreen buttons are fixed dialog chrome, not content
12609
+ * children, so the role leads rather than the base (content children are
12610
+ * base-first via `scopeTestId`). This keeps every dialog's close button under
12611
+ * a shared `button-close-*` prefix — it matches webui's established
12612
+ * close-button ids and lets automation target "all close buttons" with one
12613
+ * selector.
12614
+ */
12615
+ closeTestId = computed(() => ['close', ...this.baseSegments()], ...(ngDevMode ? [{ debugName: "closeTestId" }] : []));
12616
+ /** Role-first test-id segments for the fullscreen button: `button-fullscreen[-<base>]`. */
12617
+ fullscreenTestId = computed(() => ['fullscreen', ...this.baseSegments()], ...(ngDevMode ? [{ debugName: "fullscreenTestId" }] : []));
12596
12618
  /** Stable id for the title heading, referenced by the dialog's aria-labelledby. */
12597
12619
  titleId = `tn-dialog-title-${nextUniqueId++}`;
12598
12620
  isFullscreen = signal(false, ...(ngDevMode ? [{ debugName: "isFullscreen" }] : []));