@nldd/design-system 0.8.82 → 0.8.84

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 (487) hide show
  1. package/custom-elements.json +3849 -542
  2. package/dist/components/actions/button/button.d.ts +9 -2
  3. package/dist/components/actions/button/button.d.ts.map +1 -1
  4. package/dist/components/actions/button/button.js +15 -2
  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 +2 -2
  10. package/dist/components/actions/icon-button/icon-button.js +2 -2
  11. package/dist/components/actions/menu/menu.d.ts +3 -1
  12. package/dist/components/actions/menu/menu.d.ts.map +1 -1
  13. package/dist/components/actions/menu/menu.js +22 -11
  14. package/dist/components/actions/menu/menu.js.map +1 -1
  15. package/dist/components/actions/toolbar/toolbar.styles.js +2 -2
  16. package/dist/components/components.js +2911 -1157
  17. package/dist/components/content/avatar/avatar.d.ts +6 -0
  18. package/dist/components/content/avatar/avatar.d.ts.map +1 -1
  19. package/dist/components/content/avatar/avatar.js +9 -0
  20. package/dist/components/content/avatar/avatar.js.map +1 -1
  21. package/dist/components/content/avatar/avatar.styles.d.ts.map +1 -1
  22. package/dist/components/content/avatar/avatar.styles.js +5 -1
  23. package/dist/components/content/avatar/avatar.styles.js.map +1 -1
  24. package/dist/components/content/avatar/avatar.template.d.ts.map +1 -1
  25. package/dist/components/content/avatar/avatar.template.js +2 -0
  26. package/dist/components/content/avatar/avatar.template.js.map +1 -1
  27. package/dist/components/content/avatar-group/avatar-group.styles.d.ts.map +1 -1
  28. package/dist/components/content/avatar-group/avatar-group.styles.js +6 -16
  29. package/dist/components/content/avatar-group/avatar-group.styles.js.map +1 -1
  30. package/dist/components/content/blockquote/blockquote.d.ts +3 -4
  31. package/dist/components/content/blockquote/blockquote.d.ts.map +1 -1
  32. package/dist/components/content/blockquote/blockquote.js +3 -4
  33. package/dist/components/content/blockquote/blockquote.js.map +1 -1
  34. package/dist/components/content/icon/icon-aliases.d.ts.map +1 -1
  35. package/dist/components/content/icon/icon-aliases.js +80 -6
  36. package/dist/components/content/icon/icon-aliases.js.map +1 -1
  37. package/dist/components/content/icon/icon-gallery-status.d.ts.map +1 -1
  38. package/dist/components/content/icon/icon-gallery-status.js +57 -94
  39. package/dist/components/content/icon/icon-gallery-status.js.map +1 -1
  40. package/dist/components/content/icon/icon-registry.d.ts.map +1 -1
  41. package/dist/components/content/icon/icon-registry.js +36 -4
  42. package/dist/components/content/icon/icon-registry.js.map +1 -1
  43. package/dist/components/content/icon/icon.d.ts +8 -2
  44. package/dist/components/content/icon/icon.d.ts.map +1 -1
  45. package/dist/components/content/icon/icon.js +17 -2
  46. package/dist/components/content/icon/icon.js.map +1 -1
  47. package/dist/components/content/icon/icon.styles.d.ts.map +1 -1
  48. package/dist/components/content/icon/icon.styles.js +8 -0
  49. package/dist/components/content/icon/icon.styles.js.map +1 -1
  50. package/dist/components/content/image/image.d.ts +1 -1
  51. package/dist/components/content/image/image.js +1 -1
  52. package/dist/components/content/image/image.styles.d.ts.map +1 -1
  53. package/dist/components/content/image/image.styles.js +11 -0
  54. package/dist/components/content/image/image.styles.js.map +1 -1
  55. package/dist/components/content/keyboard-shortcut/keyboard-shortcut.d.ts +30 -30
  56. package/dist/components/content/keyboard-shortcut/keyboard-shortcut.js +30 -30
  57. package/dist/components/content/rich-text/rich-text.d.ts +20 -20
  58. package/dist/components/content/rich-text/rich-text.js +20 -20
  59. package/dist/components/content/text/text.d.ts +50 -0
  60. package/dist/components/content/text/text.d.ts.map +1 -0
  61. package/dist/components/content/text/text.js +81 -0
  62. package/dist/components/content/text/text.js.map +1 -0
  63. package/dist/components/content/text/text.styles.d.ts +2 -0
  64. package/dist/components/content/text/text.styles.d.ts.map +1 -0
  65. package/dist/components/content/text/text.styles.js +116 -0
  66. package/dist/components/content/text/text.styles.js.map +1 -0
  67. package/dist/components/content/text/text.template.d.ts +3 -0
  68. package/dist/components/content/text/text.template.d.ts.map +1 -0
  69. package/dist/components/content/text/text.template.js +7 -0
  70. package/dist/components/content/text/text.template.js.map +1 -0
  71. package/dist/components/content/title/title.d.ts +4 -4
  72. package/dist/components/content/title/title.js +4 -4
  73. package/dist/components/content/title/title.styles.d.ts.map +1 -1
  74. package/dist/components/content/title/title.styles.js +9 -13
  75. package/dist/components/content/title/title.styles.js.map +1 -1
  76. package/dist/components/content/tooltip/tooltip.d.ts +1 -1
  77. package/dist/components/content/tooltip/tooltip.js +1 -1
  78. package/dist/components/{decorate-BKn10QQi.js → decorate-lwt_OrAG.js} +1 -1
  79. package/dist/components/{dist-TpIL8G4G.js → dist-762GHPyH.js} +3 -3
  80. package/dist/components/{dist-OBifyiJS.js → dist-BB7TxeMK.js} +2 -2
  81. package/dist/components/{dist-CJR_Rwhh.js → dist-BJI4-6iQ.js} +1 -1
  82. package/dist/components/{dist-C400RcFU.js → dist-B_3OW7pC.js} +1 -1
  83. package/dist/components/{dist-afrAoubg.js → dist-C09E9-dJ.js} +34 -34
  84. package/dist/components/{dist-Ccw7ZfsU.js → dist-C6gnorjP.js} +4 -3
  85. package/dist/components/{dist-bO14jlsr.js → dist-CRsR6ckU.js} +1 -1
  86. package/dist/components/{dist-C0PiB1dr.js → dist-CjaG8dOI.js} +2 -2
  87. package/dist/components/{dist-CCg5Mso_.js → dist-DZoFKUO-.js} +1 -1
  88. package/dist/components/{dist-Bq4xc7Bm.js → dist-DaavuU6W.js} +14 -3
  89. package/dist/components/{dist-BYVOPNHp.js → dist-la_b3ZSq.js} +1 -1
  90. package/dist/components/forms/form/form.d.ts +76 -22
  91. package/dist/components/forms/form/form.d.ts.map +1 -1
  92. package/dist/components/forms/form/form.js +127 -22
  93. package/dist/components/forms/form/form.js.map +1 -1
  94. package/dist/components/forms/form-actions/form-actions.d.ts +14 -15
  95. package/dist/components/forms/form-actions/form-actions.d.ts.map +1 -1
  96. package/dist/components/forms/form-actions/form-actions.js +14 -15
  97. package/dist/components/forms/form-actions/form-actions.js.map +1 -1
  98. package/dist/components/forms/form-field/form-field.d.ts +42 -39
  99. package/dist/components/forms/form-field/form-field.d.ts.map +1 -1
  100. package/dist/components/forms/form-field/form-field.js +79 -111
  101. package/dist/components/forms/form-field/form-field.js.map +1 -1
  102. package/dist/components/forms/form-field/form-field.styles.d.ts +0 -1
  103. package/dist/components/forms/form-field/form-field.styles.d.ts.map +1 -1
  104. package/dist/components/forms/form-field/form-field.styles.js +7 -73
  105. package/dist/components/forms/form-field/form-field.styles.js.map +1 -1
  106. package/dist/components/forms/form-field/form-field.template.d.ts +0 -2
  107. package/dist/components/forms/form-field/form-field.template.d.ts.map +1 -1
  108. package/dist/components/forms/form-field/form-field.template.js +0 -15
  109. package/dist/components/forms/form-field/form-field.template.js.map +1 -1
  110. package/dist/components/forms/form-section/form-section.d.ts +26 -28
  111. package/dist/components/forms/form-section/form-section.d.ts.map +1 -1
  112. package/dist/components/forms/form-section/form-section.js +27 -29
  113. package/dist/components/forms/form-section/form-section.js.map +1 -1
  114. package/dist/components/forms/validation-list/validation-list.d.ts +193 -0
  115. package/dist/components/forms/validation-list/validation-list.d.ts.map +1 -0
  116. package/dist/components/forms/validation-list/validation-list.js +358 -0
  117. package/dist/components/forms/validation-list/validation-list.js.map +1 -0
  118. package/dist/components/forms/validation-list/validation-list.styles.d.ts +3 -0
  119. package/dist/components/forms/validation-list/validation-list.styles.d.ts.map +1 -0
  120. package/dist/components/forms/validation-list/validation-list.styles.js +58 -0
  121. package/dist/components/forms/validation-list/validation-list.styles.js.map +1 -0
  122. package/dist/components/forms/validation-list/validation-list.template.d.ts +5 -0
  123. package/dist/components/forms/validation-list/validation-list.template.d.ts.map +1 -0
  124. package/dist/components/forms/validation-list/validation-list.template.js +16 -0
  125. package/dist/components/forms/validation-list/validation-list.template.js.map +1 -0
  126. package/dist/components/{icon-CIpJq_cf.js → icon-VTLbdcvZ.js} +104 -11
  127. package/dist/components/{icon-button-BAkUJTn6.js → icon-button-Sne5TwRG.js} +6 -6
  128. package/dist/components/index.d.ts +3 -1
  129. package/dist/components/index.d.ts.map +1 -1
  130. package/dist/components/index.js +3 -1
  131. package/dist/components/index.js.map +1 -1
  132. package/dist/components/inputs/checkbox/checkbox.d.ts +20 -1
  133. package/dist/components/inputs/checkbox/checkbox.d.ts.map +1 -1
  134. package/dist/components/inputs/checkbox/checkbox.js +32 -2
  135. package/dist/components/inputs/checkbox/checkbox.js.map +1 -1
  136. package/dist/components/inputs/checkbox/checkbox.template.d.ts.map +1 -1
  137. package/dist/components/inputs/checkbox/checkbox.template.js +2 -0
  138. package/dist/components/inputs/checkbox/checkbox.template.js.map +1 -1
  139. package/dist/components/inputs/checkbox-field/checkbox-field.d.ts +16 -1
  140. package/dist/components/inputs/checkbox-field/checkbox-field.d.ts.map +1 -1
  141. package/dist/components/inputs/checkbox-field/checkbox-field.js +27 -2
  142. package/dist/components/inputs/checkbox-field/checkbox-field.js.map +1 -1
  143. package/dist/components/inputs/checkbox-field/checkbox-field.template.d.ts.map +1 -1
  144. package/dist/components/inputs/checkbox-field/checkbox-field.template.js +2 -0
  145. package/dist/components/inputs/checkbox-field/checkbox-field.template.js.map +1 -1
  146. package/dist/components/inputs/code-editor/code-editor.d.ts +14 -1
  147. package/dist/components/inputs/code-editor/code-editor.d.ts.map +1 -1
  148. package/dist/components/inputs/code-editor/code-editor.js +21 -2
  149. package/dist/components/inputs/code-editor/code-editor.js.map +1 -1
  150. package/dist/components/inputs/combo-box/combo-box.d.ts +15 -2
  151. package/dist/components/inputs/combo-box/combo-box.d.ts.map +1 -1
  152. package/dist/components/inputs/combo-box/combo-box.js +54 -5
  153. package/dist/components/inputs/combo-box/combo-box.js.map +1 -1
  154. package/dist/components/inputs/combo-box/combo-box.styles.d.ts.map +1 -1
  155. package/dist/components/inputs/combo-box/combo-box.styles.js +14 -0
  156. package/dist/components/inputs/combo-box/combo-box.styles.js.map +1 -1
  157. package/dist/components/inputs/combo-box/combo-box.template.d.ts.map +1 -1
  158. package/dist/components/inputs/combo-box/combo-box.template.js +27 -20
  159. package/dist/components/inputs/combo-box/combo-box.template.js.map +1 -1
  160. package/dist/components/inputs/date-field/date-field.d.ts +29 -31
  161. package/dist/components/inputs/date-field/date-field.d.ts.map +1 -1
  162. package/dist/components/inputs/date-field/date-field.js +40 -37
  163. package/dist/components/inputs/date-field/date-field.js.map +1 -1
  164. package/dist/components/inputs/date-field/date-field.styles.d.ts.map +1 -1
  165. package/dist/components/inputs/date-field/date-field.styles.js +11 -0
  166. package/dist/components/inputs/date-field/date-field.styles.js.map +1 -1
  167. package/dist/components/inputs/date-field/date-field.template.d.ts.map +1 -1
  168. package/dist/components/inputs/date-field/date-field.template.js +7 -2
  169. package/dist/components/inputs/date-field/date-field.template.js.map +1 -1
  170. package/dist/components/inputs/date-picker/date-picker.d.ts +34 -21
  171. package/dist/components/inputs/date-picker/date-picker.d.ts.map +1 -1
  172. package/dist/components/inputs/date-picker/date-picker.js +42 -22
  173. package/dist/components/inputs/date-picker/date-picker.js.map +1 -1
  174. package/dist/components/inputs/dropdown/dropdown.d.ts +23 -2
  175. package/dist/components/inputs/dropdown/dropdown.d.ts.map +1 -1
  176. package/dist/components/inputs/dropdown/dropdown.js +36 -3
  177. package/dist/components/inputs/dropdown/dropdown.js.map +1 -1
  178. package/dist/components/inputs/file-field/file-field.d.ts +4 -3
  179. package/dist/components/inputs/file-field/file-field.d.ts.map +1 -1
  180. package/dist/components/inputs/file-field/file-field.js +8 -7
  181. package/dist/components/inputs/file-field/file-field.js.map +1 -1
  182. package/dist/components/inputs/file-field/file-field.template.d.ts.map +1 -1
  183. package/dist/components/inputs/file-field/file-field.template.js +0 -1
  184. package/dist/components/inputs/file-field/file-field.template.js.map +1 -1
  185. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.d.ts +15 -4
  186. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.d.ts.map +1 -1
  187. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.js +20 -8
  188. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.js.map +1 -1
  189. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.template.d.ts.map +1 -1
  190. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.template.js +4 -1
  191. package/dist/components/inputs/multi-line-text-field/multi-line-text-field.template.js.map +1 -1
  192. package/dist/components/inputs/number-field/number-field.d.ts +12 -1
  193. package/dist/components/inputs/number-field/number-field.d.ts.map +1 -1
  194. package/dist/components/inputs/number-field/number-field.js +18 -3
  195. package/dist/components/inputs/number-field/number-field.js.map +1 -1
  196. package/dist/components/inputs/number-field/number-field.styles.d.ts.map +1 -1
  197. package/dist/components/inputs/number-field/number-field.styles.js +8 -16
  198. package/dist/components/inputs/number-field/number-field.styles.js.map +1 -1
  199. package/dist/components/inputs/password-field/password-field.d.ts +10 -3
  200. package/dist/components/inputs/password-field/password-field.d.ts.map +1 -1
  201. package/dist/components/inputs/password-field/password-field.js +18 -8
  202. package/dist/components/inputs/password-field/password-field.js.map +1 -1
  203. package/dist/components/inputs/password-field/password-field.template.d.ts.map +1 -1
  204. package/dist/components/inputs/password-field/password-field.template.js +3 -1
  205. package/dist/components/inputs/password-field/password-field.template.js.map +1 -1
  206. package/dist/components/inputs/radio-button/radio-button.d.ts +18 -1
  207. package/dist/components/inputs/radio-button/radio-button.d.ts.map +1 -1
  208. package/dist/components/inputs/radio-button/radio-button.js +27 -2
  209. package/dist/components/inputs/radio-button/radio-button.js.map +1 -1
  210. package/dist/components/inputs/radio-button/radio-button.template.d.ts.map +1 -1
  211. package/dist/components/inputs/radio-button/radio-button.template.js +1 -0
  212. package/dist/components/inputs/radio-button/radio-button.template.js.map +1 -1
  213. package/dist/components/inputs/radio-button-field/radio-button-field.d.ts +14 -1
  214. package/dist/components/inputs/radio-button-field/radio-button-field.d.ts.map +1 -1
  215. package/dist/components/inputs/radio-button-field/radio-button-field.js +22 -2
  216. package/dist/components/inputs/radio-button-field/radio-button-field.js.map +1 -1
  217. package/dist/components/inputs/radio-button-field/radio-button-field.template.d.ts.map +1 -1
  218. package/dist/components/inputs/radio-button-field/radio-button-field.template.js +1 -0
  219. package/dist/components/inputs/radio-button-field/radio-button-field.template.js.map +1 -1
  220. package/dist/components/inputs/radio-button-group/radio-button-group.d.ts +11 -0
  221. package/dist/components/inputs/radio-button-group/radio-button-group.d.ts.map +1 -1
  222. package/dist/components/inputs/radio-button-group/radio-button-group.js +21 -0
  223. package/dist/components/inputs/radio-button-group/radio-button-group.js.map +1 -1
  224. package/dist/components/inputs/search-field/search-field.d.ts +23 -1
  225. package/dist/components/inputs/search-field/search-field.d.ts.map +1 -1
  226. package/dist/components/inputs/search-field/search-field.js +37 -3
  227. package/dist/components/inputs/search-field/search-field.js.map +1 -1
  228. package/dist/components/inputs/search-field/search-field.template.d.ts.map +1 -1
  229. package/dist/components/inputs/search-field/search-field.template.js +4 -0
  230. package/dist/components/inputs/search-field/search-field.template.js.map +1 -1
  231. package/dist/components/inputs/segmented-control/segmented-control.d.ts +28 -0
  232. package/dist/components/inputs/segmented-control/segmented-control.d.ts.map +1 -1
  233. package/dist/components/inputs/segmented-control/segmented-control.js +52 -2
  234. package/dist/components/inputs/segmented-control/segmented-control.js.map +1 -1
  235. package/dist/components/inputs/segmented-control/segmented-control.template.d.ts.map +1 -1
  236. package/dist/components/inputs/segmented-control/segmented-control.template.js +1 -0
  237. package/dist/components/inputs/segmented-control/segmented-control.template.js.map +1 -1
  238. package/dist/components/inputs/stepper/stepper.d.ts +14 -1
  239. package/dist/components/inputs/stepper/stepper.d.ts.map +1 -1
  240. package/dist/components/inputs/stepper/stepper.js +21 -2
  241. package/dist/components/inputs/stepper/stepper.js.map +1 -1
  242. package/dist/components/inputs/switch/switch.d.ts +20 -1
  243. package/dist/components/inputs/switch/switch.d.ts.map +1 -1
  244. package/dist/components/inputs/switch/switch.js +31 -2
  245. package/dist/components/inputs/switch/switch.js.map +1 -1
  246. package/dist/components/inputs/switch/switch.template.d.ts.map +1 -1
  247. package/dist/components/inputs/switch/switch.template.js +2 -0
  248. package/dist/components/inputs/switch/switch.template.js.map +1 -1
  249. package/dist/components/inputs/switch-field/switch-field.d.ts +18 -1
  250. package/dist/components/inputs/switch-field/switch-field.d.ts.map +1 -1
  251. package/dist/components/inputs/switch-field/switch-field.js +25 -1
  252. package/dist/components/inputs/switch-field/switch-field.js.map +1 -1
  253. package/dist/components/inputs/switch-field/switch-field.template.d.ts.map +1 -1
  254. package/dist/components/inputs/switch-field/switch-field.template.js +2 -0
  255. package/dist/components/inputs/switch-field/switch-field.template.js.map +1 -1
  256. package/dist/components/inputs/text-editor/text-editor.d.ts +14 -1
  257. package/dist/components/inputs/text-editor/text-editor.d.ts.map +1 -1
  258. package/dist/components/inputs/text-editor/text-editor.js +21 -2
  259. package/dist/components/inputs/text-editor/text-editor.js.map +1 -1
  260. package/dist/components/inputs/text-field/text-field.d.ts +31 -3
  261. package/dist/components/inputs/text-field/text-field.d.ts.map +1 -1
  262. package/dist/components/inputs/text-field/text-field.js +65 -7
  263. package/dist/components/inputs/text-field/text-field.js.map +1 -1
  264. package/dist/components/inputs/text-field/text-field.template.d.ts.map +1 -1
  265. package/dist/components/inputs/text-field/text-field.template.js +5 -1
  266. package/dist/components/inputs/text-field/text-field.template.js.map +1 -1
  267. package/dist/components/inputs/time-field/time-field.d.ts +33 -35
  268. package/dist/components/inputs/time-field/time-field.d.ts.map +1 -1
  269. package/dist/components/inputs/time-field/time-field.js +43 -40
  270. package/dist/components/inputs/time-field/time-field.js.map +1 -1
  271. package/dist/components/inputs/time-field/time-field.styles.d.ts.map +1 -1
  272. package/dist/components/inputs/time-field/time-field.styles.js +12 -0
  273. package/dist/components/inputs/time-field/time-field.styles.js.map +1 -1
  274. package/dist/components/inputs/time-field/time-field.template.d.ts.map +1 -1
  275. package/dist/components/inputs/time-field/time-field.template.js +7 -2
  276. package/dist/components/inputs/time-field/time-field.template.js.map +1 -1
  277. package/dist/components/inputs/time-picker/time-picker.d.ts +34 -19
  278. package/dist/components/inputs/time-picker/time-picker.d.ts.map +1 -1
  279. package/dist/components/inputs/time-picker/time-picker.js +42 -22
  280. package/dist/components/inputs/time-picker/time-picker.js.map +1 -1
  281. package/dist/components/inputs/toggle-button/toggle-button.d.ts +22 -1
  282. package/dist/components/inputs/toggle-button/toggle-button.d.ts.map +1 -1
  283. package/dist/components/inputs/toggle-button/toggle-button.js +35 -2
  284. package/dist/components/inputs/toggle-button/toggle-button.js.map +1 -1
  285. package/dist/components/inputs/toggle-button/toggle-button.template.d.ts.map +1 -1
  286. package/dist/components/inputs/toggle-button/toggle-button.template.js +3 -0
  287. package/dist/components/inputs/toggle-button/toggle-button.template.js.map +1 -1
  288. package/dist/components/inputs/toggle-button-group/toggle-button-group.d.ts +27 -0
  289. package/dist/components/inputs/toggle-button-group/toggle-button-group.d.ts.map +1 -1
  290. package/dist/components/inputs/toggle-button-group/toggle-button-group.js +46 -0
  291. package/dist/components/inputs/toggle-button-group/toggle-button-group.js.map +1 -1
  292. package/dist/components/inputs/token-field/token-field.d.ts +7 -1
  293. package/dist/components/inputs/token-field/token-field.d.ts.map +1 -1
  294. package/dist/components/inputs/token-field/token-field.js +14 -1
  295. package/dist/components/inputs/token-field/token-field.js.map +1 -1
  296. package/dist/components/layout/app-view/app-view.d.ts.map +1 -1
  297. package/dist/components/layout/app-view/app-view.js +12 -0
  298. package/dist/components/layout/app-view/app-view.js.map +1 -1
  299. package/dist/components/layout/box/box.d.ts +4 -4
  300. package/dist/components/layout/box/box.d.ts.map +1 -1
  301. package/dist/components/layout/box/box.js +4 -4
  302. package/dist/components/layout/box/box.js.map +1 -1
  303. package/dist/components/layout/box/box.styles.d.ts.map +1 -1
  304. package/dist/components/layout/box/box.styles.js +4 -6
  305. package/dist/components/layout/box/box.styles.js.map +1 -1
  306. package/dist/components/layout/card/card.d.ts +18 -19
  307. package/dist/components/layout/card/card.d.ts.map +1 -1
  308. package/dist/components/layout/card/card.js +18 -19
  309. package/dist/components/layout/card/card.js.map +1 -1
  310. package/dist/components/layout/card/card.styles.d.ts.map +1 -1
  311. package/dist/components/layout/card/card.styles.js +1 -0
  312. package/dist/components/layout/card/card.styles.js.map +1 -1
  313. package/dist/components/layout/collection/collection.d.ts.map +1 -1
  314. package/dist/components/layout/collection/collection.js +6 -2
  315. package/dist/components/layout/collection/collection.js.map +1 -1
  316. package/dist/components/layout/divider/divider.d.ts +1 -1
  317. package/dist/components/layout/divider/divider.js +1 -1
  318. package/dist/components/layout/popover/popover.d.ts +1 -1
  319. package/dist/components/layout/popover/popover.d.ts.map +1 -1
  320. package/dist/components/layout/popover/popover.js +15 -2
  321. package/dist/components/layout/popover/popover.js.map +1 -1
  322. package/dist/components/layout/sheet/sheet.d.ts +1 -1
  323. package/dist/components/layout/sheet/sheet.js +2 -2
  324. package/dist/components/layout/sheet/sheet.js.map +1 -1
  325. package/dist/components/layout/sheet/sheet.styles.d.ts.map +1 -1
  326. package/dist/components/layout/sheet/sheet.styles.js +15 -3
  327. package/dist/components/layout/sheet/sheet.styles.js.map +1 -1
  328. package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.d.ts +8 -0
  329. package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.d.ts.map +1 -1
  330. package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.js +29 -11
  331. package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.js.map +1 -1
  332. package/dist/components/layout/window/window.d.ts +20 -21
  333. package/dist/components/layout/window/window.d.ts.map +1 -1
  334. package/dist/components/layout/window/window.js +21 -22
  335. package/dist/components/layout/window/window.js.map +1 -1
  336. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.d.ts +41 -12
  337. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.d.ts.map +1 -1
  338. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.js +47 -17
  339. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.js.map +1 -1
  340. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.styles.d.ts.map +1 -1
  341. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.styles.js +42 -13
  342. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.styles.js.map +1 -1
  343. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.template.d.ts.map +1 -1
  344. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.template.js +12 -4
  345. package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.template.js.map +1 -1
  346. package/dist/components/lists-and-tables/list/list.d.ts +168 -61
  347. package/dist/components/lists-and-tables/list/list.d.ts.map +1 -1
  348. package/dist/components/lists-and-tables/list/list.i18n.d.ts +0 -1
  349. package/dist/components/lists-and-tables/list/list.i18n.d.ts.map +1 -1
  350. package/dist/components/lists-and-tables/list/list.i18n.js +0 -1
  351. package/dist/components/lists-and-tables/list/list.i18n.js.map +1 -1
  352. package/dist/components/lists-and-tables/list/list.js +361 -122
  353. package/dist/components/lists-and-tables/list/list.js.map +1 -1
  354. package/dist/components/lists-and-tables/list/list.styles.d.ts.map +1 -1
  355. package/dist/components/lists-and-tables/list/list.styles.js +5 -0
  356. package/dist/components/lists-and-tables/list/list.styles.js.map +1 -1
  357. package/dist/components/lists-and-tables/list/list.template.d.ts +1 -3
  358. package/dist/components/lists-and-tables/list/list.template.d.ts.map +1 -1
  359. package/dist/components/lists-and-tables/list/list.template.js +2 -7
  360. package/dist/components/lists-and-tables/list/list.template.js.map +1 -1
  361. package/dist/components/lists-and-tables/list-item/list-item.d.ts +134 -23
  362. package/dist/components/lists-and-tables/list-item/list-item.d.ts.map +1 -1
  363. package/dist/components/lists-and-tables/list-item/list-item.js +354 -61
  364. package/dist/components/lists-and-tables/list-item/list-item.js.map +1 -1
  365. package/dist/components/lists-and-tables/list-item/list-item.styles.d.ts.map +1 -1
  366. package/dist/components/lists-and-tables/list-item/list-item.styles.js +116 -34
  367. package/dist/components/lists-and-tables/list-item/list-item.styles.js.map +1 -1
  368. package/dist/components/lists-and-tables/list-item/list-item.template.d.ts +1 -1
  369. package/dist/components/lists-and-tables/list-item/list-item.template.d.ts.map +1 -1
  370. package/dist/components/lists-and-tables/list-item/list-item.template.js +5 -2
  371. package/dist/components/lists-and-tables/list-item/list-item.template.js.map +1 -1
  372. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.d.ts +116 -0
  373. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.d.ts.map +1 -0
  374. package/dist/components/lists-and-tables/{list-item-action/list-item-action.js → list-item-segment/list-item-segment.js} +85 -56
  375. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.js.map +1 -0
  376. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.styles.d.ts +2 -0
  377. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.styles.d.ts.map +1 -0
  378. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.styles.js +179 -0
  379. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.styles.js.map +1 -0
  380. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.d.ts +3 -0
  381. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.d.ts.map +1 -0
  382. package/dist/components/lists-and-tables/{list-item-action/list-item-action.template.js → list-item-segment/list-item-segment.template.js} +5 -4
  383. package/dist/components/lists-and-tables/list-item-segment/list-item-segment.template.js.map +1 -0
  384. package/dist/components/lists-and-tables/table/table.d.ts +12 -9
  385. package/dist/components/lists-and-tables/table/table.d.ts.map +1 -1
  386. package/dist/components/lists-and-tables/table/table.i18n.d.ts +0 -1
  387. package/dist/components/lists-and-tables/table/table.i18n.d.ts.map +1 -1
  388. package/dist/components/lists-and-tables/table/table.i18n.js +0 -1
  389. package/dist/components/lists-and-tables/table/table.i18n.js.map +1 -1
  390. package/dist/components/lists-and-tables/table/table.js +26 -16
  391. package/dist/components/lists-and-tables/table/table.js.map +1 -1
  392. package/dist/components/lists-and-tables/table/table.styles.d.ts.map +1 -1
  393. package/dist/components/lists-and-tables/table/table.styles.js +5 -0
  394. package/dist/components/lists-and-tables/table/table.styles.js.map +1 -1
  395. package/dist/components/lists-and-tables/table/table.template.d.ts +1 -1
  396. package/dist/components/lists-and-tables/table/table.template.d.ts.map +1 -1
  397. package/dist/components/lists-and-tables/table/table.template.js +5 -9
  398. package/dist/components/lists-and-tables/table/table.template.js.map +1 -1
  399. package/dist/components/navigation/link/link.d.ts +30 -24
  400. package/dist/components/navigation/link/link.d.ts.map +1 -1
  401. package/dist/components/navigation/link/link.js +33 -24
  402. package/dist/components/navigation/link/link.js.map +1 -1
  403. package/dist/components/navigation/link/link.template.js +1 -1
  404. package/dist/components/navigation/link/link.template.js.map +1 -1
  405. package/dist/components/navigation/menu-bar/menu-bar.d.ts +7 -7
  406. package/dist/components/navigation/menu-bar/menu-bar.js +7 -7
  407. package/dist/components/navigation/menu-bar-item/menu-bar-item.d.ts +23 -23
  408. package/dist/components/navigation/menu-bar-item/menu-bar-item.js +23 -23
  409. package/dist/components/navigation/pagination/pagination.d.ts +4 -4
  410. package/dist/components/navigation/pagination/pagination.js +4 -4
  411. package/dist/components/navigation/skip-link/skip-link.d.ts +7 -7
  412. package/dist/components/navigation/skip-link/skip-link.js +7 -7
  413. package/dist/components/navigation/tab-bar/tab-bar.d.ts +5 -3
  414. package/dist/components/navigation/tab-bar/tab-bar.d.ts.map +1 -1
  415. package/dist/components/navigation/tab-bar/tab-bar.js +18 -13
  416. package/dist/components/navigation/tab-bar/tab-bar.js.map +1 -1
  417. package/dist/components/navigation/tab-bar/tab-bar.styles.js +8 -8
  418. package/dist/components/navigation/tab-bar/tab-bar.template.js +5 -5
  419. package/dist/components/navigation/tab-bar/tab-bar.template.js.map +1 -1
  420. package/dist/components/navigation/top-navigation-bar/top-navigation-bar.d.ts +15 -15
  421. package/dist/components/navigation/top-navigation-bar/top-navigation-bar.js +15 -15
  422. package/dist/components/navigation/top-navigation-bar/top-navigation-bar.styles.d.ts.map +1 -1
  423. package/dist/components/navigation/top-navigation-bar/top-navigation-bar.styles.js +14 -2
  424. package/dist/components/navigation/top-navigation-bar/top-navigation-bar.styles.js.map +1 -1
  425. package/dist/components/navigation/top-title-bar/top-title-bar.d.ts +2 -2
  426. package/dist/components/navigation/top-title-bar/top-title-bar.js +2 -2
  427. package/dist/components/navigation/top-title-bar/top-title-bar.styles.js +2 -2
  428. package/dist/components/status-and-feedback/badge/badge.d.ts +8 -2
  429. package/dist/components/status-and-feedback/badge/badge.d.ts.map +1 -1
  430. package/dist/components/status-and-feedback/badge/badge.js +17 -1
  431. package/dist/components/status-and-feedback/badge/badge.js.map +1 -1
  432. package/dist/components/status-and-feedback/badge/badge.styles.d.ts.map +1 -1
  433. package/dist/components/status-and-feedback/badge/badge.styles.js +41 -10
  434. package/dist/components/status-and-feedback/badge/badge.styles.js.map +1 -1
  435. package/dist/components/status-and-feedback/badge/badge.template.js +1 -1
  436. package/dist/components/status-and-feedback/badge/badge.template.js.map +1 -1
  437. package/dist/components/status-and-feedback/banner/banner.styles.js +2 -2
  438. package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.d.ts +37 -36
  439. package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.d.ts.map +1 -1
  440. package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.js +37 -36
  441. package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.js.map +1 -1
  442. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.d.ts +1 -1
  443. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js +2 -2
  444. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js.map +1 -1
  445. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.styles.d.ts.map +1 -1
  446. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.styles.js +7 -0
  447. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.styles.js.map +1 -1
  448. package/dist/components/status-and-feedback/notification/notification-region.js +1 -1
  449. package/dist/components/status-and-feedback/status-bar/status-bar.d.ts +29 -28
  450. package/dist/components/status-and-feedback/status-bar/status-bar.d.ts.map +1 -1
  451. package/dist/components/status-and-feedback/status-bar/status-bar.js +29 -28
  452. package/dist/components/status-and-feedback/status-bar/status-bar.js.map +1 -1
  453. package/dist/components/status-and-feedback/step-indicator/step-indicator.styles.js +1 -1
  454. package/dist/components/{visibility-mixin-GxbwkBb1.js → visibility-mixin-vbfhyo7f.js} +1 -1
  455. package/dist/components/{with-translations-DzAdFTK8.js → with-translations-CqUV9S5g.js} +1 -1
  456. package/dist/css/form-section.css +28 -46
  457. package/dist/css/form.css +7 -13
  458. package/dist/css/rich-text.css +5 -5
  459. package/dist/css/variables.css +133 -8
  460. package/dist/nldd.min.js +1382 -875
  461. package/dist/types/vue.d.ts +530 -336
  462. package/dist/utilities/codemirror/codemirror-element.d.ts.map +1 -1
  463. package/dist/utilities/codemirror/codemirror-element.js +5 -0
  464. package/dist/utilities/codemirror/codemirror-element.js.map +1 -1
  465. package/dist/utilities/described-by-mixin.d.ts +49 -0
  466. package/dist/utilities/described-by-mixin.d.ts.map +1 -0
  467. package/dist/utilities/described-by-mixin.js +109 -0
  468. package/dist/utilities/described-by-mixin.js.map +1 -0
  469. package/dist/utilities/form-associated-mixin.d.ts +5 -0
  470. package/dist/utilities/form-associated-mixin.d.ts.map +1 -1
  471. package/dist/utilities/form-associated-mixin.js +69 -0
  472. package/dist/utilities/form-associated-mixin.js.map +1 -1
  473. package/dist/utilities/scroll-mode-controller.d.ts +9 -1
  474. package/dist/utilities/scroll-mode-controller.d.ts.map +1 -1
  475. package/dist/utilities/scroll-mode-controller.js +10 -2
  476. package/dist/utilities/scroll-mode-controller.js.map +1 -1
  477. package/package.json +21 -9
  478. package/dist/components/lists-and-tables/list-item-action/list-item-action.d.ts +0 -108
  479. package/dist/components/lists-and-tables/list-item-action/list-item-action.d.ts.map +0 -1
  480. package/dist/components/lists-and-tables/list-item-action/list-item-action.js.map +0 -1
  481. package/dist/components/lists-and-tables/list-item-action/list-item-action.styles.d.ts +0 -2
  482. package/dist/components/lists-and-tables/list-item-action/list-item-action.styles.d.ts.map +0 -1
  483. package/dist/components/lists-and-tables/list-item-action/list-item-action.styles.js +0 -145
  484. package/dist/components/lists-and-tables/list-item-action/list-item-action.styles.js.map +0 -1
  485. package/dist/components/lists-and-tables/list-item-action/list-item-action.template.d.ts +0 -3
  486. package/dist/components/lists-and-tables/list-item-action/list-item-action.template.d.ts.map +0 -1
  487. package/dist/components/lists-and-tables/list-item-action/list-item-action.template.js.map +0 -1
