@nldd/design-system 0.8.82 → 0.8.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/custom-elements.json +436 -68
  2. package/dist/components/actions/button/button.d.ts +5 -0
  3. package/dist/components/actions/button/button.d.ts.map +1 -1
  4. package/dist/components/actions/button/button.js +8 -0
  5. package/dist/components/actions/button/button.js.map +1 -1
  6. package/dist/components/actions/button/button.template.d.ts.map +1 -1
  7. package/dist/components/actions/button/button.template.js +2 -0
  8. package/dist/components/actions/button/button.template.js.map +1 -1
  9. package/dist/components/actions/icon-button/icon-button.d.ts +1 -1
  10. package/dist/components/actions/icon-button/icon-button.js +1 -1
  11. package/dist/components/components.js +894 -226
  12. package/dist/components/content/avatar/avatar.styles.d.ts.map +1 -1
  13. package/dist/components/content/avatar/avatar.styles.js +5 -1
  14. package/dist/components/content/avatar/avatar.styles.js.map +1 -1
  15. package/dist/components/content/icon/icon-aliases.d.ts.map +1 -1
  16. package/dist/components/content/icon/icon-aliases.js +78 -6
  17. package/dist/components/content/icon/icon-aliases.js.map +1 -1
  18. package/dist/components/content/icon/icon-gallery-status.d.ts.map +1 -1
  19. package/dist/components/content/icon/icon-gallery-status.js +55 -94
  20. package/dist/components/content/icon/icon-gallery-status.js.map +1 -1
  21. package/dist/components/content/icon/icon-registry.d.ts.map +1 -1
  22. package/dist/components/content/icon/icon-registry.js +34 -4
  23. package/dist/components/content/icon/icon-registry.js.map +1 -1
  24. package/dist/components/content/icon/icon.d.ts +8 -2
  25. package/dist/components/content/icon/icon.d.ts.map +1 -1
  26. package/dist/components/content/icon/icon.js +17 -2
  27. package/dist/components/content/icon/icon.js.map +1 -1
  28. package/dist/components/content/icon/icon.styles.d.ts.map +1 -1
  29. package/dist/components/content/icon/icon.styles.js +8 -0
  30. package/dist/components/content/icon/icon.styles.js.map +1 -1
  31. package/dist/components/content/text/text.d.ts +50 -0
  32. package/dist/components/content/text/text.d.ts.map +1 -0
  33. package/dist/components/content/text/text.js +81 -0
  34. package/dist/components/content/text/text.js.map +1 -0
  35. package/dist/components/content/text/text.styles.d.ts +2 -0
  36. package/dist/components/content/text/text.styles.d.ts.map +1 -0
  37. package/dist/components/content/text/text.styles.js +116 -0
  38. package/dist/components/content/text/text.styles.js.map +1 -0
  39. package/dist/components/content/text/text.template.d.ts +3 -0
  40. package/dist/components/content/text/text.template.d.ts.map +1 -0
  41. package/dist/components/content/text/text.template.js +7 -0
  42. package/dist/components/content/text/text.template.js.map +1 -0
  43. package/dist/components/content/title/title.styles.d.ts.map +1 -1
  44. package/dist/components/content/title/title.styles.js +9 -13
  45. package/dist/components/content/title/title.styles.js.map +1 -1
  46. package/dist/components/{icon-CIpJq_cf.js → icon-C1Kikpol.js} +100 -10
  47. package/dist/components/{icon-button-BAkUJTn6.js → icon-button-BYy6hnAY.js} +2 -2
  48. package/dist/components/index.d.ts +2 -1
  49. package/dist/components/index.d.ts.map +1 -1
  50. package/dist/components/index.js +2 -1
  51. package/dist/components/index.js.map +1 -1
  52. package/dist/components/inputs/combo-box/combo-box.d.ts +2 -0
  53. package/dist/components/inputs/combo-box/combo-box.d.ts.map +1 -1
  54. package/dist/components/inputs/combo-box/combo-box.js +22 -0
  55. package/dist/components/inputs/combo-box/combo-box.js.map +1 -1
  56. package/dist/components/inputs/combo-box/combo-box.styles.d.ts.map +1 -1
  57. package/dist/components/inputs/combo-box/combo-box.styles.js +5 -0
  58. package/dist/components/inputs/combo-box/combo-box.styles.js.map +1 -1
  59. package/dist/components/inputs/combo-box/combo-box.template.d.ts.map +1 -1
  60. package/dist/components/inputs/combo-box/combo-box.template.js +23 -20
  61. package/dist/components/inputs/combo-box/combo-box.template.js.map +1 -1
  62. package/dist/components/inputs/date-field/date-field.template.d.ts.map +1 -1
  63. package/dist/components/inputs/date-field/date-field.template.js +7 -1
  64. package/dist/components/inputs/date-field/date-field.template.js.map +1 -1
  65. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.d.ts +8 -1
  66. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.d.ts.map +1 -1
  67. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.js +8 -0
  68. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.js.map +1 -1
  69. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.template.d.ts.map +1 -1
  70. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.template.js +2 -0
  71. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.template.js.map +1 -1
  72. package/dist/components/inputs/text-field/text-field.d.ts +21 -0
  73. package/dist/components/inputs/text-field/text-field.d.ts.map +1 -1
  74. package/dist/components/inputs/text-field/text-field.js +48 -0
  75. package/dist/components/inputs/text-field/text-field.js.map +1 -1
  76. package/dist/components/inputs/text-field/text-field.template.d.ts.map +1 -1
  77. package/dist/components/inputs/text-field/text-field.template.js +2 -0
  78. package/dist/components/inputs/text-field/text-field.template.js.map +1 -1
  79. package/dist/components/inputs/time-field/time-field.template.d.ts.map +1 -1
  80. package/dist/components/inputs/time-field/time-field.template.js +7 -1
  81. package/dist/components/inputs/time-field/time-field.template.js.map +1 -1
  82. package/dist/components/layout/box/box.d.ts +3 -3
  83. package/dist/components/layout/box/box.d.ts.map +1 -1
  84. package/dist/components/layout/box/box.js +3 -3
  85. package/dist/components/layout/box/box.js.map +1 -1
  86. package/dist/components/layout/box/box.styles.d.ts.map +1 -1
  87. package/dist/components/layout/box/box.styles.js +3 -6
  88. package/dist/components/layout/box/box.styles.js.map +1 -1
  89. package/dist/components/layout/sheet/sheet.styles.d.ts.map +1 -1
  90. package/dist/components/layout/sheet/sheet.styles.js +10 -3
  91. package/dist/components/layout/sheet/sheet.styles.js.map +1 -1
  92. package/dist/components/lists-and-tables/list/list.d.ts +60 -45
  93. package/dist/components/lists-and-tables/list/list.d.ts.map +1 -1
  94. package/dist/components/lists-and-tables/list/list.js +94 -80
  95. package/dist/components/lists-and-tables/list/list.js.map +1 -1
  96. package/dist/components/lists-and-tables/list-item/list-item.d.ts +94 -21
  97. package/dist/components/lists-and-tables/list-item/list-item.d.ts.map +1 -1
  98. package/dist/components/lists-and-tables/list-item/list-item.js +275 -48
  99. package/dist/components/lists-and-tables/list-item/list-item.js.map +1 -1
  100. package/dist/components/lists-and-tables/list-item/list-item.styles.d.ts.map +1 -1
  101. package/dist/components/lists-and-tables/list-item/list-item.styles.js +116 -34
  102. package/dist/components/lists-and-tables/list-item/list-item.styles.js.map +1 -1
  103. package/dist/components/lists-and-tables/list-item/list-item.template.d.ts +1 -1
  104. package/dist/components/lists-and-tables/list-item/list-item.template.d.ts.map +1 -1
  105. package/dist/components/lists-and-tables/list-item/list-item.template.js +5 -2
  106. package/dist/components/lists-and-tables/list-item/list-item.template.js.map +1 -1
  107. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.d.ts +116 -0
  108. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.d.ts.map +1 -0
  109. package/dist/components/lists-and-tables/{list-item-action/list-item-action.js → list-item-segment/list-item-segment.js} +77 -52
  110. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.js.map +1 -0
  111. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.styles.d.ts +2 -0
  112. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.styles.d.ts.map +1 -0
  113. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.styles.js +179 -0
  114. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.styles.js.map +1 -0
  115. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.d.ts +3 -0
  116. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.d.ts.map +1 -0
  117. package/dist/components/lists-and-tables/{list-item-action/list-item-action.template.js → list-item-segment/list-item-segment.template.js} +5 -4
  118. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.js.map +1 -0
  119. package/dist/components/status-and-feedback/badge/badge.d.ts +8 -2
  120. package/dist/components/status-and-feedback/badge/badge.d.ts.map +1 -1
  121. package/dist/components/status-and-feedback/badge/badge.js +17 -1
  122. package/dist/components/status-and-feedback/badge/badge.js.map +1 -1
  123. package/dist/components/status-and-feedback/badge/badge.styles.d.ts.map +1 -1
  124. package/dist/components/status-and-feedback/badge/badge.styles.js +35 -6
  125. package/dist/components/status-and-feedback/badge/badge.styles.js.map +1 -1
  126. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.styles.d.ts.map +1 -1
  127. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.styles.js +7 -0
  128. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.styles.js.map +1 -1
  129. package/dist/css/variables.css +25 -1
  130. package/dist/nldd.min.js +1002 -593
  131. package/dist/types/vue.d.ts +93 -47
  132. package/dist/utilities/scroll-mode-controller.d.ts +9 -1
  133. package/dist/utilities/scroll-mode-controller.d.ts.map +1 -1
  134. package/dist/utilities/scroll-mode-controller.js +10 -2
  135. package/dist/utilities/scroll-mode-controller.js.map +1 -1
  136. package/package.json +8 -4
  137. package/dist/components/lists-and-tables/list-item-action/list-item-action.d.ts +0 -108
  138. package/dist/components/lists-and-tables/list-item-action/list-item-action.d.ts.map +0 -1
  139. package/dist/components/lists-and-tables/list-item-action/list-item-action.js.map +0 -1
  140. package/dist/components/lists-and-tables/list-item-action/list-item-action.styles.d.ts +0 -2
  141. package/dist/components/lists-and-tables/list-item-action/list-item-action.styles.d.ts.map +0 -1
  142. package/dist/components/lists-and-tables/list-item-action/list-item-action.styles.js +0 -145
  143. package/dist/components/lists-and-tables/list-item-action/list-item-action.styles.js.map +0 -1
  144. package/dist/components/lists-and-tables/list-item-action/list-item-action.template.d.ts +0 -3
  145. package/dist/components/lists-and-tables/list-item-action/list-item-action.template.d.ts.map +0 -1
  146. package/dist/components/lists-and-tables/list-item-action/list-item-action.template.js.map +0 -1
@@ -3,8 +3,8 @@ import { n as slottedReset, t as inheritedTextReset } from "./shadow-resets-aG-r
3
3
  import { t as __decorate } from "./decorate-BKn10QQi.js";
4
4
  import { t as withTranslations } from "./with-translations-DzAdFTK8.js";
5
5
  import { t as reflectNonDefault } from "./reflect-non-default-OLaK60rT.js";
6
- import { i as PopupAnchorController, n as NLDDTooltip, r as NLDDActivityIndicator, t as NLDDIconButton } from "./icon-button-BAkUJTn6.js";
7
- import { t as NLDDIcon } from "./icon-CIpJq_cf.js";
6
+ import { i as PopupAnchorController, n as NLDDTooltip, r as NLDDActivityIndicator, t as NLDDIconButton } from "./icon-button-BYy6hnAY.js";
7
+ import { t as NLDDIcon } from "./icon-C1Kikpol.js";
8
8
  import { n as isPointerMode, r as isTouchMode, t as isKeyboardMode } from "./input-modality-DhTeUxKi.js";
9
9
  import { t as breakpoints } from "./breakpoints-CkxsiRgH.js";
10
10
  import { t as VisibilityMixin } from "./visibility-mixin-GxbwkBb1.js";
@@ -664,7 +664,7 @@ function renderContent(component) {
664
664
  ` : nothing}
665
665
  `;
666
666
  }