@@ -14,6 +14,9 @@ import { nlddListTranslations } from './list.i18n.js';
14
14
  import '../../status-and-feedback/inline-dialog/inline-dialog.js';
15
15
  import '../../content/icon/icon.js';
16
16
  import '../../actions/icon-button/icon-button.js';
17
+ /** What the browser counts as a tab stop in a shadow root: focusable, enabled,
18
+ * and not parked at a negative tabindex. */
19
+ const SHADOW_TAB_STOP = ':is(a[href], button, input, select, textarea, [tabindex]):not([tabindex^="-"]):not(:disabled)';
17
20
  /**
18
21
  * A container for `nldd-list-item` elements.
19
22
  *
@@ -28,6 +31,16 @@ import '../../actions/icon-button/icon-button.js';
28
31
  * spacer-cell per level. Comes with its own keyboard, see "Tree" below.
29
32
  * - `navigation` — host `role="navigation"`, items with `selected` get
30
33
  * `aria-current="page"` on their inner `<a>` or `<button>`.
34
+ * - `form` — rows that are not actions themselves: the controls inside them
35
+ * are. A row of a label and a field, a switch, a menu button, or a value you
36
+ * cannot change at all. Semantically the same as `list` (`role="list"`,
37
+ * `role="listitem"`), and everything visual is unchanged; what falls away is
38
+ * the keyboard of a list you walk through. No arrow navigation, so no
39
+ * promise of it either, and no tab stop on the row: Tab goes straight to the
40
+ * controls, in source order, the way it does in any form. Rows that ARE
41
+ * actions (`href`, `button`, `checkbox`, or a segment) contradict that and
42
+ * warn in development. SwiftUI draws the same line between `List` and
43
+ * `Form`, for the same reason.
31
44
  * - `listbox` — an accessible, filterable listbox (combobox pattern). The
32
45
  * list renders its OWN search input (`role="combobox"`) pinned
33
46
  * above the options; `.list__items` becomes `role="listbox"`
@@ -38,6 +51,39 @@ import '../../actions/icon-button/icon-button.js';
38
51
  *
39
52
  * Selection state is consumer-managed: the list never mutates `selected` itself.
40
53
  *
54
+ * ### Keyboard
55
+ *
56
+ * A list you walk through answers to the arrow keys, and there is no attribute to
57
+ * switch that on. Whether the keys do something is not a property of one list: it
58
+ * is what a reader may assume about all of them, and a per-list setting made that
59
+ * unknowable from the outside. It follows the type, which you can see before you
60
+ * touch a key.
61
+ *
62
+ * - ArrowUp / ArrowDown — move focus between the rows there is something to do
63
+ * with. A row of nothing but text is skipped, because focus that leads nowhere
64
+ * is a dead end.
65
+ * - Home / End — the first / last of those rows.
66
+ * - Tab — the list is ONE tab stop, so Tab moves past it rather than through it.
67
+ * Within the current row Tab walks that row's own controls: a chevron beside a
68
+ * checkbox, a menu button at the end. The same controls in the other rows are
69
+ * held out of the tab order (`tabindex="-1"`, or `no-tab` on a design-system
70
+ * control that keeps its tab stop in its own shadow root), and so are this
71
+ * row's once focus leaves the list, so tabbing back in lands on the row again.
72
+ * - Escape — out of a control the row holds, back onto the row. One level up,
73
+ * where Shift+Tab is one step back. On the row itself the list claims nothing,
74
+ * so Escape carries on to whatever holds the list, and a control showing a
75
+ * menu keeps the first press for closing that menu.
76
+ *
77
+ * While focus sits in a control a row holds, the list stands down: those keys
78
+ * are the control's, and a list that took them anyway would pull focus out of a
79
+ * combo box or a text field mid-word. What the row IS — its own link, button or
80
+ * segments — keeps answering here.
81
+ *
82
+ * Arrows move focus only; selection stays consumer-managed. Three types answer
83
+ * differently, and all three say so on screen before you touch a key: a listbox
84
+ * runs its keyboard from its search field, a reorderable list moves rows with the
85
+ * arrows, and a form has no rows to move between at all.
86
+ *
41
87
  * ### Listbox
42
88
  *
43
89
  * In `type="listbox"` the list owns a native `<input role="combobox">` (mirroring
@@ -56,24 +102,23 @@ import '../../actions/icon-button/icon-button.js';
56
102
  * on the item, a highlight) is distinct from `selected`. Filtering is the
57
103
  * consumer's job: listen to `input` (`{ detail: { value } }`) and toggle `[hidden]`
58
104
  * on items; after the visible set changes the list resets the active option to the
59
- * first visible one. `reorderable` and `arrow-navigation` are ignored in listbox
60
- * mode (listbox has its own keyboard).
105
+ * first visible one. `reorderable` and the roving arrow keys are ignored in
106
+ * listbox mode (listbox has its own keyboard).
61
107
  *
62
108
  * ### Tree
63
109
  *
64
- * A tree is a composite widget, so it brings its own keyboard `arrow-navigation`
65
- * is implied and needn't be set:
66
- * - ArrowDown / ArrowUp — move between the rows in the order they appear on
67
- * screen, the rows of an open branch included.
68
- * - Home / End — first / last row.
110
+ * A tree adds to that keyboard, and counts the rows of an open branch as part of
111
+ * the order the arrows walk:
69
112
  * - ArrowRight — opens a closed branch; on an open one it steps to its first child.
70
113
  * - ArrowLeft — closes an open branch; on a leaf it steps out to the parent row.
71
- * - Enter / Space open and close, the same as Right and Left. Only while focus
114
+ * - Enter follows the row: its own link or button, or on a segmented branch the
115
+ * first action that is not the chevron. A branch with only a chevron folds instead.
116
+ * - Space — open and close, the same as Right and Left. Only while focus
72
117
  * sits on the row itself: a row that is its own control, and a segmented
73
118
  * action you tabbed into, handle both keys themselves.
74
119
  *
75
120
  * Opening and closing runs through the row's own disclosure control — the
76
- * segmented action marked `disclosure`, or the row itself when it is a button.
121
+ * segment marked `disclosure`, or the row itself when it is a button.
77
122
  * The list activates that control rather than writing `expanded`, so the state
78
123
  * keeps being set in one place: the consumer's handler. A row that is a link is
79
124
  * never activated this way, since that would navigate away.
@@ -103,20 +148,17 @@ import '../../actions/icon-button/icon-button.js';
103
148
  * @element nldd-list
104
149
  *
105
150
  * @attr {'simple'|'box-tinted'|'box-base'} variant - Visual style (default 'simple'): `simple` is a plain vertical strip with no chrome, the two `box` values a framed card with rounded corners, fill and inset border ring. `box-tinted` for a list on a plain page, `box-base` for one on an already-tinted parent (the border ring gets +2 palette steps so it still reads against a card-on-card)
106
- * @attr {'list'|'navigation'|'listbox'|'tree'} type - A11y role and behavior (default 'list'). See the docblock above.
107
- * @attr {boolean} reorderable - Enables drag-to-reorder and pushes `reorderable` onto the items. Only valid with `type="list"`; wins over `arrow-navigation` when both are set.
151
+ * @attr {'list'|'navigation'|'listbox'|'tree'|'form'} type - A11y role and behavior (default 'list'). See the docblock above.
152
+ * @attr {boolean} reorderable - Enables drag-to-reorder and pushes `reorderable` onto the items. Only valid with `type="list"`; there the arrow keys move rows instead of focus.
108
153
  * @attr {'always'|'on-touch'|'never'} dividers - When to draw the lines between the items (default 'always'). `on-touch` draws them only where the primary input is touch, under `(pointer: coarse)`: a pointer has the hover highlight to tell one row from the next and a finger has nothing, so the line earns its place in the one case and is clutter in the other. `never` hides them everywhere
109
- * @attr {boolean} arrow-navigation - Roving-tabindex arrow-key navigation: ArrowUp/ArrowDown move focus between the rows, Home/End jump to first/last, and the list becomes a single tab stop. Implied by `type="tree"` (which adds ArrowLeft/ArrowRight, see above). Ignored when `reorderable` is active on a `type="list"`, and in listbox mode.
110
154
  * @attr {string} height - Listbox only: caps the options' scroll region at this CSS length (e.g. '320px'). Unset means no cap.
111
- * @attr {string} empty-text - Text for the default empty-state dialog (falls back to the Dutch i18n default). Ignored when `[slot=empty]` is filled.
112
- * @attr {string} empty-supporting-text - Supporting text for the default empty-state dialog. Ignored when `[slot=empty]` is filled.
113
155
  * @attr {string} accessible-label - Accessible name, forwarded to the list in `type="list"` and to the search field in `type="listbox"`. For `type="navigation"` set `aria-label` / `aria-labelledby` on the element itself. Falls back to the i18n default.
114
156
  * @attr {object} translations - Override translation keys; unset keys fall back to Dutch
115
157
  *
116
158
  * @slot - List items (`nldd-list-item`)
117
159
  * @slot toolbar - Controls below the search field (filters, sort, counts, view toggles). Available for every type; collapses when empty.
118
160
  * @slot search-bar-end - Controls inline at the end of the search bar, beside the search field (e.g. a filter or options button). Listbox only; collapses when empty.
119
- * @slot empty - Shown when no items are visible (all `[hidden]` or none). Defaults to `nldd-inline-dialog` with `empty-text` / `empty-supporting-text` (falling back to Dutch i18n "Geen items"). Slot content overrides the default dialog entirely. In `type="listbox"` it is suppressed while the search field is empty (no query yet), so the consumer can show just the search field or its own hint outside the list.
161
+ * @slot empty - Shown when no items are visible (all `[hidden]` or none). Empty by default: what an empty list should say is the app's to write, so put an `nldd-inline-dialog` here. In `type="listbox"` it is suppressed while the search field is empty (no query yet), so the consumer can show just the search field or its own hint outside the list.
120
162
  *
121
163
  * @fires nldd-reorder - Reorderable `type="list"`: `{ fromIndex, toIndex }` on drop
122
164
  * @fires input - `type="listbox"`: search value changed; `{ value }`. Toggle `[hidden]` on items to filter.
@@ -136,27 +178,6 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
136
178
  * primary input is touch: a pointer has the hover highlight to tell one row
137
179
  * from the next, and a finger has nothing. */
138
180
  this.dividers = 'always';
139
- /**
140
- * Roving-tabindex arrow-key navigation. When set, ArrowUp/ArrowDown move focus
141
- * between the (interactive) items, Home/End jump to the first/last, and the
142
- * whole list becomes a single tab stop — so Tab moves past the rest instead of
143
- * stepping through every item. Arrows move focus only; selection stays
144
- * consumer-managed.
145
- *
146
- * Pragmatic by design: the `list`/`navigation` role is kept (no widget role).
147
- * Use it only on **simple** lists where each item has a single action and no
148
- * extra controls (a control in a `start`/`end` slot would not be reachable as
149
- * its own tab stop). Mutually exclusive with `reorderable` (both use the arrow
150
- * keys); when both are set, `reorderable` wins and this is ignored.
151
- *
152
- * Known a11y limitation: because the role stays `list`/`navigation` (not
153
- * `listbox`/`menu`), screen readers do not auto-announce that the arrow keys
154
- * navigate. As a best-effort signal the host carries
155
- * `aria-keyshortcuts="ArrowUp ArrowDown Home End"` while active, but blind users
156
- * may still not discover the feature — another reason to keep it to genuinely
157
- * simple lists.
158
- */
159
- this.arrowNavigation = false;
160
181
  /**
161
182
  * Only in `type="listbox"`: caps the options' scroll region at this CSS
162
183
  * length (any value `CSS.supports('max-height', …)` accepts, e.g. "320px").
@@ -165,17 +186,6 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
165
186
  * outside listbox mode.
166
187
  */