667
- function template$22(helpers) {
667
+ function template$23(helpers) {
668
668
  const content = renderContent(this);
669
669
  const buttonClass = ["button", this.supportingText ? "has-supporting-text" : ""].filter(Boolean).join(" ");
670
670
  const ariaExpanded = this.expandable || !!this.popupType ? String(this.expanded) : this.expanded ? "true" : nothing;
@@ -694,6 +694,7 @@ function template$22(helpers) {
694
694
  aria-haspopup=${this.popupType || nothing}
695
695
  aria-expanded=${ariaExpanded}
696
696
  aria-busy=${ariaBusy}
697
+ tabindex=${this.noTab ? "-1" : nothing}
697
698
  @pointerdown=${this._popup.handlePointerdown}
698
699
  @click=${helpers.handleClick}
699
700
  >
@@ -713,6 +714,7 @@ function template$22(helpers) {
713
714
  aria-haspopup=${this.popupType || nothing}
714
715
  aria-expanded=${ariaExpanded}
715
716
  aria-busy=${ariaBusy}
717
+ tabindex=${this.noTab ? "-1" : nothing}
716
718
  popovertarget=${this.popovertarget || nothing}
717
719
  .popoverTargetElement=${this.popoverTargetElement}
718
720
  .popoverTargetAction=${this.popoverTargetAction}
@@ -750,6 +752,7 @@ var nlddButtonTranslations = { "components.button.opens-in-new-tab-label": "Open
750
752
  * @attr {string} supporting-text - Supporting text shown below the text (md/lg) or after it (sm/xs), in a secondary color. Part of the accessible name (unless `accessible-label` is set, which replaces the whole accessible name).
751
753
  * @attr {boolean} single-line - When true, truncates overflowing text with an ellipsis instead of letting it wrap. Requires the button (or an ancestor) to constrain the width.
752
754
  * @attr {boolean} no-highlight-border - Removes the per-variant highlight border (e.g. when nldd-button-bar draws a single group border instead).
755
+ * @attr {boolean} no-tab - Takes the button out of the tab order (tabindex="-1"), for a control owned by a roving container (e.g. a button in a row of an nldd-list, where the arrow keys move between rows) that manages focus itself. Still mouse- and script-focusable.
753
756
  * @attr {string} start-icon - Icon name for the start icon (before text)
754
757
  * @attr {string} end-icon - Icon name for the end icon (after text)
755
758
  * @attr {string} accessible-label - Accessible label for the button, overrides text for screen readers
@@ -775,6 +778,7 @@ var NLDDButton = (_NLDDButton = class NLDDButton extends withTranslations(LitEle
775
778
  this.horizontalAlignment = "";
776
779
  this.width = "";
777
780
  this.maxWidth = "";
781
+ this.noTab = false;
778
782
  this.expandable = false;
779
783
  this.expanded = false;
780
784
  this.type = "button";
@@ -839,7 +843,7 @@ var NLDDButton = (_NLDDButton = class NLDDButton extends withTranslations(LitEle
839
843
  this.shadowRoot?.querySelector(".button")?.focus(options);
840
844
  }
841
845
  render() {
842
- return template$22.call(this, { handleClick: this._handleClick.bind(this) });
846
+ return template$23.call(this, { handleClick: this._handleClick.bind(this) });
843
847
  }
844
848
  }, _NLDDButton.styles = buttonStyles, _NLDDButton.formAssociated = true, _NLDDButton);
845
849
  __decorate([property({
@@ -864,6 +868,11 @@ __decorate([property({
864
868
  attribute: "max-width",
865
869
  converter: reflectNonDefault("")
866
870
  })], NLDDButton.prototype, "maxWidth", void 0);
871
+ __decorate([property({
872
+ type: Boolean,
873
+ reflect: true,
874
+ attribute: "no-tab"
875
+ })], NLDDButton.prototype, "noTab", void 0);
867
876
  __decorate([property({
868
877
  type: Boolean,
869
878
  reflect: true,
@@ -1050,7 +1059,7 @@ var splitButtonStyles = css`
1050
1059
  `;
1051
1060
  //#endregion
1052
1061
  //#region src/components/actions/split-button/split-button.template.ts
1053
- function template$21() {
1062
+ function template$22() {
1054
1063
  return html`
1055
1064
  <div class="split-button">
1056
1065
  <nldd-button
@@ -1832,7 +1841,7 @@ var iconCellStyles = css`
1832
1841
  `;
1833
1842
  //#endregion
1834
1843
  //#region src/components/lists-and-tables/cells/icon-cell/icon-cell.template.ts
1835
- function template$20() {
1844
+ function template$21() {
1836
1845
  return html`
1837
1846
  ${this.icon ? html`<nldd-icon name=${this.icon}></nldd-icon>` : html`<slot></slot>`}
1838
1847
  `;
@@ -1865,7 +1874,7 @@ var NLDDIconCell = (_NLDDIconCell = class NLDDIconCell extends VisibilityMixin(L
1865
1874
  this.icon = "";
1866
1875
  }
1867
1876
  render() {
1868
- return template$20.call(this);
1877
+ return template$21.call(this);
1869
1878
  }
1870
1879
  }, _NLDDIconCell.styles = iconCellStyles, _NLDDIconCell);
1871
1880
  __decorate([property({
@@ -2207,7 +2216,7 @@ function renderQueryMark(text, query, mode = "predictive") {
2207
2216
  }
2208
2217
  //#endregion
2209
2218
  //#region src/components/lists-and-tables/cells/text-cell/text-cell.template.ts
2210
- function template$19() {
2219
+ function template$20() {
2211
2220
  return html`
2212
2221
  <p
2213
2222
  class="text-cell__overline"
@@ -2342,7 +2351,7 @@ var NLDDTextCell = (_NLDDTextCell = class NLDDTextCell extends VisibilityMixin(L
2342
2351
  else this.style.removeProperty("--_min-height");
2343
2352
  }
2344
2353
  render() {
2345
- return template$19.call(this);
2354
+ return template$20.call(this);
2346
2355
  }
2347
2356
  }, _NLDDTextCell.styles = [textCellStyles], _NLDDTextCell);
2348
2357
  __decorate([property({
@@ -2549,7 +2558,7 @@ var keyboardShortcutStyles = css`
2549
2558
  `;
2550
2559
  //#endregion
2551
2560
  //#region src/components/content/keyboard-shortcut/keyboard-shortcut.template.ts
2552
- function template$18(component) {
2561
+ function template$19(component) {
2553
2562
  const keys = component._parsedKeys;
2554
2563
  if (keys.length === 0) return html`
2555
2564
  <kbd class="keyboard-shortcut">
@@ -2663,7 +2672,7 @@ var NLDDKeyboardShortcut = (_NLDDKeyboardShortcut = class NLDDKeyboardShortcut e
2663
2672
  return spec.replace(/\+\+\+/g, `+${MARKER}+`).split("+").map((k) => k.trim().replace(new RegExp(MARKER, "g"), "+")).filter(Boolean);
2664
2673
  }
2665
2674
  render() {
2666
- return template$18(this);
2675
+ return template$19(this);
2667
2676
  }
2668
2677
  }, _NLDDKeyboardShortcut.styles = keyboardShortcutStyles, _NLDDKeyboardShortcut);
2669
2678
  __decorate([property({
@@ -2932,7 +2941,7 @@ var buttonGroupStyles = css`
2932
2941
  `;
2933
2942
  //#endregion
2934
2943
  //#region src/components/actions/button-group/button-group.template.ts
2935
- function template$17() {
2944
+ function template$18() {
2936
2945
  return html`
2937
2946
  <div class="button-group">
2938
2947
  <slot @slotchange=${this.handleSlotChange}></slot>
@@ -2973,7 +2982,7 @@ var NLDDButtonGroup = (_NLDDButtonGroup = class NLDDButtonGroup extends LitEleme
2973
2982
  if (changedProperties.has("orientation") || changedProperties.has("size")) this.handleSlotChange();
2974
2983
  }
2975
2984
  render() {
2976
- return template$17.call(this);
2985
+ return template$18.call(this);
2977
2986
  }
2978
2987
  }, _NLDDButtonGroup.styles = buttonGroupStyles, _NLDDButtonGroup);
2979
2988
  __decorate([property({
@@ -4549,7 +4558,7 @@ var NLDDSplitButton = (_NLDDSplitButton = class NLDDSplitButton extends LitEleme
4549
4558
  }
4550
4559
  }
4551
4560
  render() {
4552
- return template$21.call(this);
4561
+ return template$22.call(this);
4553
4562
  }
4554
4563
  }, _NLDDSplitButton.styles = splitButtonStyles, _NLDDSplitButton);
4555
4564
  __decorate([property({
@@ -4693,7 +4702,7 @@ var buttonBarStyles = css`
4693
4702
  `;
4694
4703
  //#endregion
4695
4704
  //#region src/components/actions/button-bar/button-bar.template.ts
4696
- function template$16() {
4705
+ function template$17() {
4697
4706
  return html`
4698
4707
  <div class="button-bar"
4699
4708
  part="bar"
@@ -4826,7 +4835,7 @@ var NLDDButtonBar = (_NLDDButtonBar = class NLDDButtonBar extends LitElement {
4826
4835
  this._building = false;
4827
4836
  }
4828
4837
  render() {
4829
- return template$16.call(this);
4838
+ return template$17.call(this);
4830
4839
  }
4831
4840
  }, _NLDDButtonBar.styles = buttonBarStyles, _NLDDButtonBar);
4832
4841
  __decorate([property({
@@ -5245,7 +5254,7 @@ function toolbarTitleTemplate(component) {
5245
5254
  <slot name="action"></slot>
5246
5255
  `;
5247
5256
  }
5248
- function template$15(component, hasCenterChildren, leftSpacerZero, rightSpacerZero, isSoloFluidItem, hasOverflow, menuOpen, label, centerOnly, t) {
5257
+ function template$16(component, hasCenterChildren, leftSpacerZero, rightSpacerZero, isSoloFluidItem, hasOverflow, menuOpen, label, centerOnly, t) {
5249
5258
  return html`
5250
5259
  <div class="toolbar"
5251
5260
  role="toolbar"
@@ -5959,7 +5968,7 @@ var NLDDToolbar = (_NLDDToolbar = class NLDDToolbar extends LitElement {
5959
5968
  render() {
5960
5969
  const visibleNonDivider = this._allHostChildren().filter((c) => !this._overflowIds.has(c.id));
5961
5970
  const isSoloFluid = this._soloFluid || visibleNonDivider.length === 1 && (visibleNonDivider[0].type === "title" || visibleNonDivider[0].type === "item" && visibleNonDivider[0].isFluid);
5962
- return template$15(this, this._centerChildren.length > 0, this._leftSpacerZero, this._rightSpacerZero, isSoloFluid, this._pinnedOverflowItems.length > 0 || this._overflowIds.size > 0, this._menuOpen, this.label, this._centerOnly, (key) => this._t(key));
5971
+ return template$16(this, this._centerChildren.length > 0, this._leftSpacerZero, this._rightSpacerZero, isSoloFluid, this._pinnedOverflowItems.length > 0 || this._overflowIds.size > 0, this._menuOpen, this.label, this._centerOnly, (key) => this._t(key));
5963
5972
  }
5964
5973
  }, _NLDDToolbar.styles = toolbarStyles, _NLDDToolbar);
5965
5974
  __decorate([property({
@@ -6061,8 +6070,12 @@ var avatarStyles = css`
6061
6070
  nldd-activity-indicator. The fill (not the text) color must resolve here,
6062
6071
  so .avatar keeps its inherited color and the contrast text lives on the
6063
6072
  child elements. */
6073
+ /* color on the host: the contrast token reads currentColor, so the flip has to
6074
+ be computed against the same value the fill uses. */
6064
6075
  :host([color="inherit"]) {
6065
- --_background-color: var(--context-content-color, currentColor);
6076
+ color: var(--context-content-color, currentColor);
6077
+
6078
+ --_background-color: currentColor;
6066
6079
  --_content-color: var(--semantics-content-contrast-color);
6067
6080
  }
6068
6081
 
@@ -6536,7 +6549,7 @@ var blockquoteStyles = css`
6536
6549
  `;
6537
6550
  //#endregion
6538
6551
  //#region src/components/content/blockquote/blockquote.template.ts
6539
- function template$14(component) {
6552
+ function template$15(component) {
6540
6553
  return html`
6541
6554
  <blockquote class="blockquote"
6542
6555
  cite=${component.cite || nothing}
@@ -6583,7 +6596,7 @@ var NLDDBlockquote = (_NLDDBlockquote = class NLDDBlockquote extends LitElement
6583
6596
  };
6584
6597
  }
6585
6598
  render() {
6586
- return template$14(this);
6599
+ return template$15(this);
6587
6600
  }
6588
6601
  }, _NLDDBlockquote.styles = blockquoteStyles, _NLDDBlockquote);
6589
6602
  __decorate([property({ type: String })], NLDDBlockquote.prototype, "cite", void 0);
@@ -8399,7 +8412,7 @@ var listStyles = css`
8399
8412
  `;
8400
8413
  //#endregion
8401
8414
  //#region src/components/lists-and-tables/list/list.template.ts
8402
- var template$13 = ({ itemsLabel, hasToolbar, type, isEmpty, emptyText, emptySupportingText, listbox }) => {
8415
+ var template$14 = ({ itemsLabel, hasToolbar, type, isEmpty, emptyText, emptySupportingText, listbox }) => {
8403
8416
  const isNavigation = type === "navigation";
8404
8417
  const isListbox = type === "listbox";
8405
8418
  const skipItemsLabel = isNavigation || isListbox;
@@ -8517,7 +8530,6 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
8517
8530
  this.type = "list";
8518
8531
  this.reorderable = false;
8519
8532
  this.dividers = "always";
8520
- this.arrowNavigation = false;
8521
8533
  this.height = "";
8522
8534
  this.emptyText = "";
8523
8535
  this.emptySupportingText = "";
@@ -8700,7 +8712,7 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
8700
8712
  if (!mutations.some((m) => {
8701
8713
  if (m.type === "childList") return m.target === this || isRow(m.target);
8702
8714
  if (m.type !== "attributes" || !isRow(m.target)) return false;
8703
- if (m.attributeName === "expanded") return true;
8715
+ if (m.attributeName === "expanded" || m.attributeName === "disabled") return true;
8704
8716
  return m.attributeName === "hidden" && (m.target.parentElement === this || isRow(m.target.parentElement));
8705
8717
  })) return;
8706
8718
  this._updateItems();
@@ -8710,7 +8722,11 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
8710
8722
  childList: true,
8711
8723
  subtree: true,
8712
8724
  attributes: true,
8713
- attributeFilter: ["hidden", "expanded"]
8725
+ attributeFilter: [
8726
+ "hidden",
8727
+ "expanded",
8728
+ "disabled"
8729
+ ]
8714
8730
  });
8715
8731
  this._applyHostType();
8716
8732
  }
@@ -8734,7 +8750,7 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
8734
8750
  this._cancelDrag();
8735
8751
  }
8736
8752
  updated(changed) {
8737
- if (changed.has("reorderable") || changed.has("type") || changed.has("arrowNavigation")) {
8753
+ if (changed.has("reorderable") || changed.has("type")) {
8738
8754
  if (this.reorderable && this.type !== "list" && false);
8739
8755
  this._updateItems();
8740
8756
  this._warnArrowNav();
@@ -8900,30 +8916,38 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
8900
8916
  this._emitListboxInput("");
8901
8917
  this._searchInput?.focus();
8902
8918
  }
8903
- /** Arrow-navigation is effective only when reorderable isn't already claiming
8904
- * the arrow keys for drag-reorder (reorderable wins). The guard also checks
8905
- * `type === 'list'` on purpose: reorderable is inert without it, so there is no
8906
- * conflict to resolve. `arrow-navigation reorderable` without `type="list"`
8907
- * therefore keeps arrow-nav active (reorderable does nothing), and
8908
- * `_warnArrowNav` likewise only warns for the real reorderable-list conflict. */
8919
+ /**
8920
+ * Every list answers to the arrow keys. There is no switch for it, on purpose:
8921
+ * whether the keys do something is not a property of one list, it is what a
8922
+ * reader may assume about all of them, and a per-list setting made that
8923
+ * unknowable from the outside.
8924
+ *
8925
+ * Two lists answer differently, and you can see which before you touch a key:
8926
+ * a listbox has a search field and runs its own keyboard from there, and a
8927
+ * reorderable list uses the arrows to move rows. The guard checks
8928
+ * `type === 'list'` because reorderable is inert without it, so there is no
8929
+ * conflict to resolve.
8930
+ */
8909
8931
  get _arrowNavActive() {
8910
8932
  if (this.type === "listbox") return false;
8911
- if (this.type === "tree") return true;
8912
- return this.arrowNavigation && !(this.reorderable && this.type === "list");
8933
+ return !(this.reorderable && this.type === "list");
8913
8934
  }
8914
8935
  /** Interactive, painted rows — the roving stops, in the order they appear on
8915
- * screen. Non-interactive rows (no link/button) and hidden ones are skipped.
8936
+ * screen. Rows with nothing to operate and hidden ones are skipped.
8916
8937
  * Painted, not top-level: in a tree the rows of an open branch sit between
8917
8938
  * the branch and the next top-level row, and arrows have to walk them too. */
8918
8939
  _getInteractiveItems() {
8919
8940
  const painted = this._getPaintedRows();
8920
8941
  if (this.type === "tree") return painted;
8921
- return painted.filter((row) => Boolean(row.href || row.button));
8942
+ return painted.filter((row) => row._isRovingStop);
8922
8943
  }
8923
8944
  /** Push roving state onto the items, deferred to a microtask: _updateItems can
8924
8945
  * run inside the update lifecycle (firstUpdated/updated), and setting the
8925
8946
  * items' reactive state there would trip Lit's change-in-update warning.
8926
- * Coalesced so repeated item updates schedule it only once. */
8947
+ * Coalesced so repeated item updates schedule it only once.
8948
+ *
8949
+ * @internal Also called by a row whose content changed after the stops were
8950
+ * picked. */
8927
8951
  _updateRoving() {
8928
8952
  if (this._rovingScheduled) return;
8929
8953
  this._rovingScheduled = true;
@@ -8941,7 +8965,8 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
8941
8965
  rows.forEach((row) => {
8942
8966
  row._arrowNavigation = active;
8943
8967
  });
8944
- if (active) {
8968
+ const interactive = active ? this._getInteractiveItems() : [];
8969
+ if (interactive.length > 0) {
8945
8970
  this.setAttribute("aria-keyshortcuts", "ArrowUp ArrowDown Home End");
8946
8971
  this.setAttribute("aria-description", this._t("components.list.arrow-navigation-description-text"));
8947
8972
  } else {
@@ -8954,7 +8979,6 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
8954
8979
  });
8955
8980
  return;
8956
8981
  }
8957
- const interactive = this._getInteractiveItems();
8958
8982
  if (interactive.length === 0) return;
8959
8983
  const entry = interactive.find((row) => row._rovingActive) ?? interactive.find((row) => row.selected) ?? interactive[0];
8960
8984
  rows.forEach((row) => {
@@ -9023,15 +9047,26 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
9023
9047
  event.preventDefault();
9024
9048
  this._moveRovingTo(parent);
9025
9049
  }
9026
- /** Tree only: Enter and Space open and close the row, the same thing Right and
9027
- * Left do. Only when focus sits on the row ITSELF a row that is its own
9028
- * control, and a segmented action you tabbed into, handle both keys
9029
- * natively, and acting here as well would toggle twice. */
9050
+ /**
9051
+ * Tree only, and only while focus sits on the row ITSELF: a row that is its
9052
+ * own control, and a segment you tabbed into, handle both keys
9053
+ * natively, and acting here as well would fire twice.
9054
+ *
9055
+ * Enter does what the row is for — it follows the row's own link or button,
9056
+ * or on a branch cut into segments the first one that is not the chevron.
9057
+ * Space folds, the same thing Right and Left do, because a chevron is a
9058
+ * button and Space is what a button answers to. A branch with nothing but a
9059
+ * chevron takes Enter for folding too, so the key is never dead.
9060
+ */
9030
9061
  _onTreeActivate(event) {
9031
9062
  const target = event.target;
9032
9063
  if (!(target instanceof Element) || target.tagName.toLowerCase() !== "nldd-list-item") return;
9033
9064
  const row = target;
9034
9065
  if (row.shadowRoot?.activeElement) return;
9066
+ if (event.key === "Enter" && row._activatePrimary()) {
9067
+ event.preventDefault();
9068
+ return;
9069
+ }
9035
9070
  if (row._activateDisclosure()) event.preventDefault();
9036
9071
  }
9037
9072
  _moveRovingTo(row) {
@@ -9161,7 +9196,7 @@ var NLDDList = (_NLDDList2 = class NLDDList extends LitElement {
9161
9196
  }));
9162
9197
  }
9163
9198
  render() {
9164
- return template$13({
9199
+ return template$14({
9165
9200
  itemsLabel: this.accessibleLabel || this._t("components.list.items-accessible-label"),
9166
9201
  hasToolbar: this._hasToolbar,
9167
9202
  type: this.type,
@@ -9202,11 +9237,6 @@ __decorate([property({
9202
9237
  reflect: true,
9203
9238
  converter: reflectNonDefault("always")
9204
9239
  })], NLDDList.prototype, "dividers", void 0);
9205
- __decorate([property({
9206
- type: Boolean,
9207
- reflect: true,
9208
- attribute: "arrow-navigation"
9209
- })], NLDDList.prototype, "arrowNavigation", void 0);
9210
9240
  __decorate([property({
9211
9241
  type: String,
9212
9242
  reflect: true
@@ -9267,8 +9297,6 @@ var listItemStyles = css`
9267
9297
  --context-list-item-size: var(--semantics-controls-sm-min-size);
9268
9298
  }
9269
9299
 
9270
- /* An interactive row widens by the indicator inset and pads the block back,
9271
- so the content stays on the grid while the fill covers the wider box. */
9272
9300
  :host(.is-interactive) {
9273
9301
  /* Not the host's 100%: a width plus negative margins is over-constrained
9274
9302
  in block layout, so the row would shift instead of widen. */
@@ -9287,13 +9315,13 @@ var listItemStyles = css`
9287
9315
  padding-inline: 0;
9288
9316
  }
9289
9317
 
9290
- /* A segmented action at a row edge already owns the padding for that side,
9318
+ /* A segment at a row edge already owns the padding for that side,
9291
9319
  so the row drops its own there. Mid-row it claims nothing. */
9292
- :host(.is-interactive.has-leading-action) .list-item {
9320
+ :host(.is-interactive.has-leading-segment) .list-item {
9293
9321
  padding-inline-start: 0;
9294
9322
  }
9295
9323
 
9296
- :host(.is-interactive.has-trailing-action) .list-item {
9324
+ :host(.is-interactive.has-trailing-segment) .list-item {
9297
9325
  padding-inline-end: 0;
9298
9326
  }
9299
9327
 
@@ -9378,6 +9406,14 @@ var listItemStyles = css`
9378
9406
  cursor: var(--semantics-controls-link-cursor);
9379
9407
  }
9380
9408
 
9409
+ /* There is no disabled attribute for an anchor, so the row blocks the click
9410
+ itself and aria-disabled carries the state. */
9411
+ button.list-item__action:disabled,
9412
+ :host([disabled]) a.list-item__action {
9413
+ cursor: default;
9414
+ opacity: var(--primitives-opacity-disabled);
9415
+ }
9416
+
9381
9417
  .list-item__opens-in-new-tab-hint {
9382
9418
  position: absolute;
9383
9419
  margin: -1px;
@@ -9392,9 +9428,7 @@ var listItemStyles = css`
9392
9428
 
9393
9429
 
9394
9430
 
9395
- /* The fill always covers the widened geometry: an interactive row is already
9396
- widened, a plain row bleeds outward by the same amount. It sits on the
9397
- control when the row is one, so hover / focus / press can drive it. */
9431
+ /* On the control when the row is one, so hover, focus and press can drive it. */
9398
9432
  .list-item:not(:has(.list-item__action))::before,
9399
9433
  .list-item__action::before {
9400
9434
  content: '';
@@ -9413,12 +9447,16 @@ var listItemStyles = css`
9413
9447
  inset-inline: 0;
9414
9448
  }
9415
9449
 
9416
- :host([selected]) {
9450
+ /* data-current is set by the row itself when one of its own segments carries
9451
+ current, so a segmented row paints without one on the host. */
9452
+ :host(:is([selected], [checkbox][checked])),
9453
+ :host(:is([current], [data-current])) {
9417
9454
  --_background-color: var(--components-list-item-is-selected-background-color);
9418
9455
  --context-content-color: var(--components-list-item-is-selected-content-color);
9419
9456
  --context-content-secondary-color: var(--components-list-item-is-selected-content-color);
9420
9457
  }
9421
9458
 
9459
+
9422
9460
  /* A checked checkbox action selects the whole row, so the fill runs across
9423
9461
  the disclosure action too instead of stopping at its boundary. */
9424
9462
  .list-item.is-action-checked {
@@ -9427,49 +9465,124 @@ var listItemStyles = css`
9427
9465
  --context-content-secondary-color: var(--components-list-item-is-selected-content-color);
9428
9466
  }
9429
9467
 
9430
- /* hover only on hover-capable devices: avoids touch-scroll flashing the
9431
- hover state on the row under the finger */
9468
+ /* Hover only on hover-capable devices, so a touch that turns into a scroll
9469
+ does not flash the row under the finger.
9470
+
9471
+ The row hands its rung down to its segments through the two context
9472
+ variables at the end of each block: a segmented row has no control of its
9473
+ own, so the segment paints, and it must paint on the same scale as the
9474
+ row it sits in. */
9432
9475
  @media (hover: hover) {
9433
- .list-item__action:hover {
9476
+ :host(:not([disabled])) .list-item__action:hover {
9434
9477
  --_background-color: var(--components-list-item-is-hovered-background-color);
9435
9478
  --context-content-color: var(--components-list-item-is-hovered-content-color);
9436
9479
  --context-content-secondary-color: var(--components-list-item-is-hovered-content-color);
9437
9480
  }
9438
9481
 
9439
- :host([selected]) .list-item__action:hover {
9440
- --_background-color: var(--components-list-item-is-selected-background-color);
9482
+ :host(:is([selected], [checkbox][checked]):not([disabled])) .list-item__action:hover,
9483
+ :host(:is([current], [data-current]):not([disabled])) .list-item__action:hover {
9484
+ --_background-color: var(--components-list-item-is-selected-is-hovered-background-color);
9441
9485
  --context-content-color: var(--components-list-item-is-selected-content-color);
9442
9486
  --context-content-secondary-color: var(--components-list-item-is-selected-content-color);
9443
9487
  }
9488
+ }
9444
9489
 
9445
- :host([selected]) .list-item__action:focus:hover {
9446
- --_background-color: var(--components-list-item-is-highlighted-background-color);
9447
- --context-content-color: var(--components-list-item-is-highlighted-content-color);
9448
- --context-content-secondary-color: var(--components-list-item-is-highlighted-content-color);
9490
+ :host(:is([selected], [checkbox][checked])) {
9491
+ --context-list-item-hovered-background-color: var(--components-list-item-is-selected-is-hovered-background-color);
9492
+ --context-list-item-hovered-content-color: var(--components-list-item-is-selected-content-color);
9493
+ --context-list-item-active-background-color: var(--components-list-item-is-selected-is-active-background-color);
9494
+ }
9495
+
9496
+ /* Pressing the row you are on lands on the accent whether or not focus got
9497
+ there first. Safari does not focus a button on click, and a press that
9498
+ waits for focus would go grey there while the other browsers go accent.
9499
+ Hover still follows the focus: that is the state, not the gesture. */
9500
+ :host(:is([current], [data-current])) {
9501
+ --context-list-item-hovered-background-color: var(--components-list-item-is-selected-is-hovered-background-color);
9502
+ --context-list-item-hovered-content-color: var(--components-list-item-is-selected-content-color);
9503
+ --context-list-item-active-background-color: var(--components-list-item-is-highlighted-is-active-background-color);
9504
+ --context-list-item-active-content-color: var(--components-list-item-is-highlighted-content-color);
9505
+ }
9506
+
9507
+ /* focus-within on the host, not on the row-wide control: focus inside a
9508
+ nested nldd-list-item-segment has to match, and a segmented row has no
9509
+ control of its own to key off.
9510
+
9511
+ After the hover rules on purpose: a pointer that lands on the row is
9512
+ hovering it as well, and the state it just gave focus to has to win. */
9513
+ :host(:is([current], [data-current]):focus-within) .list-item,
9514
+ :host(:is([current], [data-current]):focus-within) .list-item__action {
9515
+ --context-content-color: var(--components-list-item-is-highlighted-content-color);
9516
+ --context-content-secondary-color: var(--components-list-item-is-highlighted-content-color);
9517
+ }
9518
+
9519
+ :host(:is([current], [data-current]):focus-within) {
9520
+ --context-list-item-hovered-background-color: var(--components-list-item-is-highlighted-is-hovered-background-color);
9521
+ --context-list-item-hovered-content-color: var(--components-list-item-is-highlighted-content-color);
9522
+ --context-list-item-active-background-color: var(--components-list-item-is-highlighted-is-active-background-color);
9523
+ }
9524
+
9525
+ :host(:is([current], [data-current]):focus-within) .list-item::before,
9526
+ :host(:is([current], [data-current]):focus-within) .list-item__action::before {
9527
+ background-color: var(--components-list-item-is-highlighted-background-color);
9528
+ }
9529
+
9530
+ /* Only the row-wide control, never the row itself: on a segmented row the
9531
+ hovered segment deepens on its own, and a row that darkened as a whole
9532
+ would hide which segment you are on. */
9533
+ @media (hover: hover) {
9534
+ :host(:is([current], [data-current]):focus-within:not([disabled])) .list-item__action:hover::before {
9535
+ background-color: var(--components-list-item-is-highlighted-is-hovered-background-color);
9449
9536
  }
9450
9537
  }
9451
9538
 
9539
+ /* Two selectors, because pressing means hovering too and the hover rule
9540
+ above carries a pseudo-class more: the focused one has to match its
9541
+ weight to win, and the plain one catches Safari, where the mouse being
9542
+ down means the row is not focused at all. */
9543
+ :host(:is([current], [data-current]):not([disabled])) .list-item__action.is-pressed::before,
9544
+ :host(:is([current], [data-current]):focus-within:not([disabled])) .list-item__action.is-pressed::before {
9545
+ background-color: var(--components-list-item-is-highlighted-is-active-background-color);
9546
+ }
9547
+
9548
+ /* The content colour has to travel with the fill: the neutral press rule
9549
+ above sets it too, and black on a deep accent is unreadable. */
9550
+ :host(:is([current], [data-current]):focus-within:not([disabled])) .list-item__action:hover {
9551
+ --context-content-color: var(--components-list-item-is-highlighted-content-color);
9552
+ --context-content-secondary-color: var(--components-list-item-is-highlighted-content-color);
9553
+ }
9554
+
9452
9555
  /* JS-driven rather than :active, so a touch that turns into a scroll clears
9453
9556
  the press (pointercancel) instead of flashing it. */
9454
- .list-item__action.is-pressed {
9455
- --_background-color: var(--components-list-item-is-hovered-background-color);
9456
- --context-content-color: var(--components-list-item-is-hovered-content-color);
9457
- --context-content-secondary-color: var(--components-list-item-is-hovered-content-color);
9557
+ :host(:not([disabled])) .list-item__action.is-pressed {
9558
+ --_background-color: var(--components-list-item-is-active-background-color);
9559
+ --context-content-color: var(--components-list-item-is-active-content-color);
9560
+ --context-content-secondary-color: var(--components-list-item-is-active-content-color);
9458
9561
  }
9459
9562
 
9460
- :host([selected]) .list-item__action {
9563
+ :host(:is([selected], [checkbox][checked]):not([disabled])) .list-item__action.is-pressed,
9564
+ :host(:is([current], [data-current]):not([disabled])) .list-item__action.is-pressed {
9565
+ --_background-color: var(--components-list-item-is-selected-is-active-background-color);
9566
+ --context-content-color: var(--components-list-item-is-selected-content-color);
9567
+ --context-content-secondary-color: var(--components-list-item-is-selected-content-color);
9568
+ }
9569
+
9570
+ :host(:is([selected], [checkbox][checked])) .list-item__action {
9461
9571
  --_background-color: var(--components-list-item-is-selected-background-color);
9462
9572
  --context-content-color: var(--components-list-item-is-selected-content-color);
9463
9573
  --context-content-secondary-color: var(--components-list-item-is-selected-content-color);
9464
9574
  }
9465
9575
 
9466
- /* The strongest fill: a selected row that is pressed or focused, and the
9467
- listbox active descendant (.is-highlighted, set by the list because focus
9468
- stays in the search input). */
9469
- :host([selected]) .list-item__action.is-pressed,
9470
- :host([selected]) .list-item__action:focus,
9576
+ /* .is-highlighted is set by the list: in a listbox the focus stays in the
9577
+ search input, so the option cannot carry the state itself. */
9578
+ /* After the neutral press rules above, or black lands on a deep accent. */
9579
+ :host(:is([current], [data-current]):not([disabled])) .list-item__action.is-pressed {
9580
+ --context-content-color: var(--components-list-item-is-highlighted-content-color);
9581
+ --context-content-secondary-color: var(--components-list-item-is-highlighted-content-color);
9582
+ }
9583
+
9471
9584
  .list-item.is-highlighted,
9472
- :host([selected]) .list-item.is-highlighted .list-item__action {
9585
+ :host(:is([selected], [checkbox][checked])) .list-item.is-highlighted .list-item__action {
9473
9586
  --_background-color: var(--components-list-item-is-highlighted-background-color);
9474
9587
  --context-content-color: var(--components-list-item-is-highlighted-content-color);
9475
9588
  --context-content-secondary-color: var(--components-list-item-is-highlighted-content-color);
@@ -9499,9 +9612,8 @@ var listItemStyles = css`
9499
9612
  outline: none;
9500
9613
  }
9501
9614
 
9502
- /* A row that is itself the disclosure control turns the chevron: mark its
9503
- icon-cell disclosure. The cell rotates, not the icon ::slotted reaches a
9504
- direct child only, and rotating the cell turns the glyph in place. */
9615
+ /* The cell rotates, not the icon: ::slotted reaches a direct child only, and
9616
+ rotating the cell turns the glyph in place. */
9505
9617
  ::slotted(nldd-icon-cell[disclosure]) {
9506
9618
  rotate: 0deg;
9507
9619
  transition: rotate var(--primitives-transition-duration-fast) var(--primitives-transition-easing-default);
@@ -9537,10 +9649,10 @@ var listItemStyles = css`
9537
9649
  /* Content-wide by default; the divider-start/divider-end cell markers
9538
9650
  override it through the measured --_divider-inset-* vars. */
9539
9651
 
9540
- /* A segmented action with focus paints its ring past its own box, and the
9652
+ /* A segment with focus paints its ring past its own box, and the
9541
9653
  divider is rendered after the slot — so without this the line ran straight
9542
9654
  through the ring. Lifting the focused action puts the ring on top. */
9543
- ::slotted(nldd-list-item-action:focus-within) {
9655
+ ::slotted(nldd-list-item-segment:focus-within) {
9544
9656
  z-index: var(--_focus-z-index);
9545
9657
  }
9546
9658
 
@@ -9575,7 +9687,7 @@ var listItemStyles = css`
9575
9687
  //#region src/components/lists-and-tables/list-item/list-item.template.ts
9576
9688
  var content = html`<slot></slot>`;
9577
9689
  var divider = html`<div class="list-item__divider"></div>`;
9578
- var template$12 = (button, href, target, rel, opensInNewTabLabel, actionTabindex, isHighlighted = false, checkbox = false, checked = false, expanded, showChildren = false, hasCheckedSegment = false) => {
9690
+ var template$13 = (button, href, target, rel, opensInNewTabLabel, actionTabindex, isHighlighted = false, checkbox = false, checked = false, expanded, showChildren = false, hasCheckedSegment = false, disabled = false) => {
9579
9691
  const ariaExpanded = expanded === void 0 ? nothing : String(expanded);
9580
9692
  const children = showChildren ? html`<div class="list-item__children"
9581
9693
  role="group"
@@ -9591,6 +9703,7 @@ var template$12 = (button, href, target, rel, opensInNewTabLabel, actionTabindex
9591
9703
  href=${href}
9592
9704
  target=${target ?? nothing}
9593
9705
  rel=${rel ?? nothing}
9706
+ aria-disabled=${disabled ? "true" : nothing}
9594
9707
  aria-expanded=${ariaExpanded}
9595
9708
  tabindex=${actionTabindex ?? nothing}
9596
9709
  >${content}${opensInNewTabLabel ? html`<span class="list-item__opens-in-new-tab-hint">${opensInNewTabLabel}</span>` : nothing}</a>
@@ -9600,6 +9713,7 @@ var template$12 = (button, href, target, rel, opensInNewTabLabel, actionTabindex
9600
9713
  <button class="list-item__action"
9601
9714
  type="button"
9602
9715
  role="checkbox"
9716
+ ?disabled=${disabled}
9603
9717
  aria-checked=${String(checked)}
9604
9718
  aria-expanded=${ariaExpanded}
9605
9719
  tabindex=${actionTabindex ?? nothing}
@@ -9609,6 +9723,7 @@ var template$12 = (button, href, target, rel, opensInNewTabLabel, actionTabindex
9609
9723
  if (button) return html`<div class=${blockClass}>
9610
9724
  <button class="list-item__action"
9611
9725
  type="button"
9726
+ ?disabled=${disabled}
9612
9727
  aria-expanded=${ariaExpanded}
9613
9728
  tabindex=${actionTabindex ?? nothing}
9614
9729
  >${content}</button>
@@ -9627,14 +9742,66 @@ var nlddListItemTranslations = { "components.list-item.opens-in-new-tab-label":
9627
9742
  var list_item_exports = /* @__PURE__ */ __exportAll({ NLDDListItem: () => NLDDListItem });
9628
9743
  var _NLDDListItem2;
9629
9744
  var _NLDDListItem;
9745
+ /** Anything in a row's light DOM that is a tab stop of its own. `[tabindex]`
9746
+ * counts because an authored one makes any element focusable; the value itself
9747
+ * is read per element, and put back when the row becomes the current one. */
9748
+ var OWN_TAB_STOP = "a[href], button, input, select, textarea, [contenteditable]:not([contenteditable=\"false\"]), [tabindex]";
9749
+ /** Keyed on the element, so a row that is re-rendered around the same control
9750
+ * still knows what the consumer authored. */
9751
+ var authoredTabState = /* @__PURE__ */ new WeakMap();
9752
+ function authoredStateOf(el) {
9753
+ let authored = authoredTabState.get(el);
9754
+ if (!authored) {
9755
+ authored = {
9756
+ noTab: "noTab" in el ? el.noTab : void 0,
9757
+ tabindex: el.getAttribute("tabindex")
9758
+ };
9759
+ authoredTabState.set(el, authored);
9760
+ }
9761
+ return authored;
9762
+ }
9763
+ function applyAuthoredTabState(el, authored) {
9764
+ if (authored.noTab !== void 0) {
9765
+ el.noTab = authored.noTab;
9766
+ return;
9767
+ }
9768
+ if (authored.tabindex === null) el.removeAttribute("tabindex");
9769
+ else el.setAttribute("tabindex", authored.tabindex);
9770
+ }
9771
+ /**
9772
+ * Puts one control in or out of the tab order on behalf of the row it sits in.
9773
+ *
9774
+ * A design-system control keeps its tab stop inside its own shadow root, where
9775
+ * a tabindex on the host cannot reach it, so it carries `no-tab` for exactly
9776
+ * this. Everything else is native and takes the tabindex directly. A consumer
9777
+ * who set either themselves keeps it: their `no-tab` or `tabindex="-1"` is a
9778
+ * decision, not a leftover.
9779
+ */
9780
+ function setTabbable(el, tabbable) {
9781
+ const authored = authoredStateOf(el);
9782
+ if (authored.noTab !== void 0) {
9783
+ el.noTab = authored.noTab || !tabbable;
9784
+ return;
9785
+ }
9786
+ if (tabbable) applyAuthoredTabState(el, authored);
9787
+ else el.setAttribute("tabindex", "-1");
9788
+ }
9789
+ function releaseTabbable(el) {
9790
+ const authored = authoredTabState.get(el);
9791
+ if (!authored) return;
9792
+ applyAuthoredTabState(el, authored);
9793
+ authoredTabState.delete(el);
9794
+ }
9630
9795
  var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations(LitElement, nlddListItemTranslations) {
9631
9796
  constructor(..._args) {
9632
9797
  super(..._args);
9633
9798
  this.size = "md";
9634
9799
  this.selected = false;
9800
+ this.current = false;
9635
9801
  this.button = false;
9636
9802
  this.checkbox = false;
9637
9803
  this.checked = false;
9804
+ this.disabled = false;
9638
9805
  this.reorderable = false;
9639
9806
  this._showChildren = false;
9640
9807
  this._parentType = "list";
@@ -9644,11 +9811,17 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9644
9811
  this._isBoxed = false;
9645
9812
  this._hasCheckedSegment = false;
9646
9813
  this._lightDomObserver = null;
9814
+ this._rovingControlsCache = null;
9647
9815
  this._dividerMarkerObserver = null;
9648
9816
  this._observedMarkerTargets = [];
9649
9817
  this._warnedDegenerateDivider = false;
9650
9818
  this._ownCellSize = /* @__PURE__ */ new WeakMap();
9651
9819
  this._handleClick = (e) => {
9820
+ if (this.disabled) {
9821
+ e.preventDefault();
9822
+ e.stopPropagation();
9823
+ return;
9824
+ }
9652
9825
  this._action?.focus();
9653
9826
  if (this.checkbox && !this.href && e.composedPath().includes(this._action)) {
9654
9827
  this.checked = !this.checked;
@@ -9665,10 +9838,18 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9665
9838
  this._handleFocusOut = () => {
9666
9839
  this._action?.classList.remove("is-pointer-focus");
9667
9840
  };
9841
+ this._onMouseDown = (e) => {
9842
+ if (e.button > 0 || this.reorderable) return;
9843
+ if (this._isFromNestedRow(e)) return;
9844
+ if (!this._action) return;
9845
+ e.preventDefault();
9846
+ };
9668
9847
  this._onPointerDown = (e) => {
9848
+ if (this.disabled) return;
9669
9849
  if (e.button > 0) return;
9670
9850
  if (this._isFromNestedRow(e)) return;
9671
9851
  this._action?.classList.add("is-pressed");
9852
+ this._action?.focus({ preventScroll: true });
9672
9853
  };
9673
9854
  this._clearPressed = () => {
9674
9855
  this._action?.classList.remove("is-pressed");
@@ -9683,6 +9864,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9683
9864
  this.addEventListener("focusout", this._handleFocusOut);
9684
9865
  this.addEventListener("click", this._handleClick);
9685
9866
  this.addEventListener("pointerdown", this._onPointerDown);
9867
+ this.addEventListener("mousedown", this._onMouseDown);
9686
9868
  this.addEventListener("pointerup", this._clearPressed);
9687
9869
  this.addEventListener("pointercancel", this._clearPressed);
9688
9870
  this._lightDomObserver = new MutationObserver(() => this._onLightDomChange());
@@ -9692,6 +9874,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9692
9874
  attributes: true,
9693
9875
  attributeFilter: [
9694
9876
  "checked",
9877
+ "current",
9695
9878
  "divider-start",
9696
9879
  "divider-end"
9697
9880
  ]
@@ -9704,6 +9887,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9704
9887
  this.removeEventListener("focusout", this._handleFocusOut);
9705
9888
  this.removeEventListener("click", this._handleClick);
9706
9889
  this.removeEventListener("pointerdown", this._onPointerDown);
9890
+ this.removeEventListener("mousedown", this._onMouseDown);
9707
9891
  this.removeEventListener("pointerup", this._clearPressed);
9708
9892
  this.removeEventListener("pointercancel", this._clearPressed);
9709
9893
  this._lightDomObserver?.disconnect();
@@ -9713,32 +9897,100 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9713
9897
  }
9714
9898
  _onLightDomChange() {
9715
9899
  this._updateCheckedSegment();
9900
+ this._updateCurrentSegment();
9716
9901
  this._updateInteractive();
9717
9902
  this._measureDividerMarkers();
9903
+ this._rovingControlsCache = null;
9904
+ if (this._arrowNavigation) {
9905
+ this._syncRovingTabStops();
9906
+ this._parentList?._updateRoving();
9907
+ }
9908
+ }
9909
+ get _parentList() {
9910
+ return this.closest("nldd-list");
9911
+ }
9912
+ /**
9913
+ * The controls in this row that own a tab stop: a design-system control that
9914
+ * carries `no-tab`, or anything natively focusable. Segments are left
9915
+ * out — they have their own channel (`_tabbable`) — but a control slotted
9916
+ * inside one is not, so it is managed here.
9917
+ *
9918
+ * Custom elements that have not upgraded yet cannot answer whether they carry
9919
+ * `no-tab`, so the cache is dropped and the row re-syncs once they do.
9920
+ */
9921
+ _rovingControls() {
9922
+ if (this._rovingControlsCache) return this._rovingControlsCache;
9923
+ const pending = /* @__PURE__ */ new Set();
9924
+ const controls = this._ownDescendants("*").filter((el) => {
9925
+ const tag = el.tagName.toLowerCase();
9926
+ if (tag === "nldd-list-item-segment") return false;
9927
+ if (tag.includes("-") && !customElements.get(tag)) {
9928
+ pending.add(tag);
9929
+ return false;
9930
+ }
9931
+ return "noTab" in el || el.matches(OWN_TAB_STOP);
9932
+ });
9933
+ this._rovingControlsCache = controls;
9934
+ pending.forEach((tag) => {
9935
+ customElements.whenDefined(tag).then(() => {
9936
+ this._rovingControlsCache = null;
9937
+ if (this._arrowNavigation) this._syncRovingTabStops();
9938
+ });
9939
+ });
9940
+ return controls;
9941
+ }
9942
+ /**
9943
+ * Whether the arrow keys stop at this row.
9944
+ *
9945
+ * Anything you can operate makes a row a stop: its own link, button or
9946
+ * checkbox, a segment, or a control sitting in one of its cells. A
9947
+ * row of nothing but text is skipped, because focus that leads nowhere is a
9948
+ * dead end for a keyboard.
9949
+ *
9950
+ * @internal Read by the parent nldd-list.
9951
+ */
9952
+ get _isRovingStop() {
9953
+ if (this.disabled) return false;
9954
+ if (this.href || this.button || this.checkbox) return true;
9955
+ if (this._ownDescendants("nldd-list-item-segment:not([disabled])").length > 0) return true;
9956
+ return this._rovingControls().some((control) => !control.hasAttribute("disabled"));
9957
+ }
9958
+ /**
9959
+ * A segment marked `current` makes the whole row the current one.
9960
+ *
9961
+ * A row cut into segments has no control of its own, so `aria-current="page"`
9962
+ * belongs on the segment that holds the link. Written there, the row would
9963
+ * stay unpainted and the consumer had to set `current` twice, once for the
9964
+ * semantics and once for the colour, with nothing to catch the two drifting
9965
+ * apart. The row reads it off its own segments instead — reading, not
9966
+ * writing: the attributes stay the consumer's.
9967
+ */
9968
+ _updateCurrentSegment() {
9969
+ this.toggleAttribute("data-current", this._ownDescendants("nldd-list-item-segment[current]").length > 0);
9718
9970
  }
9719
9971
  /** A checked checkbox-segment reads as "this row is selected", so the fill
9720
9972
  * covers the whole row — including a disclosure segment — instead of
9721
- * stopping at the segmented action boundary. Scoped to own descendants: a checked
9973
+ * stopping at the segment boundary. Scoped to own descendants: a checked
9722
9974
  * row in a nested branch must not light up its ancestors. */
9723
9975
  _updateCheckedSegment() {
9724
- this._hasCheckedSegment = this._ownDescendants("nldd-list-item-action[checkbox][checked]").length > 0;
9976
+ this._hasCheckedSegment = this._ownDescendants("nldd-list-item-segment[checkbox][checked]").length > 0;
9725
9977
  }
9726
9978
  /** A row with any action — its own href/button/checkbox or a slotted
9727
9979
  * segment — carries the widened geometry: negative host margin plus the
9728
9980
  * compensating row padding (see the geometry rules in the class doc).
9729
9981
  *
9730
- * An action segment at a row edge owns the padding for that side itself,
9731
- * so the row drops its own there and the segmented action lands on the row's edge.
9982
+ * An segment at a row edge owns the padding for that side itself,
9983
+ * so the row drops its own there and the segment lands on the row's edge.
9732
9984
  * Stamped as classes because the CSS cannot ask: `:has()` is not allowed
9733
9985
  * inside `:host()`, and the row's own padding is what has to change — a
9734
- * `::slotted()` rule could only reach the segmented action. */
9986
+ * `::slotted()` rule could only reach the segment. */
9735
9987
  _updateInteractive() {
9736
- const interactive = !!this.href || this.button || this.checkbox || this._ownDescendants("nldd-list-item-action").length > 0;
9988
+ const interactive = !!this.href || this.button || this.checkbox || this._ownDescendants("nldd-list-item-segment").length > 0;
9737
9989
  this.classList.toggle("is-interactive", interactive);
9738
9990
  const ownChildren = Array.from(this.children).filter((el) => el.getAttribute("slot") !== "children");
9739
- const isSegment = (el) => el?.tagName.toLowerCase() === "nldd-list-item-action";
9740
- this.classList.toggle("has-leading-action", isSegment(ownChildren[0]));
9741
- this.classList.toggle("has-trailing-action", isSegment(ownChildren[ownChildren.length - 1]));
9991
+ const isSegment = (el) => el?.tagName.toLowerCase() === "nldd-list-item-segment";
9992
+ this.classList.toggle("has-leading-segment", isSegment(ownChildren[0]));
9993
+ this.classList.toggle("has-trailing-segment", isSegment(ownChildren[ownChildren.length - 1]));
9742
9994
  }
9743
9995
  firstUpdated() {
9744
9996
  if (this.hasAttribute("data-nldd-clone")) return;
@@ -9750,12 +10002,12 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9750
10002
  }
9751
10003
  /**
9752
10004
  * The row's own descendants for `selector` — everything down to and inside
9753
- * its action segmented actions, but NOT inside a nested row. In a tree the child rows
10005
+ * its segments, but NOT inside a nested row. In a tree the child rows
9754
10006
  * are DOM children of this row, so a plain querySelectorAll would push this
9755
10007
  * row's state into theirs (a parent's `expanded` turning every nested
9756
10008
  * chevron, its `size` overwriting theirs). A `:scope >` child selector is
9757
10009
  * too strict the other way: cells legitimately sit one level deeper, inside
9758
- * an nldd-list-item-action.
10010
+ * an nldd-list-item-segment.
9759
10011
  */
9760
10012
  _ownDescendants(selector) {
9761
10013
  return Array.from(this.querySelectorAll(selector)).filter((el) => el.closest("nldd-list-item") === this);
@@ -9786,13 +10038,17 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9786
10038
  });
9787
10039
  }
9788
10040
  updated(changed) {
9789
- if (changed.has("selected") || changed.has("button") || changed.has("checkbox") || changed.has("href") || changed.has("_parentType")) this._updateAriaState();
10041
+ if (changed.has("selected") || changed.has("current") || changed.has("button") || changed.has("checkbox") || changed.has("href") || changed.has("_parentType")) this._updateAriaState();
9790
10042
  if (changed.has("button") || changed.has("checkbox") || changed.has("href")) this._updateInteractive();
9791
10043
  if (changed.has("expanded")) {
9792
10044
  this._relayExpanded();
9793
10045
  this._warnOnStrayExpanded();
9794
10046
  }
9795
10047
  if (changed.has("_arrowNavigation") || changed.has("_rovingActive")) this._syncRovingTabStops();
10048
+ if (changed.has("disabled")) {
10049
+ this._syncRovingTabStops();
10050
+ this._parentList?._updateRoving();
10051
+ }
9796
10052
  this._propagateSize();
9797
10053
  }
9798
10054
  /**
@@ -9810,8 +10066,8 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9810
10066
  /** Segments marked `disclosure` announce the row's expanded state, so the
9811
10067
  * consumer writes it once — here, where it also drives the children group. */
9812
10068
  _relayExpanded() {
9813
- this._ownDescendants("nldd-list-item-action[disclosure]").forEach((action) => {
9814
- action._rowExpanded = this._resolvedExpanded;
10069
+ this._ownDescendants("nldd-list-item-segment[disclosure]").forEach((segment) => {
10070
+ segment._rowExpanded = this._resolvedExpanded;
9815
10071
  });
9816
10072
  }
9817
10073
  /** `expanded` needs a control to sit on; a plain container has none. */
@@ -9842,7 +10098,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9842
10098
  _applyParentType(type) {
9843
10099
  this._parentType = type;
9844
10100
  this._relayToChildren((item) => item._applyParentType(type));
9845
- this._ownDescendants("nldd-list-item-action").forEach((action) => action._applyParentType?.(type));
10101
+ this._ownDescendants("nldd-list-item-segment").forEach((segment) => segment._applyParentType?.(type));
9846
10102
  }
9847
10103
  /** Nested rows sit in this item's `children` slot, not the list's, so a plain
9848
10104
  * `querySelector` from the list walks past them. */
@@ -9865,7 +10121,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9865
10121
  this.removeAttribute("aria-selected");
9866
10122
  }
9867
10123
  const action = this._action;
9868
- if (this._parentType === "navigation" && this.selected && action) action.setAttribute("aria-current", "page");
10124
+ if (this._parentType === "navigation" && (this.current || this.selected) && action) action.setAttribute("aria-current", "page");
9869
10125
  else action?.removeAttribute("aria-current");
9870
10126
  }
9871
10127
  /**
@@ -9970,8 +10226,9 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9970
10226
  /**
9971
10227
  * The roving tab stop, spread over the row and the controls inside it: the
9972
10228
  * current row is reachable with Tab, everything else only with the arrow
9973
- * keys. Within the current row Tab then walks its segmented actions, so a row
9974
- * that holds a checkbox and a chevron stays fully operable.
10229
+ * keys. Within the current row Tab then walks its segments and any
10230
+ * control in its cells, so a row that holds a checkbox and a chevron, or a
10231
+ * menu button at its end, stays fully operable.
9975
10232
  *
9976
10233
  * A row that is not the current one carries NO tabindex at all rather than
9977
10234
  * -1. A shadow host with a tabindex is a focus scope of its own, and Chromium
@@ -9983,25 +10240,29 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
9983
10240
  * tab stop is in the DOM before focus is handed over.
9984
10241
  */
9985
10242
  _syncRovingTabStops() {
9986
- const ownActions = Array.from(this.children).filter((el) => el.getAttribute("slot") !== "children" && el.tagName.toLowerCase() === "nldd-list-item-action");
10243
+ const ownSegments = Array.from(this.children).filter((el) => el.getAttribute("slot") !== "children" && el.tagName.toLowerCase() === "nldd-list-item-segment");
9987
10244
  if (!this._arrowNavigation) {
9988
10245
  this.removeAttribute("tabindex");
9989
- ownActions.forEach((action) => {
9990
- action._tabbable = void 0;
10246
+ ownSegments.forEach((segment) => {
10247
+ segment._tabbable = void 0;
9991
10248
  });
10249
+ this._rovingControls().forEach(releaseTabbable);
9992
10250
  return;
9993
10251
  }
9994
10252
  if (this._action || !this._rovingActive) this.removeAttribute("tabindex");
9995
10253
  else this.setAttribute("tabindex", "0");
9996
- ownActions.forEach((action) => {
9997
- action._tabbable = this._rovingActive;
10254
+ ownSegments.forEach((segment) => {
10255
+ segment._tabbable = this._rovingActive;
10256
+ });
10257
+ this._rovingControls().forEach((control) => {
10258
+ setTabbable(control, this._rovingActive);
9998
10259
  });
9999
10260
  }
10000
- /** The control that opens and closes this row: the segmented action marked
10261
+ /** The control that opens and closes this row: the segment marked
10001
10262
  * `disclosure`, or the row itself when it is a button. Never a link — Left
10002
10263
  * and Right may not navigate away. */
10003
10264
  get _disclosureControl() {
10004
- const action = Array.from(this.children).find((el) => el.getAttribute("slot") !== "children" && el.tagName.toLowerCase() === "nldd-list-item-action" && el.hasAttribute("disclosure"));
10265
+ const action = Array.from(this.children).find((el) => el.getAttribute("slot") !== "children" && el.tagName.toLowerCase() === "nldd-list-item-segment" && el.hasAttribute("disclosure"));
10005
10266
  if (action) return action;
10006
10267
  if (this.button && !this.href) return this._action;
10007
10268
  }
@@ -10016,6 +10277,22 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
10016
10277
  if (hadFocus) this.focus();
10017
10278
  return true;
10018
10279
  }
10280
+ /**
10281
+ * Activates what this row is FOR, as opposed to what folds it: the first
10282
+ * segment that is not the disclosure. A row that is its own control
10283
+ * needs none of this, because the key reaches that control by itself.
10284
+ * Returns false when there is nothing but a chevron.
10285
+ */
10286
+ _activatePrimary() {
10287
+ const primary = [...this.querySelectorAll(":scope > nldd-list-item-segment")].find((segment) => !segment.hasAttribute("disclosure"));
10288
+ if (!primary) return false;
10289
+ const control = primary.shadowRoot?.querySelector("a, button");
10290
+ if (!control) return false;
10291
+ const hadFocus = this.matches(":focus-within");
10292
+ control.click();
10293
+ if (hadFocus) this.focus();
10294
+ return true;
10295
+ }
10019
10296
  /** The branch this row hangs under, or undefined for a top-level row. */
10020
10297
  get parentRow() {
10021
10298
  const parent = this.parentElement;
@@ -10025,7 +10302,7 @@ var NLDDListItem = (_NLDDListItem2 = class NLDDListItem extends withTranslations
10025
10302
  render() {
10026
10303
  const opensInNewTabLabel = this.href && this.target === "_blank" ? this._t("components.list-item.opens-in-new-tab-label") : void 0;
10027
10304
  const actionTabindex = this._isListboxOption ? "-1" : this._arrowNavigation ? this._rovingActive ? "0" : "-1" : void 0;
10028
- return template$12(this.button, this.href, this.target, this.rel, opensInNewTabLabel, actionTabindex, this._highlighted, this.checkbox, this.checked, this._resolvedExpanded, this._showChildren, this._hasCheckedSegment);
10305
+ return template$13(this.button, this.href, this.target, this.rel, opensInNewTabLabel, actionTabindex, this._highlighted, this.checkbox, this.checked, this._resolvedExpanded, this._showChildren, this._hasCheckedSegment, this.disabled);
10029
10306
  }
10030
10307
  }, _NLDDListItem = _NLDDListItem2, _NLDDListItem2.styles = [listItemStyles], _NLDDListItem2.SIZED_CELLS = "nldd-text-cell, nldd-drag-handle-cell", _NLDDListItem2);
10031
10308
  __decorate([property({
@@ -10036,6 +10313,10 @@ __decorate([property({
10036
10313
  type: Boolean,
10037
10314
  reflect: true
10038
10315
  })], NLDDListItem.prototype, "selected", void 0);
10316
+ __decorate([property({
10317
+ type: Boolean,
10318
+ reflect: true
10319
+ })], NLDDListItem.prototype, "current", void 0);
10039
10320
  __decorate([property({
10040
10321
  type: Boolean,
10041
10322
  reflect: true
@@ -10048,6 +10329,10 @@ __decorate([property({
10048
10329
  type: Boolean,
10049
10330
  reflect: true
10050
10331
  })], NLDDListItem.prototype, "checked", void 0);
10332
+ __decorate([property({
10333
+ type: Boolean,
10334
+ reflect: true
10335
+ })], NLDDListItem.prototype, "disabled", void 0);
10051
10336
  __decorate([property({
10052
10337
  type: Boolean,
10053
10338
  reflect: true
@@ -10167,7 +10452,7 @@ var cellStyles = css`
10167
10452
  `;
10168
10453
  //#endregion
10169
10454
  //#region src/components/lists-and-tables/cells/cell/cell.template.ts
10170
- var template$11 = () => html`<slot></slot>`;
10455
+ var template$12 = () => html`<slot></slot>`;
10171
10456
  //#endregion
10172
10457
  //#region src/components/lists-and-tables/cells/cell/cell.ts
10173
10458
  /**
@@ -10217,7 +10502,7 @@ var NLDDCell = (_NLDDCell = class NLDDCell extends VisibilityMixin(LitElement, "
10217
10502
  else this.style.removeProperty("--_min-height");
10218
10503
  }
10219
10504
  render() {
10220
- return template$11();
10505
+ return template$12();
10221
10506
  }
10222
10507
  }, _NLDDCell.styles = [cellStyles], _NLDDCell);
10223
10508
  __decorate([property({
@@ -12453,7 +12738,7 @@ var tagStyles = css`
12453
12738
  `;
12454
12739
  //#endregion
12455
12740
  //#region src/components/content/tag/tag.template.ts
12456
- function template$10(component) {
12741
+ function template$11(component) {
12457
12742
  const variant = component._effectiveVariant;
12458
12743
  const showIcon = variant === "icon" || variant === "icon-and-text" && component._hasIcon;
12459
12744
  const showText = (variant === "text" || variant === "icon-and-text") && component._hasText;
@@ -12551,7 +12836,7 @@ var NLDDTag = (_NLDDTag = class NLDDTag extends LitElement {
12551
12836
  }
12552
12837
  updated() {}
12553
12838
  render() {
12554
- return template$10(this);
12839
+ return template$11(this);
12555
12840
  }
12556
12841
  }, _NLDDTag.styles = tagStyles, _NLDDTag);
12557
12842
  __decorate([property({
@@ -12579,6 +12864,196 @@ __decorate([state()], NLDDTag.prototype, "_hasSlotText", void 0);
12579
12864
  __decorate([state()], NLDDTag.prototype, "_hasSlotIcon", void 0);
12580
12865
  NLDDTag = __decorate([customElement("nldd-tag")], NLDDTag);
12581
12866
  //#endregion
12867
+ //#region src/components/content/text/text.styles.ts
12868
+ var textStyles = css`
12869
+
12870
+
12871
+ /* # Host */
12872
+
12873
+ :host {
12874
+ --_font-size: var(--primitives-font-size-100);
12875
+ --_font-weight: var(--primitives-font-weight-body-regular);
12876
+ --_line-height: var(--primitives-line-height-snug);
12877
+ --_color: var(--context-content-color, var(--semantics-content-color));
12878
+ --_text-align: left;
12879
+
12880
+ display: block;
12881
+ color: var(--_color);
12882
+ text-align: var(--_text-align);
12883
+ font: var(--_font-weight) var(--_font-size) / var(--_line-height) var(--primitives-font-family-body);
12884
+ }
12885
+
12886
+ :host([hidden]) {
12887
+ display: none;
12888
+ }
12889
+
12890
+
12891
+ /* # Size */
12892
+
12893
+ :host([size="xxs"]) {
12894
+ --_font-size: var(--primitives-font-size-70);
12895
+ }
12896
+
12897
+ :host([size="xs"]) {
12898
+ --_font-size: var(--primitives-font-size-80);
12899
+ }
12900
+
12901
+ :host([size="sm"]) {
12902
+ --_font-size: var(--primitives-font-size-90);
12903
+ }
12904
+
12905
+ :host([size="lg"]) {
12906
+ --_font-size: var(--primitives-font-size-200);
12907
+ }
12908
+
12909
+
12910
+ /* # Weight */
12911
+
12912
+ :host([weight="medium"]) {
12913
+ --_font-weight: var(--primitives-font-weight-body-medium);
12914
+ }
12915
+
12916
+ :host([weight="bold"]) {
12917
+ --_font-weight: var(--primitives-font-weight-body-bold);
12918
+ }
12919
+
12920
+ /* Not the browser's "bolder", which is relative: from medium it lands on 700
12921
+ and from bold it asks for a weight this font does not have, so the browser
12922
+ thickens the glyphs itself. */
12923
+ ::slotted(strong),
12924
+ ::slotted(b) {
12925
+ color: inherit;
12926
+ font-weight: var(--primitives-font-weight-body-bold);
12927
+ }
12928
+
12929
+
12930
+ /* # Line height */
12931
+
12932
+ :host([line-height="flat"]) {
12933
+ --_line-height: var(--primitives-line-height-flat);
12934
+ }
12935
+
12936
+ :host([line-height="tight"]) {
12937
+ --_line-height: var(--primitives-line-height-tight);
12938
+ }
12939
+
12940
+ :host([line-height="loose"]) {
12941
+ --_line-height: var(--primitives-line-height-loose);
12942
+ }
12943
+
12944
+
12945
+ /* # Color */
12946
+
12947
+ :host([color="secondary"]) {
12948
+ --_color: var(--context-content-secondary-color, var(--semantics-content-secondary-color));
12949
+ }
12950
+
12951
+ :host([color="accent"]) {
12952
+ --_color: var(--semantics-content-accent-color);
12953
+ }
12954
+
12955
+ :host([color="success"]) {
12956
+ --_color: var(--semantics-content-success-color);
12957
+ }
12958
+
12959
+ :host([color="warning"]) {
12960
+ --_color: var(--semantics-content-warning-color);
12961
+ }
12962
+
12963
+ :host([color="critical"]) {
12964
+ --_color: var(--semantics-content-critical-color);
12965
+ }
12966
+
12967
+ :host([color="inherit"]) {
12968
+ --_color: inherit;
12969
+ }
12970
+
12971
+
12972
+ /* # Alignment */
12973
+
12974
+ :host([horizontal-alignment="center"]) {
12975
+ --_text-align: center;
12976
+ }
12977
+
12978
+ :host([horizontal-alignment="right"]) {
12979
+ --_text-align: right;
12980
+ }
12981
+ `;
12982
+ //#endregion
12983
+ //#region src/components/content/text/text.template.ts
12984
+ function template$10() {
12985
+ return html`
12986
+ <slot></slot>
12987
+ `;
12988
+ }
12989
+ //#endregion
12990
+ //#region src/components/content/text/text.ts
12991
+ /**
12992
+ * Nederlandse Digitale Dienst Text Component (Lit + TypeScript)
12993
+ *
12994
+ * One run of body text at a size from the type scale. It is what you reach for
12995
+ * where an app would otherwise write a bare `<p>` and inherit whatever the page
12996
+ * happens to set: a line under a title, a sentence in a panel, a caption.
12997
+ *
12998
+ * Every combination it offers exists as a token, so it cannot invent typography
12999
+ * — it only names what the scale already has. The three axes are the same three
13000
+ * the tokens carry: size, weight and line height.
13001
+ *
13002
+ * Not for headings, which is `nldd-title`, and not for a block of prose with its
13003
+ * own rhythm, spacing and media widths, which is `nldd-rich-text`. This is one
13004
+ * run of text and nothing around it.
13005
+ *
13006
+ * Color follows the context channel a list item, menu or table sets on its
13007
+ * content, so text inside a row travels with that row as it is hovered or
13008
+ * selected. Standalone that channel is unset and the semantic color answers.
13009
+ *
13010
+ * @element nldd-text
13011
+ * @attr {string} size - Text size on the body scale: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' (default: 'md')
13012
+ * @attr {string} weight - Font weight: 'regular' | 'medium' | 'bold' (default: 'regular'). With 'bold' a slotted `<strong>` no longer stands out: there is nothing bolder in the scale.
13013
+ * @attr {string} line-height - Line height: 'flat' | 'tight' | 'snug' | 'loose' (default: 'snug')
13014
+ * @attr {string} color - Text color: 'default' | 'secondary' | 'accent' | 'success' | 'warning' | 'critical' | 'inherit' (default: 'default'). 'default' and 'secondary' follow the surrounding content channel; 'inherit' takes the color it inherits, for text on a painted surface.
13015
+ * @attr {string} horizontal-alignment - Alignment of the text within the block: 'left' | 'center' | 'right' (default: 'left'). Aligns the words; `horizontal-alignment` on nldd-container moves the box.
13016
+ *
13017
+ * @slot - The text. Inline elements work as they are: `<strong>` and `<b>` take the bold weight from the scale, `<a>`, `<em>` and components such as `nldd-tag` are left alone.
13018
+ */
13019
+ var _NLDDText;
13020
+ var NLDDText = (_NLDDText = class NLDDText extends LitElement {
13021
+ constructor(..._args) {
13022
+ super(..._args);
13023
+ this.size = "md";
13024
+ this.weight = "regular";
13025
+ this.lineHeight = "snug";
13026
+ this.color = "default";
13027
+ this.horizontalAlignment = "left";
13028
+ }
13029
+ render() {
13030
+ return template$10();
13031
+ }
13032
+ }, _NLDDText.styles = textStyles, _NLDDText);
13033
+ __decorate([property({
13034
+ reflect: true,
13035
+ converter: reflectNonDefault("md")
13036
+ })], NLDDText.prototype, "size", void 0);
13037
+ __decorate([property({
13038
+ reflect: true,
13039
+ converter: reflectNonDefault("regular")
13040
+ })], NLDDText.prototype, "weight", void 0);
13041
+ __decorate([property({
13042
+ reflect: true,
13043
+ attribute: "line-height",
13044
+ converter: reflectNonDefault("snug")
13045
+ })], NLDDText.prototype, "lineHeight", void 0);
13046
+ __decorate([property({
13047
+ reflect: true,
13048
+ converter: reflectNonDefault("default")
13049
+ })], NLDDText.prototype, "color", void 0);
13050
+ __decorate([property({
13051
+ reflect: true,
13052
+ attribute: "horizontal-alignment",
13053
+ converter: reflectNonDefault("left")
13054
+ })], NLDDText.prototype, "horizontalAlignment", void 0);
13055
+ NLDDText = __decorate([customElement("nldd-text")], NLDDText);
13056
+ //#endregion
12582
13057
  //#region src/components/content/title/title.styles.ts
12583
13058
  var smMax$15 = unsafeCSS(breakpoints.smMax);
12584
13059
  var mdMin$19 = unsafeCSS(breakpoints.mdMin);
@@ -12787,13 +13262,8 @@ var titleStyles = css`
12787
13262
  overflow-wrap: anywhere !important;
12788
13263
  }
12789
13264
 
12790
- /* balance, not pretty: a heading is a handful of words, so evening out the
12791
- line lengths reads better than only protecting the last line.
12792
- *
12793
- * The measure is in ch, so one value covers every size: ch scales with the
12794
- * font, and 40 characters stays 40 characters whether the title is 18px or
12795
- * 52px. It only bites in a wide container — inside a card or a column the
12796
- * box is already narrower than the cap. */
13265
+ /* The measure is in ch, so one value covers every size: ch scales with the
13266
+ font, and 40 characters stays 40 characters at 18px and at 52px. */
12797
13267
  ::slotted(:not([slot])) {
12798
13268
  ${slottedReset}
12799
13269
  ${inheritedTextReset}
@@ -12810,15 +13280,16 @@ var titleStyles = css`
12810
13280
  ${inheritedTextReset}
12811
13281
  margin: 0 !important;
12812
13282
  color: var(--semantics-content-secondary-color) !important;
12813
- font: var(--primitives-font-body-sm-regular-tight) !important;
13283
+ font: var(--primitives-font-body-md-regular-tight) !important;
12814
13284
  overflow-wrap: anywhere !important;
12815
13285
  }
12816
13286
 
12817
- /* color="inherit": follow the surface's text color (e.g. a
12818
- filled-categories panel that sets a pure white/black content color);
12819
- overline and subtitle take the same color at the system-wide
12820
- secondary opacity tier. !important matches the hardened slotted
12821
- rules above. */
13287
+ :host([size="5"]) ::slotted([slot="subtitle"]),
13288
+ :host([size="6"]) ::slotted([slot="subtitle"]) {
13289
+ font: var(--primitives-font-body-sm-regular-tight) !important;
13290
+ }
13291
+
13292
+ /* !important matches the hardened slotted rules above. */
12822
13293
 
12823
13294
  :host([color="inherit"]) ::slotted(:not([slot])) {
12824
13295
  color: inherit !important;
@@ -17037,6 +17508,11 @@ var comboBoxStyles = css`
17037
17508
  border-color: var(--semantics-input-fields-is-invalid-border-color);
17038
17509
  }
17039
17510
 
17511
+ :host([readonly]) .combo-box {
17512
+ --_background-color: var(--semantics-input-fields-is-read-only-background-color);
17513
+ border-color: var(--semantics-input-fields-is-read-only-border-color);
17514
+ }
17515
+
17040
17516
  .combo-box:has(input:-webkit-autofill),
17041
17517
  .combo-box:has(input:autofill) {
17042
17518
  --_background-color: var(--semantics-input-fields-is-autofill-background-color);
@@ -17168,17 +17644,18 @@ function comboBoxTemplate(component) {
17168
17644
  <div class="combo-box">
17169
17645
  <input class="combo-box__input"
17170
17646
  type="text"
17171
- role="combobox"
17647
+ role=${component.readonly ? nothing : "combobox"}
17172
17648
  aria-label=${component.accessibleLabel || nothing}
17173
- aria-expanded=${component._isOpen ? "true" : "false"}
17174
- aria-controls=${component._menuId}
17175
- aria-autocomplete="list"
17176
- aria-haspopup="listbox"
17649
+ aria-expanded=${component.readonly ? nothing : component._isOpen ? "true" : "false"}
17650
+ aria-controls=${component.readonly ? nothing : component._menuId}
17651
+ aria-autocomplete=${component.readonly ? nothing : "list"}
17652
+ aria-haspopup=${component.readonly ? nothing : "listbox"}
17177
17653
  aria-activedescendant=${component._highlightedId || nothing}
17178
17654
  aria-invalid=${component.invalid ? "true" : nothing}
17179
17655
  .value=${component.text}
17180
17656
  placeholder=${component.placeholder || nothing}
17181
17657
  ?disabled=${component.disabled}
17658
+ ?readonly=${component.readonly}
17182
17659
  name=${component.name || nothing}
17183
17660
  autocomplete=${component.autocomplete || nothing}
17184
17661
  spellcheck=${component.noSpellcheck ? "false" : "true"}
@@ -17188,7 +17665,7 @@ function comboBoxTemplate(component) {
17188
17665
  >
17189
17666
  <div class="combo-box__input-fade"></div>
17190
17667
  <div class="combo-box__end">
17191
- ${component.text ? html`
17668
+ ${component.text && !component.readonly ? html`
17192
17669
  <div class="combo-box__clear-button">
17193
17670
  <nldd-icon-button
17194
17671
  variant="neutral-transparent"
@@ -17202,20 +17679,22 @@ function comboBoxTemplate(component) {
17202
17679
  </div>
17203
17680
  ` : nothing}
17204
17681
  ${renderValidationIcon$8(component)}
17205
- <div class="combo-box__picker-button">
17206
- <nldd-icon-button
17207
- variant="neutral-tinted"
17208
- size=${iconButtonSize}
17209
- icon="chevron-down"
17210
- text=${component._t("components.combo-box.open-menu-action")}
17211
- tooltip-timing="never"
17212
- ?disabled=${component.disabled}
17213
- ?expanded=${component._isOpen}
17214
- popup-type="listbox"
17215
- @pointerdown=${component._handlePickerPointerdown}
17216
- @click=${component._toggleMenu}
17217
- ></nldd-icon-button>
17218
- </div>
17682
+ ${component.readonly ? nothing : html`
17683
+ <div class="combo-box__picker-button">
17684
+ <nldd-icon-button
17685
+ variant="neutral-tinted"
17686
+ size=${iconButtonSize}
17687
+ icon="chevron-down"
17688
+ text=${component._t("components.combo-box.open-menu-action")}
17689
+ tooltip-timing="never"
17690
+ ?disabled=${component.disabled}
17691
+ ?expanded=${component._isOpen}
17692
+ popup-type="listbox"
17693
+ @pointerdown=${component._handlePickerPointerdown}
17694
+ @click=${component._toggleMenu}
17695
+ ></nldd-icon-button>
17696
+ </div>
17697
+ `}
17219
17698
  </div>
17220
17699
  </div>
17221
17700
  <slot @slotchange=${component._onSlotChange}></slot>
@@ -17321,6 +17800,7 @@ function submitOnEnter(host, event) {
17321
17800
  * @attr {boolean} valid - Marks the field as valid
17322
17801
  * @attr {boolean} invalid - Marks the field as invalid
17323
17802
  * @attr {boolean} disabled - Disabled state
17803
+ * @attr {boolean} readonly - Read-only state: the value stays readable, selectable and in the tab order, but the menu does not open and there is nothing to clear. The input drops its combobox role and the aria that goes with it, so assistive technology is not told about a list it cannot open. Use this where the value belongs to the record rather than to the form, e.g. the product an asset is an instance of.
17324
17804
  * @attr {boolean} allow-custom - Allow committing free-typed values that match no option (Enter/blur). Default false: only menu options are accepted.
17325
17805
  * @attr {string} name - Input name for form submission
17326
17806
  * @attr {string} autocomplete - Browser autofill hint. Default 'off' to prevent the native autofill panel from competing with the menu dropdown. Set to a valid token (e.g. 'country', 'organization') when browser autofill is desired.
@@ -17364,6 +17844,7 @@ var NLDDComboBox = (_NLDDComboBox2 = class NLDDComboBox extends FormAssociated(L
17364
17844
  this.valid = false;
17365
17845
  this.invalid = false;
17366
17846
  this.disabled = false;
17847
+ this.readonly = false;
17367
17848
  this.allowCustom = false;
17368
17849
  this.name = "";
17369
17850
  this.autocomplete = "off";
@@ -17522,6 +18003,7 @@ var NLDDComboBox = (_NLDDComboBox2 = class NLDDComboBox extends FormAssociated(L
17522
18003
  */
17523
18004
  _openMenu() {
17524
18005
  if (!this._menu || this._isOpen) return;
18006
+ if (this.readonly) return;
17525
18007
  if (this.allowCustom && !this._hasVisibleMenuItems()) return;
17526
18008
  if (!("showPopover" in this._menu)) {
17527
18009
  console.warn("<nldd-combo-box>: Popover API is not supported in this browser. The dropdown will not open.");
@@ -17591,6 +18073,7 @@ var NLDDComboBox = (_NLDDComboBox2 = class NLDDComboBox extends FormAssociated(L
17591
18073
  /** On blur: with allow-custom, accept a custom typed value; otherwise discard a
17592
18074
  * non-matching typed value by reverting the input to the current value. */
17593
18075
  _handleBlur(e) {
18076
+ if (this.readonly) return;
17594
18077
  const relatedTarget = e.relatedTarget;
17595
18078
  const focusMovedIntoMenu = !!relatedTarget && !!this._menu?.contains(relatedTarget);
17596
18079
  if (!focusMovedIntoMenu) this._closeMenu();
@@ -17616,6 +18099,10 @@ var NLDDComboBox = (_NLDDComboBox2 = class NLDDComboBox extends FormAssociated(L
17616
18099
  this._menu?.filter("");
17617
18100
  }
17618
18101
  _handleKeydown(e) {
18102
+ if (this.readonly) {
18103
+ if (e.key === "Enter") submitOnEnter(this, e);
18104
+ return;
18105
+ }
17619
18106
  if (!this._isOpen) {
17620
18107
  if (e.key === "ArrowDown") {
17621
18108
  e.preventDefault();
@@ -17702,6 +18189,10 @@ __decorate([property({
17702
18189
  type: Boolean,
17703
18190
  reflect: true
17704
18191
  })], NLDDComboBox.prototype, "disabled", void 0);
18192
+ __decorate([property({
18193
+ type: Boolean,
18194
+ reflect: true
18195
+ })], NLDDComboBox.prototype, "readonly", void 0);
17705
18196
  __decorate([property({
17706
18197
  type: Boolean,
17707
18198
  reflect: true,
@@ -19808,6 +20299,7 @@ function renderValidationIcon$7(component) {
19808
20299
  */
19809
20300
  function renderPicker$2(component) {
19810
20301
  if (component.noPicker) return nothing;
20302
+ if (component.readonly) return nothing;
19811
20303
  const buttonSize = component.size === "sm" ? "xs" : "sm";
19812
20304
  return html`
19813
20305
  <div class="date-field__picker-button">
@@ -19817,7 +20309,7 @@ function renderPicker$2(component) {
19817
20309
  icon="calendar"
19818
20310
  text=${component._t("components.date-field.to-pick-date-action")}
19819
20311
  tooltip-timing="never"
19820
- ?disabled=${component.disabled || component.readonly}
20312
+ ?disabled=${component.disabled}
19821
20313
  @click=${component._handlePickerClick}
19822
20314
  ></nldd-icon-button>
19823
20315
  <nldd-popover
@@ -21366,6 +21858,8 @@ function multiLineTextFieldTemplate(component) {
21366
21858
  <textarea class="multi-line-text-field__input"
21367
21859
  id=${component.inputId || nothing}
21368
21860
  rows=${component.rows}
21861
+ inputmode=${component.keyboard || nothing}
21862
+ enterkeyhint=${component.enterKey || nothing}
21369
21863
  .value=${component.value}
21370
21864
  placeholder=${component.placeholder || nothing}
21371
21865
  ?disabled=${component.disabled}
@@ -21401,6 +21895,8 @@ function multiLineTextFieldTemplate(component) {
21401
21895
  * @attr {boolean} readonly - Readonly state
21402
21896
  * @attr {boolean} required - Required state
21403
21897
  * @attr {string} autocomplete - Autocomplete hint
21898
+ * @attr {string} keyboard - Which virtual keyboard a phone or tablet raises, forwarded as `inputmode`: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'. It changes nothing about what the field accepts, and nothing at all on a desktop.
21899
+ * @attr {string} enter-key - What the Enter key of the virtual keyboard says, forwarded as `enterkeyhint`: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send'. In a field where Enter starts a new line, leave it alone.
21404
21900
  * @attr {number} rows - Initial visible rows (minimum height). Default: 3.
21405
21901
  * @attr {string} resize - 'none' | 'vertical' | 'auto' (default). 'auto' grows with content (native field-sizing), no manual handle.
21406
21902
  * @attr {string} accessible-label - Accessible label forwarded to the inner textarea. Set automatically by nldd-form-field.
@@ -21525,6 +22021,15 @@ __decorate([property({
21525
22021
  reflect: true
21526
22022
  })], NLDDMultiLineTextField.prototype, "required", void 0);
21527
22023
  __decorate([property({ type: String })], NLDDMultiLineTextField.prototype, "autocomplete", void 0);
22024
+ __decorate([property({
22025
+ type: String,
22026
+ reflect: true
22027
+ })], NLDDMultiLineTextField.prototype, "keyboard", void 0);
22028
+ __decorate([property({
22029
+ type: String,
22030
+ reflect: true,
22031
+ attribute: "enter-key"
22032
+ })], NLDDMultiLineTextField.prototype, "enterKey", void 0);
21528
22033
  __decorate([property({ type: Number })], NLDDMultiLineTextField.prototype, "rows", void 0);
21529
22034
  __decorate([property({
21530
22035
  reflect: true,
@@ -30191,6 +30696,8 @@ function textFieldTemplate(component) {
30191
30696
  <input class="text-field__input"
30192
30697
  id=${component.inputId || nothing}
30193
30698
  type=${component.type}
30699
+ inputmode=${component.keyboard || nothing}
30700
+ enterkeyhint=${component.enterKey || nothing}
30194
30701
  .value=${component.value}
30195
30702
  placeholder=${component.placeholder || nothing}
30196
30703
  ?disabled=${component.disabled}
@@ -30226,6 +30733,8 @@ function textFieldTemplate(component) {
30226
30733
  * @attr {boolean} valid - Marks the field as valid
30227
30734
  * @attr {boolean} disabled - Disabled state
30228
30735
  * @attr {string} type - Input type: 'text' | 'email' | 'tel' | 'url'
30736
+ * @attr {string} keyboard - Which virtual keyboard a phone or tablet raises, forwarded as `inputmode`: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'. It changes nothing about what the field accepts, and nothing at all on a desktop. Reach for it where the value is digits but not a quantity you would step (a house number, a postcode, a rack unit): 'numeric'. The keyboard for 'tel', 'email' and 'url' already follows from `type`.
30737
+ * @attr {string} enter-key - What the Enter key of the virtual keyboard says, forwarded as `enterkeyhint`: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send'. It only labels the key; what Enter does is still up to the form, and on a desktop it changes nothing.
30229
30738
  * @attr {string} name - Input name for form submission
30230
30739
  * @attr {boolean} readonly - Readonly state
30231
30740
  * @attr {boolean} required - Required state
@@ -30239,6 +30748,35 @@ function textFieldTemplate(component) {
30239
30748
  * @fires change - When input value is committed
30240
30749
  */
30241
30750
  var _NLDDTextField;
30751
+ /** The tokens `inputmode` and `enterkeyhint` accept. Arrays, so one list types
30752
+ * the property and answers at runtime: a value outside it is dropped by the
30753
+ * browser without a word, which is a typo you only find on a phone. */
30754
+ var KEYBOARDS = [
30755
+ "none",
30756
+ "text",
30757
+ "decimal",
30758
+ "numeric",
30759
+ "tel",
30760
+ "search",
30761
+ "email",
30762
+ "url"
30763
+ ];
30764
+ var ENTER_KEYS = [
30765
+ "enter",
30766
+ "done",
30767
+ "go",
30768
+ "next",
30769
+ "previous",
30770
+ "search",
30771
+ "send"
30772
+ ];
30773
+ /** The keyboard each `type` already asks for. Setting `keyboard` to something
30774
+ * else contradicts the type, which is worth saying out loud in dev. */
30775
+ var KEYBOARD_IMPLIED_BY_TYPE = {
30776
+ email: "email",
30777
+ tel: "tel",
30778
+ url: "url"
30779
+ };
30242
30780
  var NLDDTextField = (_NLDDTextField = class NLDDTextField extends FormAssociated(LitElement) {
30243
30781
  constructor(..._args) {
30244
30782
  super(..._args);
@@ -30259,17 +30797,31 @@ var NLDDTextField = (_NLDDTextField = class NLDDTextField extends FormAssociated
30259
30797
  this.errorMessageIds = "";
30260
30798
  this.noSpellcheck = false;
30261
30799
  this.width = "";
30800
+ this._warnedKeyboard = false;
30262
30801
  }
30263
30802
  firstUpdated() {
30264
30803
  this._initialValue = this.value;
30265
30804
  }
30266
30805
  updated(changed) {
30806
+ if (changed.has("keyboard") || changed.has("type")) this._warnKeyboardVsType();
30807
+ if (changed.has("keyboard")) this._warnUnknownToken("keyboard", this.keyboard, KEYBOARDS);
30808
+ if (changed.has("enterKey")) this._warnUnknownToken("enter-key", this.enterKey, ENTER_KEYS);
30267
30809
  if (changed.has("width")) {
30268
30810
  const w = this.width;
30269
30811
  if (w && w !== "full" && CSS.supports("width", w)) this.style.setProperty("--_width", w);
30270
30812
  else this.style.removeProperty("--_width");
30271
30813
  }
30272
30814
  }
30815
+ /** A token the browser does not know is dropped silently, and the field falls
30816
+ * back to the default keyboard. */
30817
+ _warnUnknownToken(attribute, value, allowed) {}
30818
+ /** A `type` other than text already asks for its own keyboard. Overriding it
30819
+ * with a different one gives a field that says "email" and shows digits,
30820
+ * which is never what was meant. */
30821
+ _warnKeyboardVsType() {
30822
+ const implied = KEYBOARD_IMPLIED_BY_TYPE[this.type];
30823
+ if (!(!!this.keyboard && !!implied && this.keyboard !== implied)) this._warnedKeyboard = false;
30824
+ }
30273
30825
  formValue() {
30274
30826
  return this.value;
30275
30827
  }
@@ -30349,6 +30901,15 @@ __decorate([property({
30349
30901
  reflect: true
30350
30902
  })], NLDDTextField.prototype, "disabled", void 0);
30351
30903
  __decorate([property({ type: String })], NLDDTextField.prototype, "type", void 0);
30904
+ __decorate([property({
30905
+ type: String,
30906
+ reflect: true
30907
+ })], NLDDTextField.prototype, "keyboard", void 0);
30908
+ __decorate([property({
30909
+ type: String,
30910
+ reflect: true,
30911
+ attribute: "enter-key"
30912
+ })], NLDDTextField.prototype, "enterKey", void 0);
30352
30913
  __decorate([property({
30353
30914
  type: String,
30354
30915
  reflect: true
@@ -31465,6 +32026,7 @@ function renderValidationIcon$1(component) {
31465
32026
  */
31466
32027
  function renderPicker$1(component) {
31467
32028
  if (component.noPicker) return nothing;
32029
+ if (component.readonly) return nothing;
31468
32030
  const buttonSize = component.size === "sm" ? "xs" : "sm";
31469
32031
  return html`
31470
32032
  <div class="time-field__picker-button">
@@ -31474,7 +32036,7 @@ function renderPicker$1(component) {
31474
32036
  icon="clock"
31475
32037
  text=${component._t("components.time-field.to-pick-time-action")}
31476
32038
  tooltip-timing="never"
31477
- ?disabled=${component.disabled || component.readonly}
32039
+ ?disabled=${component.disabled}
31478
32040
  @click=${component._handlePickerClick}
31479
32041
  ></nldd-icon-button>
31480
32042
  <nldd-popover
@@ -33649,9 +34211,17 @@ NLDDTokenField = _NLDDTokenField = __decorate([customElement("nldd-token-field")
33649
34211
  var SINGLE_COLUMN_CHANGE_EVENT = "nldd-single-column-change";
33650
34212
  /** Nearest ancestor app-view (light-DOM `closest`; slotted layers stay in the
33651
34213
  * consumer's light tree so this reaches across the slot boundaries), or null
33652
- * when a layer is used stand-alone (e.g. a bare page in the docs). */
34214
+ * when a layer is used stand-alone (e.g. a bare page in the docs).
34215
+ *
34216
+ * An overlay ends the search: a sheet or a modal dialog is its own scroll
34217
+ * container and its own top edge, so a page inside one owns its scroller
34218
+ * whatever the app around it does. Without this the app-view would push its
34219
+ * root mode straight through the overlay and the page's sticky header would
34220
+ * stick against the document, over the content of the overlay. The overlays
34221
+ * reset --context-scroll-mode as well, which is what the stand-alone read
34222
+ * below then finds. */
33653
34223
  function findScrollModeProvider(host) {
33654
- const el = host.closest?.("nldd-app-view");
34224
+ const el = host.closest?.("nldd-app-view, nldd-sheet, nldd-modal-dialog");
33655
34225
  return el && "registerScrollConsumer" in el ? el : null;
33656
34226
  }
33657
34227
  /**
@@ -38289,6 +38859,14 @@ var sheetStyles = css`
38289
38859
  /* # Block */
38290
38860
 
38291
38861
  .sheet {
38862
+ /* Where the app's layout context ends. The sheet scrolls itself and starts
38863
+ at its own top edge, so a page inside it keeps its own scroller and its
38864
+ sticky header sticks to that edge instead of to a bar that stands
38865
+ outside. See findScrollModeProvider for the other half. */
38866
+ --context-scroll-mode: nested;
38867
+ --context-layer-top: 0px;
38868
+ --context-layer-bottom: 0px;
38869
+
38292
38870
  display: flex;
38293
38871
  position: fixed;
38294
38872
  margin: 0;
@@ -38418,9 +38996,8 @@ var sheetStyles = css`
38418
38996
  flex-grow: 1;
38419
38997
  }
38420
38998
 
38421
- /* A slotted page or container fills the sheet body (so its own content scrolls
38422
- within the sheet). Scoped to these two so other direct children keep their
38423
- intrinsic height instead of being stretched. */
38999
+ /* Scoped to these two so other direct children keep their intrinsic height
39000
+ instead of being stretched. */
38424
39001
  ::slotted(nldd-page),
38425
39002
  ::slotted(nldd-container) {
38426
39003
  min-height: 0;
@@ -38917,17 +39494,14 @@ var boxStyles = css`
38917
39494
  }
38918
39495
 
38919
39496
 
38920
- /* ## Background variants */
39497
+ /* ## Backgrounds */
38921
39498
 
38922
- :host([variant="base"]) {
39499
+ :host([background="base"]) {
38923
39500
  --_background-color: var(--components-box-base-background-color);
38924
39501
  --_border-color: var(--components-box-base-border-color);
38925
39502
  }
38926
39503
 
38927
-
38928
- /* ## Variants */
38929
-
38930
- :host([variant="critical"]) {
39504
+ :host([background="critical"]) {
38931
39505
  --_background-color: var(--components-box-critical-background-color);
38932
39506
  --_border-color: var(--components-box-critical-border-color);
38933
39507
  }
@@ -38970,7 +39544,7 @@ function boxTemplate(_component) {
38970
39544
  * helping users understand their relationship at a glance.
38971
39545
  *
38972
39546
  * @element nldd-box
38973
- * @attr {'tinted'|'base'|'critical'} variant - Which surface this box draws.
39547
+ * @attr {'tinted'|'base'|'critical'} background - Which surface this box draws, named as it is on nldd-app-view, nldd-page, nldd-split-view-pane and nldd-card. It starts tinted where a card starts base: a box is there to stand out from the page, a card to sit on it.
38974
39548
  * - `tinted` (default): a box on a plain page background.
38975
39549
  * - `base`: a box on an already-tinted parent (the border ring gets +2
38976
39550
  * palette steps so it still reads against a card-on-card).
@@ -38990,7 +39564,7 @@ var _NLDDBox;
38990
39564
  var NLDDBox = (_NLDDBox = class NLDDBox extends LitElement {
38991
39565
  constructor(..._args) {
38992
39566
  super(..._args);
38993
- this.variant = "tinted";
39567
+ this.background = "tinted";
38994
39568
  }
38995
39569
  render() {
38996
39570
  return boxTemplate(this);
@@ -38999,7 +39573,7 @@ var NLDDBox = (_NLDDBox = class NLDDBox extends LitElement {
38999
39573
  __decorate([property({
39000
39574
  reflect: true,
39001
39575
  converter: reflectNonDefault("tinted")
39002
- })], NLDDBox.prototype, "variant", void 0);
39576
+ })], NLDDBox.prototype, "background", void 0);
39003
39577
  NLDDBox = __decorate([customElement("nldd-box")], NLDDBox);
39004
39578
  //#endregion
39005
39579
  //#region src/components/layout/card/card.styles.ts
@@ -40552,8 +41126,8 @@ __decorate([state()], NLDDPageFooter.prototype, "_hasMain", void 0);
40552
41126
  __decorate([state()], NLDDPageFooter.prototype, "_hasLegalBar", void 0);
40553
41127
  NLDDPageFooter = __decorate([customElement("nldd-page-footer")], NLDDPageFooter);
40554
41128
  //#endregion
40555
- //#region src/components/lists-and-tables/list-item-action/list-item-action.styles.ts
40556
- var listItemActionStyles = css`
41129
+ //#region src/components/lists-and-tables/list-item-segment/list-item-segment.styles.ts
41130
+ var listItemSegmentStyles = css`
40557
41131
  :host {
40558
41132
  box-sizing: border-box;
40559
41133
  }
@@ -40566,6 +41140,11 @@ var listItemActionStyles = css`
40566
41140
 
40567
41141
  display: flex;
40568
41142
  position: relative;
41143
+ /* Its own stacking context, so the fill below (z-index -1) stays behind
41144
+ this segment's content but in front of the row's fill. Without it the
41145
+ two -1 layers land in the same context — the row's while it is lit —
41146
+ and the segment's disappears underneath. */
41147
+ isolation: isolate;
40569
41148
  align-items: stretch;
40570
41149
  /* The row's areas center their children; this must span instead, so its hit
40571
41150
  area and fill reach the row's top and bottom edges. */
@@ -40592,7 +41171,7 @@ var listItemActionStyles = css`
40592
41171
  min-width: 0;
40593
41172
  }
40594
41173
 
40595
- :host([width="full"]) .list-item-action {
41174
+ :host([width="full"]) .list-item-segment {
40596
41175
  justify-content: flex-start;
40597
41176
  }
40598
41177
 
@@ -40613,11 +41192,9 @@ var listItemActionStyles = css`
40613
41192
  }
40614
41193
  }
40615
41194
 
40616
- /* The control is the whole action: hit area, fill and focus ring. Its inline
40617
- padding is fixed at the indicator inset, the way a button owns its padding,
40618
- so the fill always sits the same distance from the content. Do not add
40619
- spacer cells for room or hit area — that doubles the space. */
40620
- .list-item-action {
41195
+ /* The control owns its inline padding, fixed at the indicator inset. Do not
41196
+ add spacer cells for room or hit area: that doubles the space. */
41197
+ .list-item-segment {
40621
41198
  box-sizing: border-box;
40622
41199
  display: flex;
40623
41200
  position: relative;
@@ -40631,25 +41208,25 @@ var listItemActionStyles = css`
40631
41208
  padding-inline: var(--components-list-item-indicator-inline-inset);
40632
41209
  flex-direction: row;
40633
41210
  align-items: center;
40634
- /* Content narrower than the floor is centered in the leftover space, which
40635
- is the floor's doing and not the author's. A growing action keeps its
40636
- content leading: that is text, and text reads from the start. */
40637
41211
  justify-content: center;
40638
41212
  color: inherit;
40639
41213
  text-align: start;
40640
41214
  text-decoration: none;
40641
41215
  }
40642
41216
 
40643
- a.list-item-action {
41217
+ a.list-item-segment {
40644
41218
  cursor: var(--semantics-controls-link-cursor);
40645
41219
  }
40646
41220
 
40647
- button.list-item-action:disabled {
40648
- cursor: not-allowed;
41221
+ /* There is no disabled attribute for an anchor, so the segment blocks the
41222
+ click itself and aria-disabled carries the state. */
41223
+ button.list-item-segment:disabled,
41224
+ :host([disabled]) a.list-item-segment {
41225
+ cursor: default;
40649
41226
  opacity: var(--primitives-opacity-disabled);
40650
41227
  }
40651
41228
 
40652
- .list-item-action::before {
41229
+ .list-item-segment::before {
40653
41230
  content: '';
40654
41231
  display: block;
40655
41232
  position: absolute;
@@ -40661,30 +41238,61 @@ var listItemActionStyles = css`
40661
41238
  pointer-events: none;
40662
41239
  }
40663
41240
 
41241
+ /* The row hands down which fill a hovered segment takes. Unset on an ordinary
41242
+ row, where the fallback answers. */
40664
41243
  @media (hover: hover) {
40665
- a.list-item-action:hover,
40666
- button.list-item-action:not(:disabled):hover {
40667
- --_background-color: var(--components-list-item-is-hovered-background-color);
40668
- --context-content-color: var(--components-list-item-is-hovered-content-color);
40669
- --context-content-secondary-color: var(--components-list-item-is-hovered-content-color);
41244
+ :host(:not([disabled])) a.list-item-segment:hover,
41245
+ button.list-item-segment:not(:disabled):hover {
41246
+ --_background-color: var(--context-list-item-hovered-background-color, var(--components-list-item-is-hovered-background-color));
41247
+ --context-content-color: var(--context-list-item-hovered-content-color, var(--components-list-item-is-hovered-content-color));
41248
+ --context-content-secondary-color: var(--context-list-item-hovered-content-color, var(--components-list-item-is-hovered-content-color));
40670
41249
  }
40671
41250
  }
40672
41251
 
40673
41252
  /* Press feedback — works on touch where :hover doesn't. JS-driven so a touch
40674
41253
  that turns into a scroll clears it (pointercancel) instead of flashing. */
40675
- .list-item-action.is-pressed {
40676
- --_background-color: var(--components-list-item-is-hovered-background-color);
40677
- --context-content-color: var(--components-list-item-is-hovered-content-color);
40678
- --context-content-secondary-color: var(--components-list-item-is-hovered-content-color);
41254
+ /* The element selectors match the weight of the hover rule above: a pointer
41255
+ that presses is hovering as well, and the press has to win. */
41256
+ :host(:not([disabled])) a.list-item-segment.is-pressed,
41257
+ button.list-item-segment:not(:disabled).is-pressed,
41258
+ :host(:not([disabled])) .list-item-segment.is-pressed {
41259
+ --_background-color: var(--context-list-item-active-background-color, var(--components-list-item-is-active-background-color));
41260
+ --context-content-color: var(--context-list-item-active-content-color, var(--context-list-item-hovered-content-color, var(--components-list-item-is-active-content-color)));
41261
+ --context-content-secondary-color: var(--context-list-item-active-content-color, var(--context-list-item-hovered-content-color, var(--components-list-item-is-active-content-color)));
41262
+ }
41263
+
41264
+ /* After the hover rule on purpose: hovering back over the segment must not
41265
+ dim it while what it opened is still on screen. */
41266
+ :host([expanded]) .list-item-segment {
41267
+ --_background-color: var(--components-list-item-is-expanded-background-color);
41268
+ --context-content-color: var(--components-list-item-is-expanded-content-color);
41269
+ --context-content-secondary-color: var(--components-list-item-is-expanded-content-color);
41270
+ }
41271
+
41272
+ @media (hover: hover) {
41273
+ :host([expanded]:not([disabled])) a.list-item-segment:hover,
41274
+ :host([expanded]) button.list-item-segment:not(:disabled):hover {
41275
+ --_background-color: var(--components-list-item-is-expanded-is-hovered-background-color);
41276
+ --context-content-color: var(--components-list-item-is-expanded-content-color);
41277
+ --context-content-secondary-color: var(--components-list-item-is-expanded-content-color);
41278
+ }
41279
+ }
41280
+
41281
+ :host([expanded]:not([disabled])) a.list-item-segment.is-pressed,
41282
+ :host([expanded]) button.list-item-segment:not(:disabled).is-pressed,
41283
+ :host([expanded]:not([disabled])) .list-item-segment.is-pressed {
41284
+ --_background-color: var(--components-list-item-is-expanded-is-active-background-color);
41285
+ --context-content-color: var(--components-list-item-is-expanded-content-color);
41286
+ --context-content-secondary-color: var(--components-list-item-is-expanded-content-color);
40679
41287
  }
40680
41288
 
40681
- :host([checked]) .list-item-action {
41289
+ :host([checked]) .list-item-segment {
40682
41290
  --_background-color: var(--components-list-item-is-selected-background-color);
40683
41291
  --context-content-color: var(--components-list-item-is-selected-content-color);
40684
41292
  --context-content-secondary-color: var(--components-list-item-is-selected-content-color);
40685
41293
  }
40686
41294
 
40687
- .list-item-action:focus-visible:not(.is-pointer-focus)::after {
41295
+ .list-item-segment:focus-visible:not(.is-pointer-focus)::after {
40688
41296
  content: '';
40689
41297
  display: block;
40690
41298
  position: absolute;
@@ -40697,22 +41305,23 @@ var listItemActionStyles = css`
40697
41305
  }
40698
41306
  `;
40699
41307
  //#endregion
40700
- //#region src/components/lists-and-tables/list-item-action/list-item-action.template.ts
41308
+ //#region src/components/lists-and-tables/list-item-segment/list-item-segment.template.ts
40701
41309
  function template$9(control, href, target, rel, checked, expanded, current, disabled, accessibleLabel, actionTabindex) {
40702
41310
  const content = html`<slot></slot>`;
40703
41311
  const ariaExpanded = expanded === void 0 ? nothing : String(expanded);
40704
41312
  const ariaCurrent = current ? "page" : nothing;
40705
41313
  const label = accessibleLabel || nothing;
40706
- if (control === "link") return html`<a class="list-item-action"
41314
+ if (control === "link") return html`<a class="list-item-segment"
40707
41315
  href=${href ?? nothing}
40708
41316
  target=${target ?? nothing}
40709
41317
  rel=${rel ?? nothing}
41318
+ aria-disabled=${disabled ? "true" : nothing}
40710
41319
  aria-expanded=${ariaExpanded}
40711
41320
  aria-current=${ariaCurrent}
40712
41321
  aria-label=${label}
40713
41322
  tabindex=${actionTabindex ?? nothing}
40714
41323
  >${content}</a>`;
40715
- if (control === "checkbox" || control === "button") return html`<button class="list-item-action"
41324
+ if (control === "checkbox" || control === "button") return html`<button class="list-item-segment"
40716
41325
  type="button"
40717
41326
  role=${control === "checkbox" ? "checkbox" : nothing}
40718
41327
  aria-checked=${control === "checkbox" ? String(checked) : nothing}
@@ -40722,12 +41331,12 @@ function template$9(control, href, target, rel, checked, expanded, current, disa
40722
41331
  ?disabled=${disabled}
40723
41332
  tabindex=${actionTabindex ?? nothing}
40724
41333
  >${content}</button>`;
40725
- return html`<div class="list-item-action">${content}</div>`;
41334
+ return html`<div class="list-item-segment">${content}</div>`;
40726
41335
  }
40727
41336
  //#endregion
40728
- //#region src/components/lists-and-tables/list-item-action/list-item-action.ts
40729
- var _NLDDListItemAction;
40730
- var NLDDListItemAction = (_NLDDListItemAction = class NLDDListItemAction extends LitElement {
41337
+ //#region src/components/lists-and-tables/list-item-segment/list-item-segment.ts
41338
+ var _NLDDListItemSegment;
41339
+ var NLDDListItemSegment = (_NLDDListItemSegment = class NLDDListItemSegment extends LitElement {
40731
41340
  constructor(..._args) {
40732
41341
  super(..._args);
40733
41342
  this.button = false;
@@ -40740,7 +41349,11 @@ var NLDDListItemAction = (_NLDDListItemAction = class NLDDListItemAction extends
40740
41349
  this.accessibleLabel = "";
40741
41350
  this._parentType = "list";
40742
41351
  this._handleClick = (e) => {
40743
- if (this.disabled) return;
41352
+ if (this.disabled) {
41353
+ e.preventDefault();
41354
+ e.stopPropagation();
41355
+ return;
41356
+ }
40744
41357
  this._control?.focus();
40745
41358
  if (this._controlType !== "checkbox") return;
40746
41359
  if (!e.composedPath().includes(this._control)) return;
@@ -40757,9 +41370,14 @@ var NLDDListItemAction = (_NLDDListItemAction = class NLDDListItemAction extends
40757
41370
  this._handleFocusOut = () => {
40758
41371
  this._control?.classList.remove("is-pointer-focus");
40759
41372
  };
41373
+ this._onMouseDown = (e) => {
41374
+ if (e.button > 0 || this.disabled) return;
41375
+ e.preventDefault();
41376
+ };
40760
41377
  this._onPointerDown = (e) => {
40761
41378
  if (e.button > 0 || this.disabled) return;
40762
41379
  this._control?.classList.add("is-pressed");
41380
+ this._control?.focus({ preventScroll: true });
40763
41381
  };
40764
41382
  this._clearPressed = () => {
40765
41383
  this._control?.classList.remove("is-pressed");
@@ -40771,6 +41389,7 @@ var NLDDListItemAction = (_NLDDListItemAction = class NLDDListItemAction extends
40771
41389
  this.addEventListener("focusout", this._handleFocusOut);
40772
41390
  this.addEventListener("click", this._handleClick);
40773
41391
  this.addEventListener("pointerdown", this._onPointerDown);
41392
+ this.addEventListener("mousedown", this._onMouseDown);
40774
41393
  this.addEventListener("pointerup", this._clearPressed);
40775
41394
  this.addEventListener("pointercancel", this._clearPressed);
40776
41395
  }
@@ -40780,6 +41399,7 @@ var NLDDListItemAction = (_NLDDListItemAction = class NLDDListItemAction extends
40780
41399
  this.removeEventListener("focusout", this._handleFocusOut);
40781
41400
  this.removeEventListener("click", this._handleClick);
40782
41401
  this.removeEventListener("pointerdown", this._onPointerDown);
41402
+ this.removeEventListener("mousedown", this._onMouseDown);
40783
41403
  this.removeEventListener("pointerup", this._clearPressed);
40784
41404
  this.removeEventListener("pointercancel", this._clearPressed);
40785
41405
  }
@@ -40791,7 +41411,7 @@ var NLDDListItemAction = (_NLDDListItemAction = class NLDDListItemAction extends
40791
41411
  _applyParentType(type) {
40792
41412
  this._parentType = type;
40793
41413
  }
40794
- /** Whether the consumer asked for an interactive action at all. */
41414
+ /** Whether the consumer asked for an interactive segment at all. */
40795
41415
  get _wantsControl() {
40796
41416
  return Boolean(this.href) || this.button || this.checkbox;
40797
41417
  }
@@ -40806,7 +41426,7 @@ var NLDDListItemAction = (_NLDDListItemAction = class NLDDListItemAction extends
40806
41426
  this._control?.focus(options);
40807
41427
  }
40808
41428
  /** The open state has to reach the styles, and it lives in a property (the
40809
- * row's, for a disclosure action) that CSS cannot see. A host class is the
41429
+ * row's, for a disclosure segment) that CSS cannot see. A host class is the
40810
41430
  * hook — the same mechanism nldd-list already uses for .is-boxed / .is-first. */
40811
41431
  updated() {
40812
41432
  const expanded = this.disclosure ? this._rowExpanded : this.expanded;
@@ -40815,48 +41435,48 @@ var NLDDListItemAction = (_NLDDListItemAction = class NLDDListItemAction extends
40815
41435
  render() {
40816
41436
  return template$9(this._controlType, this.href, this.target, this.rel, this.checked, this.disclosure ? this._rowExpanded : this.expanded, this.current, this.disabled, this.accessibleLabel, this._tabbable === void 0 ? void 0 : this._tabbable ? "0" : "-1");
40817
41437
  }
40818
- }, _NLDDListItemAction.styles = [listItemActionStyles], _NLDDListItemAction);
41438
+ }, _NLDDListItemSegment.styles = [listItemSegmentStyles], _NLDDListItemSegment);
40819
41439
  __decorate([property({
40820
41440
  type: Boolean,
40821
41441
  reflect: true
40822
- })], NLDDListItemAction.prototype, "button", void 0);
40823
- __decorate([property({ reflect: true })], NLDDListItemAction.prototype, "href", void 0);
40824
- __decorate([property({ reflect: true })], NLDDListItemAction.prototype, "target", void 0);
40825
- __decorate([property({ reflect: true })], NLDDListItemAction.prototype, "rel", void 0);
41442
+ })], NLDDListItemSegment.prototype, "button", void 0);
41443
+ __decorate([property({ reflect: true })], NLDDListItemSegment.prototype, "href", void 0);
41444
+ __decorate([property({ reflect: true })], NLDDListItemSegment.prototype, "target", void 0);
41445
+ __decorate([property({ reflect: true })], NLDDListItemSegment.prototype, "rel", void 0);
40826
41446
  __decorate([property({
40827
41447
  type: Boolean,
40828
41448
  reflect: true
40829
- })], NLDDListItemAction.prototype, "checkbox", void 0);
41449
+ })], NLDDListItemSegment.prototype, "checkbox", void 0);
40830
41450
  __decorate([property({
40831
41451
  type: Boolean,
40832
41452
  reflect: true
40833
- })], NLDDListItemAction.prototype, "checked", void 0);
41453
+ })], NLDDListItemSegment.prototype, "checked", void 0);
40834
41454
  __decorate([property({
40835
41455
  type: Boolean,
40836
41456
  reflect: true
40837
- })], NLDDListItemAction.prototype, "expanded", void 0);
41457
+ })], NLDDListItemSegment.prototype, "expanded", void 0);
40838
41458
  __decorate([property({
40839
41459
  type: Boolean,
40840
41460
  reflect: true
40841
- })], NLDDListItemAction.prototype, "disclosure", void 0);
41461
+ })], NLDDListItemSegment.prototype, "disclosure", void 0);
40842
41462
  __decorate([property({
40843
41463
  type: Boolean,
40844
41464
  reflect: true
40845
- })], NLDDListItemAction.prototype, "current", void 0);
41465
+ })], NLDDListItemSegment.prototype, "current", void 0);
40846
41466
  __decorate([property({
40847
41467
  type: Boolean,
40848
41468
  reflect: true
40849
- })], NLDDListItemAction.prototype, "disabled", void 0);
41469
+ })], NLDDListItemSegment.prototype, "disabled", void 0);
40850
41470
  __decorate([property({
40851
41471
  reflect: true,
40852
41472
  converter: reflectNonDefault("fit-content")
40853
- })], NLDDListItemAction.prototype, "width", void 0);
40854
- __decorate([property({ attribute: "accessible-label" })], NLDDListItemAction.prototype, "accessibleLabel", void 0);
40855
- __decorate([state()], NLDDListItemAction.prototype, "_parentType", void 0);
40856
- __decorate([state()], NLDDListItemAction.prototype, "_tabbable", void 0);
40857
- __decorate([state()], NLDDListItemAction.prototype, "_rowExpanded", void 0);
40858
- __decorate([query(".list-item-action")], NLDDListItemAction.prototype, "_control", void 0);
40859
- NLDDListItemAction = __decorate([customElement("nldd-list-item-action")], NLDDListItemAction);
41473
+ })], NLDDListItemSegment.prototype, "width", void 0);
41474
+ __decorate([property({ attribute: "accessible-label" })], NLDDListItemSegment.prototype, "accessibleLabel", void 0);
41475
+ __decorate([state()], NLDDListItemSegment.prototype, "_parentType", void 0);
41476
+ __decorate([state()], NLDDListItemSegment.prototype, "_tabbable", void 0);
41477
+ __decorate([state()], NLDDListItemSegment.prototype, "_rowExpanded", void 0);
41478
+ __decorate([query(".list-item-segment")], NLDDListItemSegment.prototype, "_control", void 0);
41479
+ NLDDListItemSegment = __decorate([customElement("nldd-list-item-segment")], NLDDListItemSegment);
40860
41480
  //#endregion
40861
41481
  //#region src/components/lists-and-tables/table/table.styles.ts
40862
41482
  var tableStyles = css`
@@ -44463,7 +45083,7 @@ var NLDDTopNavigationBar = (_NLDDTopNavigationBar = class NLDDTopNavigationBar e
44463
45083
  Promise.resolve().then(() => list_item_exports),
44464
45084
  Promise.resolve().then(() => text_cell_exports),
44465
45085
  Promise.resolve().then(() => icon_cell_exports),
44466
- import("./icon-CIpJq_cf.js").then((n) => n.n)
45086
+ import("./icon-C1Kikpol.js").then((n) => n.n)
44467
45087
  ]);
44468
45088
  }
44469
45089
  _createGlobalMenuSheet() {
@@ -47018,6 +47638,13 @@ var modalDialogStyles = css`
47018
47638
  /* # Block */
47019
47639
 
47020
47640
  .modal-dialog {
47641
+ /* Where the app's layout context ends, as in nldd-sheet: the dialog scrolls
47642
+ itself and starts at its own top edge, so anything inside it stops
47643
+ following the app's scroll mode and its layer offsets. */
47644
+ --context-scroll-mode: nested;
47645
+ --context-layer-top: 0px;
47646
+ --context-layer-bottom: 0px;
47647
+
47021
47648
  box-sizing: border-box;
47022
47649
  outline: none;
47023
47650
  border: none;
@@ -48328,6 +48955,7 @@ var badgeStyles = css`
48328
48955
  /* # Host */
48329
48956
 
48330
48957
  :host {
48958
+ --_custom-color: transparent;
48331
48959
  --_background-color: var(--semantics-categories-critical-filled-background-color);
48332
48960
  --_border-color: var(--semantics-categories-critical-filled-highlight-border-color);
48333
48961
  --_border-width: var(--components-badge-border-width);
@@ -48359,6 +48987,18 @@ var badgeStyles = css`
48359
48987
 
48360
48988
  /* ## Color */
48361
48989
 
48990
+ /* color on the host, for the same reason as custom-color below: the contrast
48991
+ token reads currentColor, so without this the flip is computed against the
48992
+ inherited color while the fill comes from the context channel. A row that
48993
+ sets the channel to white over dark text then paints white on white. */
48994
+ :host([color="inherit"]) {
48995
+ color: var(--context-content-color, currentColor);
48996
+
48997
+ --_background-color: currentColor;
48998
+ --_border-color: transparent;
48999
+ --_content-color: var(--semantics-content-contrast-color);
49000
+ }
49001
+
48362
49002
  :host([color="accent"]) {
48363
49003
  --_background-color: var(--semantics-categories-accent-filled-background-color);
48364
49004
  --_border-color: var(--semantics-categories-accent-filled-highlight-border-color);
@@ -48494,6 +49134,17 @@ var badgeStyles = css`
48494
49134
  --_content-color: var(--semantics-categories-mintgroen-filled-content-color);
48495
49135
  }
48496
49136
 
49137
+ /* color on the host rather than on the fill: the contrast token reads
49138
+ currentColor, so the text lands on black or white without a second formula
49139
+ to keep in step. After every [color] rule, so it wins over one. */
49140
+ :host([custom-color]) {
49141
+ color: var(--_custom-color);
49142
+
49143
+ --_background-color: var(--_custom-color);
49144
+ --_border-color: transparent;
49145
+ --_content-color: var(--semantics-content-contrast-color);
49146
+ }
49147
+
48497
49148
  :host([hidden]) {
48498
49149
  display: none;
48499
49150
  }
@@ -48516,7 +49167,6 @@ var badgeStyles = css`
48516
49167
  gap: var(--_gap);
48517
49168
  align-items: center;
48518
49169
  justify-content: center;
48519
- color: var(--_content-color);
48520
49170
  font: var(--_font);
48521
49171
  white-space: nowrap;
48522
49172
  }
@@ -48525,15 +49175,15 @@ var badgeStyles = css`
48525
49175
  .badge {
48526
49176
  border: 1px solid CanvasText;
48527
49177
  background-color: Canvas;
49178
+ }
49179
+
49180
+ .badge__icon,
49181
+ .badge__text {
48528
49182
  color: CanvasText;
48529
49183
  }
48530
49184
  }
48531
49185
 
48532
- /* Grows out of the badge and fades: it borrows the badge's own shape and
48533
- colour, so it works on a dot as well as on a counter. Behind the content
48534
- and inert, so it never affects layout or hit area.
48535
-
48536
- A growing box-shadow rather than a scale: scaling multiplies, so a wide
49186
+ /* A growing box-shadow rather than a scale: scaling multiplies, so a wide
48537
49187
  badge would throw a halo that is far wider than it is tall. A spread adds
48538
49188
  the same distance on every side, whatever the badge measures.
48539
49189
 
@@ -48598,7 +49248,12 @@ var badgeStyles = css`
48598
49248
 
48599
49249
  /* # Elements */
48600
49250
 
49251
+ /* The content carries the content color, not .badge itself: the fill is a
49252
+ custom property that resolves where it is used, and a fill of currentColor
49253
+ on an element that also sets color would take that color instead of the
49254
+ one around it. Mirrors nldd-avatar. */
48601
49255
  .badge__icon {
49256
+ color: var(--_content-color);
48602
49257
  display: inline-flex;
48603
49258
  width: var(--_icon-size);
48604
49259
  height: var(--_icon-size);
@@ -48617,6 +49272,7 @@ var badgeStyles = css`
48617
49272
  }
48618
49273
 
48619
49274
  .badge__text {
49275
+ color: var(--_content-color);
48620
49276
  display: inline-block;
48621
49277
  }
48622
49278
  `;
@@ -48666,7 +49322,8 @@ var nlddBadgeTranslations = { "components.badge.notification-label": "Notificati
48666
49322
  *
48667
49323
  * @element nldd-badge
48668
49324
  * @attr {string} size - Size: 'sm' | 'md' (default: 'md')
48669
- * @attr {string} color - Semantic ('critical' | 'accent' | 'neutral' | 'warning' | 'success') or a Rijkshuisstijl color ('lintblauw' | 'hemelblauw' | 'oranje' | …). Default: 'critical'
49325
+ * @attr {string} color - Semantic ('critical' | 'accent' | 'neutral' | 'warning' | 'success'), a Rijkshuisstijl color ('lintblauw' | 'hemelblauw' | 'oranje' | …), or 'inherit' to fill in the content color around it: the `--context-content-color` channel a list item, table row or menu sets, falling back to `currentColor`. Default: 'critical'
49326
+ * @attr {string} custom-color - A color of its own, as any CSS color value ('#a90061', 'oklch(0.6 0.2 20)', 'var(--brand-cable-blue)'). For a color the design system cannot know: the jacket of a cable, a color someone picked. It wins over `color`. Whatever it paints, the text and icon on top become white or black, whichever contrasts. The text on it is black or white, picked on the relative luminance of the fill, so it clears 4.5:1 whatever color you hand it.
48670
49327
  * @attr {boolean} pulse - Grows a ring out of the badge and fades it, for something happening right now (a live connection, an outage). Respects `prefers-reduced-motion`.
48671
49328
  * @attr {string} text - Text (takes precedence over number)
48672
49329
  * @attr {number} number - Numeric value. Shortened when it is over max
@@ -48681,6 +49338,7 @@ var NLDDBadge = (_NLDDBadge = class NLDDBadge extends withTranslations(LitElemen
48681
49338
  super(..._args);
48682
49339
  this.size = "md";
48683
49340
  this.color = "critical";
49341
+ this.customColor = "";
48684
49342
  this.pulse = false;
48685
49343
  this.text = "";
48686
49344
  this.number = void 0;
@@ -48689,6 +49347,11 @@ var NLDDBadge = (_NLDDBadge = class NLDDBadge extends withTranslations(LitElemen
48689
49347
  this.accessibleLabel = "";
48690
49348
  this.decorative = false;
48691
49349
  }
49350
+ updated(changed) {
49351
+ if (!changed.has("customColor")) return;
49352
+ if (this.customColor) this.style.setProperty("--_custom-color", this.customColor);
49353
+ else this.style.removeProperty("--_custom-color");
49354
+ }
48692
49355
  get _hasText() {
48693
49356
  return !!this.text || typeof this.number === "number";
48694
49357
  }
@@ -48720,6 +49383,11 @@ __decorate([property({
48720
49383
  reflect: true,
48721
49384
  converter: reflectNonDefault("critical")
48722
49385
  })], NLDDBadge.prototype, "color", void 0);
49386
+ __decorate([property({
49387
+ reflect: true,
49388
+ attribute: "custom-color",
49389
+ converter: reflectNonDefault("")
49390
+ })], NLDDBadge.prototype, "customColor", void 0);
48723
49391
  __decorate([property({
48724
49392
  type: Boolean,
48725
49393
  reflect: true
@@ -51973,4 +52641,4 @@ __decorate([property({
51973
52641
  })], NLDDJustInTimeEducation.prototype, "noArrow", void 0);
51974
52642
  NLDDJustInTimeEducation = _NLDDJustInTimeEducation = __decorate([customElement("nldd-just-in-time-education")], NLDDJustInTimeEducation);
51975
52643
  //#endregion
51976
- export { NLDDActivityIndicator, NLDDAppView, NLDDAvatar, NLDDAvatarGroup, NLDDBadge, NLDDBanner, NLDDBarSplitView, NLDDBlockquote, NLDDBox, NLDDBreadcrumbs, NLDDBreadcrumbsItem, NLDDButton, NLDDButtonBar, NLDDButtonGroup, NLDDCard, NLDDCell, NLDDCheckbox, NLDDCheckboxField, NLDDCodeEditor, NLDDCodeViewer, NLDDCollection, NLDDComboBox, NLDDContainer, NLDDDateField, NLDDDatePicker, NLDDDescriptionCell, NLDDDivider, NLDDDocumentTabBar, NLDDDragHandleCell, NLDDDropdown, NLDDFileField, NLDDForm, NLDDFormActions, NLDDFormField, NLDDFormSection, NLDDFullBleedSection, NLDDHero, NLDDIcon, NLDDIconButton, NLDDIconCell, NLDDIdentity, NLDDImage, NLDDInlineDialog, NLDDJustInTimeEducation, NLDDKeyboardShortcut, NLDDLink, NLDDList, NLDDListItem, NLDDListItemAction, NLDDMenu, NLDDMenuBar, NLDDMenuBarItem, NLDDModalDialog, NLDDMultiLineTextField, NLDDNavigationSplitView, NLDDNotification, NLDDNumberField, NLDDOneHalfOneHalfSection, NLDDOneThirdTwoThirdsSection, NLDDPage, NLDDPageFooter, NLDDPageFooterLegalBar, NLDDPageFooterLegalBarItem, NLDDPagination, NLDDPasswordField, NLDDPopover, NLDDProgressBar, NLDDProgressBarSegmentIndicator, NLDDProgressCircle, NLDDProgressCircleSegmentIndicator, NLDDRadioButton, NLDDRadioButtonField, NLDDRadioButtonGroup, NLDDRichText, NLDDSearchField, NLDDSegmentedControl, NLDDSheet, NLDDSideBySideSplitView, NLDDSidebarSection, NLDDSimpleSection, NLDDSkipLink, NLDDSpacer, NLDDSpacerCell, NLDDSplitButton, NLDDSplitViewDivider, NLDDSplitViewPane, NLDDStackedSplitView, NLDDStatusBar, NLDDStepIndicator, NLDDStepIndicatorItem, NLDDStepper, NLDDSwitch, NLDDSwitchField, NLDDTabBar, NLDDTable, NLDDTableRow, NLDDTag, NLDDTextCell, NLDDTextEditor, NLDDTextField, NLDDTimeField, NLDDTimePicker, NLDDTimelineTrackCell, NLDDTitle, NLDDTitleCell, NLDDToggleButton, NLDDToggleButtonGroup, NLDDToken, NLDDTokenField, NLDDToolbar, NLDDTooltip, NLDDTopNavigationBar, NLDDTopTitleBar, NLDDTwoThirdsOneThirdSection, NLDDWindow };
52644
+ export { NLDDActivityIndicator, NLDDAppView, NLDDAvatar, NLDDAvatarGroup, NLDDBadge, NLDDBanner, NLDDBarSplitView, NLDDBlockquote, NLDDBox, NLDDBreadcrumbs, NLDDBreadcrumbsItem, NLDDButton, NLDDButtonBar, NLDDButtonGroup, NLDDCard, NLDDCell, NLDDCheckbox, NLDDCheckboxField, NLDDCodeEditor, NLDDCodeViewer, NLDDCollection, NLDDComboBox, NLDDContainer, NLDDDateField, NLDDDatePicker, NLDDDescriptionCell, NLDDDivider, NLDDDocumentTabBar, NLDDDragHandleCell, NLDDDropdown, NLDDFileField, NLDDForm, NLDDFormActions, NLDDFormField, NLDDFormSection, NLDDFullBleedSection, NLDDHero, NLDDIcon, NLDDIconButton, NLDDIconCell, NLDDIdentity, NLDDImage, NLDDInlineDialog, NLDDJustInTimeEducation, NLDDKeyboardShortcut, NLDDLink, NLDDList, NLDDListItem, NLDDListItemSegment, NLDDMenu, NLDDMenuBar, NLDDMenuBarItem, NLDDModalDialog, NLDDMultiLineTextField, NLDDNavigationSplitView, NLDDNotification, NLDDNumberField, NLDDOneHalfOneHalfSection, NLDDOneThirdTwoThirdsSection, NLDDPage, NLDDPageFooter, NLDDPageFooterLegalBar, NLDDPageFooterLegalBarItem, NLDDPagination, NLDDPasswordField, NLDDPopover, NLDDProgressBar, NLDDProgressBarSegmentIndicator, NLDDProgressCircle, NLDDProgressCircleSegmentIndicator, NLDDRadioButton, NLDDRadioButtonField, NLDDRadioButtonGroup, NLDDRichText, NLDDSearchField, NLDDSegmentedControl, NLDDSheet, NLDDSideBySideSplitView, NLDDSidebarSection, NLDDSimpleSection, NLDDSkipLink, NLDDSpacer, NLDDSpacerCell, NLDDSplitButton, NLDDSplitViewDivider, NLDDSplitViewPane, NLDDStackedSplitView, NLDDStatusBar, NLDDStepIndicator, NLDDStepIndicatorItem, NLDDStepper, NLDDSwitch, NLDDSwitchField, NLDDTabBar, NLDDTable, NLDDTableRow, NLDDTag, NLDDText, NLDDTextCell, NLDDTextEditor, NLDDTextField, NLDDTimeField, NLDDTimePicker, NLDDTimelineTrackCell, NLDDTitle, NLDDTitleCell, NLDDToggleButton, NLDDToggleButtonGroup, NLDDToken, NLDDTokenField, NLDDToolbar, NLDDTooltip, NLDDTopNavigationBar, NLDDTopTitleBar, NLDDTwoThirdsOneThirdSection, NLDDWindow };