167
188
  this.height = '';
168
- /**
169
- * Text for the default empty-state dialog. Falls back to the Dutch
170
- * i18n default ("Geen items"). Ignored when consumers slot their
171
- * own content into `[slot=empty]`.
172
- */
173
- this.emptyText = '';
174
- /**
175
- * Optional supporting text for the default empty-state dialog.
176
- * Ignored when consumers slot their own content into `[slot=empty]`.
177
- */
178
- this.emptySupportingText = '';
179
189
  /** Accessible name for the list, forwarded to the inner role: the list in
180
190
  * `type=list`, the search field in `type=listbox`. For `type=navigation`,
181
191
  * set `aria-label` / `aria-labelledby` on the element directly (it is a
@@ -210,6 +220,7 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
210
220
  // — Observers ————————————————————————————————————————————————————————————
211
221
  this._itemsObserver = null;
212
222
  this._contextScheduled = false;
223
+ this._warnedSilentEmpty = false;
213
224
  /** Keep the active option valid after the visible set changes (initial
214
225
  * render, slot change, or consumer-driven `[hidden]` filtering): ensure ids,
215
226
  * reset the active option to the first visible one when the current active is
@@ -236,7 +247,8 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
236
247
  * bar gap) collapses when empty. Bound in the template so it follows the slot
237
248
  * even though the search bar only renders in listbox mode. */
238
249
  this._onSearchBarEndSlotChange = (event) => {
239
- this._hasSearchBarEnd = event.target.assignedElements().length > 0;
250
+ const slot = event.target;
251
+ queueMicrotask(() => { this._hasSearchBarEnd = slot.assignedElements().length > 0; });
240
252
  };
241
253
  this._onSearchFocus = () => {
242
254
  this._searchFocused = true;
@@ -310,6 +322,25 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
310
322
  this._setActiveOption(visible[next]);
311
323
  };
312
324
  this._rovingScheduled = false;
325
+ this._warnedActionRowInForm = false;
326
+ /**
327
+ * Whether the control the Escape came from had a popover open when the key
328
+ * went down. Read on the way in, because a control closes its own menu in its
329
+ * own handler and does not stop the key: by the time this list sees it on the
330
+ * way out, the menu is already gone and one press would do two levels at once.
331
+ */
332
+ this._popoverWasOpen = false;
333
+ this._onKeyDownCapture = (event) => {
334
+ if (event.key !== 'Escape' || !this._arrowNavActive)
335
+ return;
336
+ const origin = this._origin(event);
337
+ // Asked of the whole row rather than of the control the event came from:
338
+ // a popover can hang anywhere between the focused node and the row — under
339
+ // the control, beside it in the same cell — and missing one costs a level.
340
+ // The other way round costs a press, once, in a row that has an open menu
341
+ // and a second control you are typing in.
342
+ this._popoverWasOpen = !!origin?.control && !!origin.row.querySelector(':popover-open');
343
+ };
313
344
  this._onFocusIn = (event) => {
314
345
  if (!this._arrowNavActive)
315
346
  return;
@@ -318,8 +349,40 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
318
349
  // click, or programmatic focus), so arrows continue from there.
319
350
  if (item && !item._rovingActive && this._getInteractiveItems().includes(item)) {
320
351
  this._setRovingActive(item);
352
+ return;
321
353
  }
354
+ // Focus back on the row it was already on: hand its controls their stops
355
+ // again, since leaving the list parked them.
356
+ if (item?._rovingActive)
357
+ item._syncRovingTabStops();
322
358
  };
359
+ /**
360
+ * Focus gone from the list: park everything but the row.
361
+ *
362
+ * The stops a row hands out to its controls last as long as the row is the
363
+ * current one, so without this they are still there after you tab away, and
364
+ * Shift+Tab back in lands inside the control you left rather than on the row.
365
+ * A roving list is one stop from the outside; what is inside opens up once
366
+ * you are in. _onFocusIn puts them back.
367
+ *
368
+ * Deferred: focus moving between two controls of the same row fires focusout
369
+ * before focusin, and `relatedTarget` is retargeted at a shadow boundary, so
370
+ * the only reliable answer to "did focus leave" is the one you get after it
371
+ * has landed.
372
+ */
373
+ this._onFocusOut = () => {
374
+ if (!this._arrowNavActive)
375
+ return;
376
+ queueMicrotask(() => {
377
+ if (!this.isConnected || this._containsFocus())
378
+ return;
379
+ this._getAllRows().forEach((row) => { row._parkControls(); });
380
+ });
381
+ };
382
+ /** Reported once per element: a list that gains rows would otherwise repeat
383
+ * the same line on every change. */
384
+ this._warnedUnmanaged = new WeakSet();
385
+ this._unmanagedWarnScheduled = false;
323
386
  // — Drag: pointer ————————————————————————————————————————————————————————
324
387
  this._onPointerDown = (event) => {
325
388
  if (!this.reorderable || this.type !== 'list')
@@ -384,6 +447,10 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
384
447
  // Arrow-navigation and reorder both claim the arrow keys; _arrowNavActive
385
448
  // is false whenever reorderable wins, so the two never run together.
386
449
  if (this._arrowNavActive) {
450
+ if (event.key === 'Escape') {
451
+ this._onEscape(event);
452
+ return;
453
+ }
387
454
  this._onArrowNav(event);
388
455
  return;
389
456
  }
@@ -425,25 +492,46 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
425
492
  };
426
493
  }
427
494
  // — Lifecycle ————————————————————————————————————————————————————————————
495
+ /**
496
+ * What the first render needs to know, read before it happens.
497
+ *
498
+ * All three of these used to be set in `firstUpdated`, from the slots in the
499
+ * shadow root. Setting reactive state there asks for a second render the
500
+ * moment the first one finished, which Lit reports on every page as "an
501
+ * update scheduled after an update completed". The same three answers are in
502
+ * the light DOM, which is there before the first render, so they are read
503
+ * from the children instead. The slotchange listeners below keep them true
504
+ * afterwards, and by then a second render is what you actually want.
505
+ */
506
+ willUpdate(changed) {
507
+ // Derived state belongs before the render that reads it. In `updated` the
508
+ // merge lands after the first render has finished, and asks for a second
509
+ // one on the spot.
510
+ if (changed.has('translations') || !this.hasUpdated) {
511
+ this._mergedTranslations = { ...nlddListTranslations, ...this.translations };
512
+ }
513
+ if (this.hasUpdated)
514
+ return;
515
+ this._updateEmpty();
516
+ this._hasToolbar = this.querySelector(':scope > [slot="toolbar"]') !== null;
517
+ this._hasSearchBarEnd = this.querySelector(':scope > [slot="search-bar-end"]') !== null;
518
+ }
428
519
  firstUpdated() {
520
+ // Deferred: the browser fires the first slotchange the moment this render
521
+ // commits, and state set there is an update scheduled on top of the one
522
+ // that just finished. willUpdate already read these from the light DOM, so
523
+ // the first event has nothing to add anyway; the later ones do.
429
524
  const slot = this.shadowRoot?.querySelector('slot:not([name])');
430
- slot?.addEventListener('slotchange', () => {
525
+ slot?.addEventListener('slotchange', () => queueMicrotask(() => {
431
526
  this._updateItems();
432
527
  this._updateEmpty();
433
- });
528
+ }));
434
529
  this._updateItems();
435
- this._updateEmpty();
436
530
  this._warnArrowNav();
437
531
  const toolbarSlot = this.shadowRoot?.querySelector('slot[name="toolbar"]');
438
- const syncToolbar = () => { this._hasToolbar = (toolbarSlot?.assignedElements().length ?? 0) > 0; };
439
- toolbarSlot?.addEventListener('slotchange', syncToolbar);
440
- syncToolbar();
441
- // The search-bar-end slot only renders in listbox; sync its initial presence
442
- // here. The @slotchange binding in the template keeps it updated afterwards
443
- // and re-binds whenever the search bar (re)renders on a type change.
444
- const searchBarEndSlot = this.shadowRoot?.querySelector('slot[name="search-bar-end"]');
445
- if (searchBarEndSlot)
446
- this._hasSearchBarEnd = searchBarEndSlot.assignedElements().length > 0;
532
+ toolbarSlot?.addEventListener('slotchange', () => queueMicrotask(() => {
533
+ this._hasToolbar = toolbarSlot.assignedElements().length > 0;
534
+ }));
447
535
  // Watch for rows being added or removed, for `hidden` toggles on them
448
536
  // (consumer-driven filtering) and for branches opening and closing, since
449
537
  // all three change which row paints first and last. `subtree: true` is
@@ -460,7 +548,7 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
460
548
  return m.target === this || isRow(m.target);
461
549
  if (m.type !== 'attributes' || !isRow(m.target))
462
550
  return false;
463
- if (m.attributeName === 'expanded')
551
+ if (m.attributeName === 'expanded' || m.attributeName === 'disabled')
464
552
  return true;
465
553
  return m.attributeName === 'hidden'
466
554
  && (m.target.parentElement === this || isRow(m.target.parentElement));
@@ -469,12 +557,13 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
469
557
  return;
470
558
  this._updateItems();
471
559
  this._updateEmpty();
560
+ this._warnUnmanagedControls();
472
561
  });
473
562
  this._itemsObserver.observe(this, {
474
563
  childList: true,
475
564
  subtree: true,
476
565
  attributes: true,
477
- attributeFilter: ['hidden', 'expanded'],
566
+ attributeFilter: ['hidden', 'expanded', 'disabled'],
478
567
  });
479
568
  this._applyHostType();
480
569
  }
@@ -488,22 +577,26 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
488
577
  this.style.containerType = 'inline-size';
489
578
  this.style.containerName = 'cells-container';
490
579
  this.addEventListener('pointerdown', this._onPointerDown);
580
+ this.addEventListener('keydown', this._onKeyDownCapture, true);
491
581
  this.addEventListener('keydown', this._onKeyDown);
492
582
  this.addEventListener('focusin', this._onFocusIn);
583
+ this.addEventListener('focusout', this._onFocusOut);
493
584
  this.addEventListener('click', this._onListClick);
494
585
  }
495
586
  disconnectedCallback() {
496
587
  super.disconnectedCallback();
497
588
  this.removeEventListener('pointerdown', this._onPointerDown);
589
+ this.removeEventListener('keydown', this._onKeyDownCapture, true);
498
590
  this.removeEventListener('keydown', this._onKeyDown);
499
591
  this.removeEventListener('focusin', this._onFocusIn);
592
+ this.removeEventListener('focusout', this._onFocusOut);
500
593
  this.removeEventListener('click', this._onListClick);
501
594
  this._itemsObserver?.disconnect();
502
595
  this._itemsObserver = null;
503
596
  this._cancelDrag();
504
597
  }
505
598
  updated(changed) {
506
- if (changed.has('reorderable') || changed.has('type') || changed.has('arrowNavigation')) {
599
+ if (changed.has('reorderable') || changed.has('type')) {
507
600
  if (this.reorderable && this.type !== 'list' && import.meta.env?.DEV) {
508
601
  console.warn('nldd-list: `reorderable` is only valid when type="list". Ignoring.');
509
602
  }
@@ -513,9 +606,6 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
513
606
  if (changed.has('variant')) {
514
607
  this._updateItemContext();
515
608
  }
516
- if (changed.has('translations')) {
517
- this._mergedTranslations = { ...nlddListTranslations, ...this.translations };
518
- }
519
609
  if (changed.has('type')) {
520
610
  this._applyHostType();
521
611
  // Leaving listbox mode: drop the active highlight and reset state so a
@@ -638,6 +728,35 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
638
728
  _updateEmpty() {
639
729
  const items = this._getItems();
640
730
  this._isEmpty = items.length === 0 || items.every(item => item.hasAttribute('hidden'));
731
+ // Nothing in it and nothing said about that is not a thing on the page.
732
+ // Drawing the surface anyway makes "nothing" look different per variant:
733
+ // invisible on a plain list, an empty tinted bar on a boxed one, which
734
+ // reads as a skeleton that never loaded.
735
+ this.classList.toggle('is-blank', this._isEmpty && !this.querySelector(':scope > [slot="empty"]'));
736
+ this._warnSilentEmpty();
737
+ }
738
+ /**
739
+ * A list with nothing in it and nothing to say about that.
740
+ *
741
+ * There is no default text any more, because what an empty list means is
742
+ * the app's to write and a house sentence was wrong more often than right.
743
+ * That leaves a real risk of a blank area with nothing in the accessibility
744
+ * tree either, so the list asks the person building it rather than
745
+ * answering for them. A listbox before you have typed is left alone: an
746
+ * empty search is not an empty list.
747
+ */
748
+ _warnSilentEmpty() {
749
+ if (!import.meta.env?.DEV)
750
+ return;
751
+ if (!this._isEmpty || this._warnedSilentEmpty)
752
+ return;
753
+ if (this.type === 'listbox' && !this._searchValue)
754
+ return;
755
+ if (this.querySelector(':scope > [slot="empty"]'))
756
+ return;
757
+ this._warnedSilentEmpty = true;
758
+ console.warn('nldd-list: no items and nothing in [slot="empty"], so the list renders a blank area. '
759
+ + 'Put an nldd-inline-dialog in that slot saying what is not there and what the next move is.', this);
641
760
  }
642
761
  // — Listbox: active-option model ————————————————————————————————————————————
643
762
  /** Every option needs a stable id for aria-activedescendant. Assign one to
@@ -711,41 +830,49 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
711
830
  this._searchInput?.focus();
712
831
  }
713
832
  // — Arrow navigation (roving tabindex) ————————————————————————————————————
714
- /** Arrow-navigation is effective only when reorderable isn't already claiming
715
- * the arrow keys for drag-reorder (reorderable wins). The guard also checks
716
- * `type === 'list'` on purpose: reorderable is inert without it, so there is no
717
- * conflict to resolve. `arrow-navigation reorderable` without `type="list"`
718
- * therefore keeps arrow-nav active (reorderable does nothing), and
719
- * `_warnArrowNav` likewise only warns for the real reorderable-list conflict. */
833
+ /**
834
+ * Every list answers to the arrow keys. There is no switch for it, on purpose:
835
+ * whether the keys do something is not a property of one list, it is what a
836
+ * reader may assume about all of them, and a per-list setting made that
837
+ * unknowable from the outside.
838
+ *
839
+ * Two lists answer differently, and you can see which before you touch a key:
840
+ * a listbox has a search field and runs its own keyboard from there, and a
841
+ * reorderable list uses the arrows to move rows. The guard checks
842
+ * `type === 'list'` because reorderable is inert without it, so there is no
843
+ * conflict to resolve.
844
+ */
720
845
  get _arrowNavActive() {
721
- // Listbox has its own keyboard (on the search input) and supersedes the
722
- // roving-tabindex arrow-nav — never run both.
723
846
  if (this.type === 'listbox')
724
847
  return false;
725
- // A tree is a composite widget: role="tree" promises arrow keys, so it
726
- // gets them without the consumer asking. Everywhere else arrow-nav stays
727
- // opt-in, because a plain list is not a widget and Tab per row is fine.
728
- if (this.type === 'tree')
729
- return true;
730
- return this.arrowNavigation && !(this.reorderable && this.type === 'list');
848
+ // A form's rows are not somewhere to go: the controls in them are, and Tab
849
+ // already reaches those. Arrow keys would be a promise with nothing behind
850
+ // it, and the tab stop they need on the row would sit in front of every
851
+ // field.
852
+ if (this.type === 'form')
853
+ return false;
854
+ return !(this.reorderable && this.type === 'list');
731
855
  }
732
856
  /** Interactive, painted rows — the roving stops, in the order they appear on
733
- * screen. Non-interactive rows (no link/button) and hidden ones are skipped.
857
+ * screen. Rows with nothing to operate and hidden ones are skipped.
734
858
  * Painted, not top-level: in a tree the rows of an open branch sit between
735
859
  * the branch and the next top-level row, and arrows have to walk them too. */
736
860
  _getInteractiveItems() {
737
861
  const painted = this._getPaintedRows();
738
- // In a tree every row is a stop, including one that only holds segmented
739
- // actions: the row itself takes focus (that is where role="treeitem"
740
- // sits) and Tab reaches the controls inside it.
862
+ // In a tree every row is a stop, including one that holds nothing at all:
863
+ // the row itself takes focus (that is where role="treeitem" sits), and a
864
+ // branch you cannot reach is a branch you cannot open.
741
865
  if (this.type === 'tree')
742
866
  return painted;
743
- return painted.filter((row) => Boolean(row.href || row.button));
867
+ return painted.filter((row) => row._isRovingStop);
744
868
  }
745
869
  /** Push roving state onto the items, deferred to a microtask: _updateItems can
746
870
  * run inside the update lifecycle (firstUpdated/updated), and setting the
747
871
  * items' reactive state there would trip Lit's change-in-update warning.
748
- * Coalesced so repeated item updates schedule it only once. */
872
+ * Coalesced so repeated item updates schedule it only once.
873
+ *
874
+ * @internal Also called by a row whose content changed after the stops were
875
+ * picked. */
749
876
  _updateRoving() {
750
877
  if (this._rovingScheduled)
751
878
  return;
@@ -762,11 +889,22 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
762
889
  const active = this._arrowNavActive;
763
890
  const rows = this._getAllRows();
764
891
  rows.forEach((row) => { row._arrowNavigation = active; });
892
+ const interactive = active ? this._getInteractiveItems() : [];
765
893
  // Best-effort AT discoverability: role="list"/"navigation" doesn't imply
766
894
  // arrow-key navigation the way listbox/menu would, so advertise the keys via
767
895
  // aria-keyshortcuts (queryable) and a plain-language aria-description (surfaced
768
- // when AT reaches the list). See the arrowNavigation JSDoc — known limitation.
769
- if (active) {
896
+ // when AT reaches the list). See _arrowNavActive — known limitation.
897
+ // Only where the keys go somewhere: a list of nothing but text has no stops
898
+ // to move between, and promising keys that do nothing is worse than silence.
899
+ if (import.meta.env?.DEV && this.type === 'form' && !this._warnedActionRowInForm) {
900
+ const action = rows.find((row) => row.href || row.button || row.checkbox
901
+ || row.querySelector(':scope > nldd-list-item-segment'));
902
+ if (action) {
903
+ this._warnedActionRowInForm = true;
904
+ console.warn('nldd-list: type="form" says the rows are not actions and the controls inside them are, so its rows carry no keyboard of their own. This one is a link, a button, a checkbox or a set of segments, which contradicts that. Use type="list" for rows you activate, and put the action in a cell if it belongs to a form row.');
905
+ }
906
+ }
907
+ if (interactive.length > 0) {
770
908
  this.setAttribute('aria-keyshortcuts', 'ArrowUp ArrowDown Home End');
771
909
  this.setAttribute('aria-description', this._t('components.list.arrow-navigation-description-text'));
772
910
  }
@@ -778,7 +916,6 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
778
916
  rows.forEach((row) => { row._rovingActive = false; });
779
917
  return;
780
918
  }
781
- const interactive = this._getInteractiveItems();
782
919
  if (interactive.length === 0)
783
920
  return;
784
921
  const entry = interactive.find((row) => row._rovingActive)
@@ -789,9 +926,8 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
789
926
  row._syncRovingTabStops();
790
927
  });
791
928
  }
792
- // items defaults to every row, nested ones included; _onArrowNav passes the
793
- // interactive set it already computed (non-interactive rows are kept out of
794
- // roving, so they stay false).
929
+ // items defaults to every row, nested ones included. Callers that pass a
930
+ // narrower set take on clearing whatever is outside it themselves.
795
931
  _setRovingActive(activeItem, items = this._getAllRows()) {
796
932
  items.forEach((item) => {
797
933
  item._rovingActive = item === activeItem;
@@ -800,8 +936,36 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
800
936
  item._syncRovingTabStops();
801
937
  });
802
938
  }
939
+ /** Whether focus is anywhere in this list, shadow boundaries included. */
940
+ _containsFocus() {
941
+ // document.activeElement only ever names the outermost host, so the answer
942
+ // is a walk down the chain of active elements: at every level, is this the
943
+ // list or inside it.
944
+ let node = document.activeElement;
945
+ while (node) {
946
+ if (node === this || this.contains(node))
947
+ return true;
948
+ node = node.shadowRoot?.activeElement ?? null;
949
+ }
950
+ return false;
951
+ }
952
+ /** The row an event came from, and the control of that row it started in. */
953
+ _origin(event) {
954
+ const path = event.composedPath();
955
+ const row = path.find((el) => el instanceof Element && el.tagName.toLowerCase() === 'nldd-list-item');
956
+ if (!row)
957
+ return null;
958
+ return { row, control: row._slottedControlFor(path) };
959
+ }
803
960
  _onArrowNav(event) {
804
961
  const { key } = event;
962
+ // Hands off while focus is in a control the row holds. What those keys do
963
+ // is the control's business — a combo box moves its options with them, a
964
+ // text field its caret — and a list that takes them anyway pulls focus out
965
+ // of the control mid-word. The row itself, its own action and its segments
966
+ // are not controls it holds, so those keep answering here.
967
+ if (this._origin(event)?.control)
968
+ return;
805
969
  if (this.type === 'tree' && (key === 'ArrowRight' || key === 'ArrowLeft')) {
806
970
  this._onTreeHorizontal(event, key);
807
971
  return;
@@ -830,9 +994,38 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
830
994
  }
831
995
  event.preventDefault();
832
996
  const target = items[next];
833
- this._setRovingActive(target, items);
997
+ // Every row, not just the interactive ones: Escape can leave the flag on a
998
+ // row that holds a control but is no stop itself, and clearing only the
999
+ // stops would leave two rows claiming to be the current one.
1000
+ this._setRovingActive(target);
834
1001
  target.focus();
835
1002
  }
1003
+ /**
1004
+ * Escape: out of a control, back onto the row that holds it.
1005
+ *
1006
+ * One level up, not one step back. Shift+Tab retraces the order and lands on
1007
+ * whatever came before, which is the row only from the first control of a
1008
+ * row; from the second it is the first. This is the move that works wherever
1009
+ * you are in the row, and it puts the arrow keys back in reach.
1010
+ *
1011
+ * It claims Escape at exactly this one level. On the row it claims nothing,
1012
+ * so Escape carries on to whatever holds the list — a sheet, a dialog, or
1013
+ * nothing at all. And a control showing a popover keeps it: that menu is the
1014
+ * topmost thing you opened, so it is what the first Escape closes.
1015
+ */
1016
+ _onEscape(event) {
1017
+ const hadPopover = this._popoverWasOpen;
1018
+ this._popoverWasOpen = false;
1019
+ const origin = this._origin(event);
1020
+ if (!origin?.control)
1021
+ return;
1022
+ if (hadPopover)
1023
+ return;
1024
+ event.preventDefault();
1025
+ event.stopPropagation();
1026
+ this._setRovingActive(origin.row);
1027
+ origin.row.focus();
1028
+ }
836
1029
  /** Tree only: Right opens a closed branch and steps into an open one, Left
837
1030
  * closes an open branch and steps out of a leaf. Opening and closing runs
838
1031
  * through the row's own disclosure control, so `expanded` keeps being
@@ -866,10 +1059,17 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
866
1059
  event.preventDefault();
867
1060
  this._moveRovingTo(parent);
868
1061
  }
869
- /** Tree only: Enter and Space open and close the row, the same thing Right and
870
- * Left do. Only when focus sits on the row ITSELF a row that is its own
871
- * control, and a segmented action you tabbed into, handle both keys
872
- * natively, and acting here as well would toggle twice. */
1062
+ /**
1063
+ * Tree only, and only while focus sits on the row ITSELF: a row that is its
1064
+ * own control, and a segment you tabbed into, handle both keys
1065
+ * natively, and acting here as well would fire twice.
1066
+ *
1067
+ * Enter does what the row is for — it follows the row's own link or button,
1068
+ * or on a branch cut into segments the first one that is not the chevron.
1069
+ * Space folds, the same thing Right and Left do, because a chevron is a
1070
+ * button and Space is what a button answers to. A branch with nothing but a
1071
+ * chevron takes Enter for folding too, so the key is never dead.
1072
+ */
873
1073
  _onTreeActivate(event) {
874
1074
  const target = event.target;
875
1075
  if (!(target instanceof Element) || target.tagName.toLowerCase() !== 'nldd-list-item')
@@ -877,6 +1077,10 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
877
1077
  const row = target;
878
1078
  if (row.shadowRoot?.activeElement)
879
1079
  return;
1080
+ if (event.key === 'Enter' && row._activatePrimary()) {
1081
+ event.preventDefault();
1082
+ return;
1083
+ }
880
1084
  if (row._activateDisclosure())
881
1085
  event.preventDefault();
882
1086
  }
@@ -887,23 +1091,69 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
887
1091
  _warnArrowNav() {
888
1092
  if (!import.meta.env?.DEV)
889
1093
  return;
890
- if (this.arrowNavigation && this.reorderable && this.type === 'list') {
891
- console.warn('nldd-list: `arrow-navigation` and `reorderable` both use the arrow keys; `reorderable` wins and arrow-navigation is ignored.');
1094
+ if (this.hasAttribute('arrow-navigation')) {
1095
+ console.warn('nldd-list: `arrow-navigation` is the default now and the attribute does nothing; remove it.');
892
1096
  }
893
- // A tree row is meant to hold more than one control (a chevron beside a
894
- // checkbox); there Tab walks the current row, so the warning below would
895
- // be noise.
896
- if (this._arrowNavActive && this.type !== 'tree') {
897
- // Best-effort, light-DOM only: a slotted custom element (e.g. nldd-switch)
898
- // keeps its focusable control in its own shadow root, so this query won't
899
- // catch every extra control. Detecting custom elements generically would
900
- // false-positive on non-interactive ones (nldd-icon, nldd-badge), so this
901
- // stays a heuristic dev aid for the documented "simple lists" case.
902
- const hasExtraControls = this._getInteractiveItems().some((item) => item.querySelector('a[href], button, input, select, textarea, [tabindex]') !== null);
903
- if (hasExtraControls) {
904
- console.warn('nldd-list: `arrow-navigation` is for simple lists, but a list-item has an extra focusable control (slotted) that will not be reachable as its own tab stop. Remove the control or disable arrow-navigation.');
1097
+ this._warnUnmanagedControls();
1098
+ }
1099
+ /**
1100
+ * A control the row cannot reach: a custom element that keeps its tab stop in
1101
+ * its own shadow root and has no `no-tab` to close it. Such a control stays a
1102
+ * tab stop in EVERY row, which is exactly what the roving promises it is not,
1103
+ * and the row does not even count as a stop for the arrow keys.
1104
+ *
1105
+ * Deferred, and re-run whenever the rows change. A slotted custom element has
1106
+ * its shadow root the moment it connects, but Lit renders the content on the
1107
+ * first update, so a check that runs in `firstUpdated` looks into an empty
1108
+ * shadow root and finds nothing to warn about. Waiting for the element to be
1109
+ * defined is not enough either: it has to have rendered.
1110
+ */
1111
+ _warnUnmanagedControls() {
1112
+ if (!import.meta.env?.DEV || !this._arrowNavActive)
1113
+ return;
1114
+ if (this._unmanagedWarnScheduled)
1115
+ return;
1116
+ this._unmanagedWarnScheduled = true;
1117
+ const check = async () => {
1118
+ this._unmanagedWarnScheduled = false;
1119
+ const rows = this._getPaintedRows();
1120
+ await Promise.all(rows.map((row) => row.updateComplete));
1121
+ for (const row of rows) {
1122
+ for (const el of Array.from(row.querySelectorAll('*'))) {
1123
+ if (el.closest('nldd-list-item') !== row)
1124
+ continue;
1125
+ // A segment is managed over its own channel (`_tabbable`), so it
1126
+ // needs no `no-tab`.
1127
+ if (el.tagName.toLowerCase() === 'nldd-list-item-segment')
1128
+ continue;
1129
+ if (!el.tagName.includes('-') || 'noTab' in el)
1130
+ continue;
1131
+ if (this._warnedUnmanaged.has(el))
1132
+ continue;
1133
+ const upgraded = el;
1134
+ if (upgraded.updateComplete)
1135
+ await upgraded.updateComplete;
1136
+ if (!el.shadowRoot?.querySelector(SHADOW_TAB_STOP))
1137
+ continue;
1138
+ // Nothing hidden on the way from the row: a menu item in a closed
1139
+ // menu is no tab stop of the row's, and the component that hides it
1140
+ // runs its own focus. Computed style, not checkVisibility(): that one
1141
+ // needs a laid-out box and answers false until the first layout.
1142
+ if (this._hiddenWithin(row, el))
1143
+ continue;
1144
+ this._warnedUnmanaged.add(el);
1145
+ console.warn(`nldd-list: <${el.tagName.toLowerCase()}> in a list-item keeps its tab stop in its own shadow root and has no \`no-tab\`, so the row cannot take it out of the tab order and the arrow keys skip that row. If the rows of this list are not actions themselves, it is a form: set type="form" and the roving falls away. Otherwise give the component \`no-tab\`, or wrap the control in an nldd-list-item-segment.`);
1146
+ }
905
1147
  }
1148
+ };
1149
+ void check();
1150
+ }
1151
+ _hiddenWithin(row, el) {
1152
+ for (let node = el; node && node !== row; node = node.parentElement) {
1153
+ if (getComputedStyle(node).display === 'none')
1154
+ return true;
906
1155
  }
1156
+ return false;
907
1157
  }
908
1158
  _getDeepActiveElement() {
909
1159
  let active = document.activeElement;
@@ -1063,8 +1313,6 @@ let NLDDList = NLDDList_1 = class NLDDList extends LitElement {
1063
1313
  hasToolbar: this._hasToolbar,
1064
1314
  type: this.type,
1065
1315
  isEmpty: this._isEmpty,
1066
- emptyText: this.emptyText || this._t('components.list.empty-text'),
1067
- emptySupportingText: this.emptySupportingText,
1068
1316
  listbox: {
1069
1317
  listboxId: this._listboxId,
1070
1318
  searchValue: this._searchValue,
@@ -1101,18 +1349,9 @@ __decorate([
1101
1349
  __decorate([
1102
1350
  property({ reflect: true, converter: reflectNonDefault('always') })
1103
1351
  ], NLDDList.prototype, "dividers", void 0);
1104
- __decorate([
1105
- property({ type: Boolean, reflect: true, attribute: 'arrow-navigation' })
1106
- ], NLDDList.prototype, "arrowNavigation", void 0);
1107
1352
  __decorate([
1108
1353
  property({ type: String, reflect: true })
1109
1354
  ], NLDDList.prototype, "height", void 0);
1110
- __decorate([
1111
- property({ reflect: true, attribute: 'empty-text', converter: reflectNonDefault('') })
1112
- ], NLDDList.prototype, "emptyText", void 0);
1113
- __decorate([
1114
- property({ reflect: true, attribute: 'empty-supporting-text', converter: reflectNonDefault('') })
1115
- ], NLDDList.prototype, "emptySupportingText", void 0);
1116
1355
  __decorate([
1117
1356
  property({ type: String, attribute: 'accessible-label' })
1118
1357
  ], NLDDList.prototype, "accessibleLabel", void 0);