@nova-design-system/nova-webcomponents 3.30.0 → 3.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/dist/cjs/index.cjs.js +9 -0
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/native.cjs.js +1 -1
  4. package/dist/cjs/nv-fielddropdown.cjs.entry.js +100 -22
  5. package/dist/cjs/nv-fielddropdownitem.cjs.entry.js +1 -1
  6. package/dist/cjs/nv-fieldselect.cjs.entry.js +44 -6
  7. package/dist/cjs/nv-fieldslider.cjs.entry.js +3 -3
  8. package/dist/cjs/nv-fieldtext.cjs.entry.js +4 -4
  9. package/dist/cjs/nv-fieldtextarea.cjs.entry.js +3 -3
  10. package/dist/cjs/nv-fieldtime.cjs.entry.js +3 -3
  11. package/dist/cjs/nv-icon.cjs.entry.js +2 -2
  12. package/dist/cjs/nv-iconbutton_2.cjs.entry.js +2 -2
  13. package/dist/cjs/nv-menu.cjs.entry.js +1 -1
  14. package/dist/cjs/nv-menuitem.cjs.entry.js +1 -1
  15. package/dist/cjs/nv-notification.cjs.entry.js +1 -1
  16. package/dist/cjs/nv-notificationcontainer.cjs.entry.js +1 -1
  17. package/dist/cjs/nv-pagination-nav.cjs.entry.js +1 -1
  18. package/dist/cjs/nv-paginationtable.cjs.entry.js +1 -1
  19. package/dist/cjs/nv-popover.cjs.entry.js +1 -1
  20. package/dist/cjs/nv-row.cjs.entry.js +1 -1
  21. package/dist/cjs/nv-sidebar.cjs.entry.js +2 -2
  22. package/dist/cjs/nv-sidebarcontent.cjs.entry.js +1 -1
  23. package/dist/cjs/nv-sidebardivider.cjs.entry.js +1 -1
  24. package/dist/cjs/nv-sidebarfooter.cjs.entry.js +1 -1
  25. package/dist/cjs/nv-sidebargroup.cjs.entry.js +1 -1
  26. package/dist/cjs/nv-sidebarheader.cjs.entry.js +1 -1
  27. package/dist/cjs/nv-sidebarlogo.cjs.entry.js +1 -1
  28. package/dist/cjs/nv-sidebarnavitem.cjs.entry.js +2 -2
  29. package/dist/cjs/nv-sidebarnavsubitem.cjs.entry.js +1 -1
  30. package/dist/cjs/nv-split.cjs.entry.js +1 -1
  31. package/dist/cjs/nv-stack.cjs.entry.js +1 -1
  32. package/dist/cjs/nv-statusindicator.cjs.entry.js +1 -1
  33. package/dist/cjs/nv-table.cjs.entry.js +1 -1
  34. package/dist/cjs/nv-tableheader.cjs.entry.js +1 -1
  35. package/dist/cjs/nv-timetest.cjs.entry.js +1 -1
  36. package/dist/cjs/nv-toggle.cjs.entry.js +2 -2
  37. package/dist/cjs/nv-togglebutton.cjs.entry.js +1 -1
  38. package/dist/cjs/nv-togglebuttongroup.cjs.entry.js +1 -1
  39. package/dist/cjs/nv-tooltip.cjs.entry.js +1 -1
  40. package/dist/collection/components/nv-alert/nv-alert.js +1 -1
  41. package/dist/collection/components/nv-badge/nv-badge.js +2 -2
  42. package/dist/collection/components/nv-dialogfooter/nv-dialogfooter.js +2 -2
  43. package/dist/collection/components/nv-drawerfooter/nv-drawerfooter.js +2 -2
  44. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.docs.js +11 -0
  45. package/dist/collection/components/nv-fielddropdown/nv-fielddropdown.js +151 -22
  46. package/dist/collection/components/nv-fielddropdownitem/nv-fielddropdownitem.docs.js +7 -7
  47. package/dist/collection/components/nv-fielddropdownitem/nv-fielddropdownitem.js +1 -1
  48. package/dist/collection/components/nv-fieldselect/nv-fieldselect.docs.js +11 -0
  49. package/dist/collection/components/nv-fieldselect/nv-fieldselect.js +98 -5
  50. package/dist/collection/components/nv-fieldselect/styles/nv-fieldselect.css +3 -0
  51. package/dist/collection/components/nv-fieldslider/nv-fieldslider.js +3 -3
  52. package/dist/collection/components/nv-fieldtext/nv-fieldtext.js +4 -4
  53. package/dist/collection/components/nv-fieldtextarea/nv-fieldtextarea.js +3 -3
  54. package/dist/collection/components/nv-fieldtime/nv-fieldtime.js +3 -3
  55. package/dist/collection/components/nv-icon/nv-icon.js +2 -2
  56. package/dist/collection/components/nv-icon/nv-icons.js +9 -0
  57. package/dist/collection/components/nv-iconbutton/nv-iconbutton.js +2 -2
  58. package/dist/collection/components/nv-loader/nv-loader.js +1 -1
  59. package/dist/collection/components/nv-menu/nv-menu.js +1 -1
  60. package/dist/collection/components/nv-menuitem/nv-menuitem.js +2 -2
  61. package/dist/collection/components/nv-notification/nv-notification.js +2 -2
  62. package/dist/collection/components/nv-notificationcontainer/nv-notificationcontainer.js +1 -1
  63. package/dist/collection/components/nv-pagination-nav/nv-pagination-nav.js +1 -1
  64. package/dist/collection/components/nv-paginationtable/nv-paginationtable.js +1 -1
  65. package/dist/collection/components/nv-popover/nv-popover.js +1 -1
  66. package/dist/collection/components/nv-row/nv-row.js +1 -1
  67. package/dist/collection/components/nv-sidebar/nv-sidebar.js +2 -2
  68. package/dist/collection/components/nv-sidebarcontent/nv-sidebarcontent.js +1 -1
  69. package/dist/collection/components/nv-sidebardivider/nv-sidebardivider.js +1 -1
  70. package/dist/collection/components/nv-sidebarfooter/nv-sidebarfooter.js +1 -1
  71. package/dist/collection/components/nv-sidebargroup/nv-sidebargroup.js +1 -1
  72. package/dist/collection/components/nv-sidebarheader/nv-sidebarheader.js +1 -1
  73. package/dist/collection/components/nv-sidebarlogo/nv-sidebarlogo.js +1 -1
  74. package/dist/collection/components/nv-sidebarnavitem/nv-sidebarnavitem.js +3 -3
  75. package/dist/collection/components/nv-sidebarnavsubitem/nv-sidebarnavsubitem.js +1 -1
  76. package/dist/collection/components/nv-split/nv-split.js +1 -1
  77. package/dist/collection/components/nv-stack/nv-stack.js +1 -1
  78. package/dist/collection/components/nv-statusindicator/nv-statusindicator.js +1 -1
  79. package/dist/collection/components/nv-table/nv-table.js +1 -1
  80. package/dist/collection/components/nv-tableheader/nv-tableheader.js +1 -1
  81. package/dist/collection/components/nv-timetest/nv-timetest.js +1 -1
  82. package/dist/collection/components/nv-toggle/nv-toggle.js +2 -2
  83. package/dist/collection/components/nv-togglebutton/nv-togglebutton.js +1 -1
  84. package/dist/collection/components/nv-togglebuttongroup/nv-togglebuttongroup.js +1 -1
  85. package/dist/collection/components/nv-tooltip/nv-tooltip.js +1 -1
  86. package/dist/components/index.js +1 -1
  87. package/dist/components/nv-accordion-item.js +1 -1
  88. package/dist/components/nv-accordion.js +1 -1
  89. package/dist/components/nv-alert.js +1 -1
  90. package/dist/components/nv-avatar.js +1 -1
  91. package/dist/components/nv-badge.js +1 -1
  92. package/dist/components/nv-breadcrumb.js +1 -1
  93. package/dist/components/nv-button.js +1 -1
  94. package/dist/components/nv-datagrid.js +1 -1
  95. package/dist/components/nv-dialog.js +1 -1
  96. package/dist/components/nv-dialogfooter.js +1 -1
  97. package/dist/components/nv-drawer.js +1 -1
  98. package/dist/components/nv-drawerfooter.js +1 -1
  99. package/dist/components/nv-fielddate.js +1 -1
  100. package/dist/components/nv-fielddaterange.js +1 -1
  101. package/dist/components/nv-fielddropdown.js +1 -1
  102. package/dist/components/nv-fielddropdownitem.js +1 -1
  103. package/dist/components/nv-fieldmultiselect.js +1 -1
  104. package/dist/components/nv-fieldnumber.js +1 -1
  105. package/dist/components/nv-fieldpassword.js +1 -1
  106. package/dist/components/nv-fieldselect.js +1 -1
  107. package/dist/components/nv-fieldslider.js +1 -1
  108. package/dist/components/nv-fieldtext.js +1 -1
  109. package/dist/components/nv-fieldtextarea.js +1 -1
  110. package/dist/components/nv-fieldtime.js +1 -1
  111. package/dist/components/nv-icon.js +1 -1
  112. package/dist/components/nv-iconbutton.js +1 -1
  113. package/dist/components/nv-loader.js +1 -1
  114. package/dist/components/nv-menu.js +1 -1
  115. package/dist/components/nv-menuitem.js +1 -1
  116. package/dist/components/nv-notification.js +1 -1
  117. package/dist/components/nv-notificationcontainer.js +1 -1
  118. package/dist/components/nv-pagination-nav.js +1 -1
  119. package/dist/components/nv-paginationtable.js +1 -1
  120. package/dist/components/nv-popover.js +1 -1
  121. package/dist/components/nv-row.js +1 -1
  122. package/dist/components/nv-sidebar.js +1 -1
  123. package/dist/components/nv-sidebarcontent.js +1 -1
  124. package/dist/components/nv-sidebardivider.js +1 -1
  125. package/dist/components/nv-sidebarfooter.js +1 -1
  126. package/dist/components/nv-sidebargroup.js +1 -1
  127. package/dist/components/nv-sidebarheader.js +1 -1
  128. package/dist/components/nv-sidebarlogo.js +1 -1
  129. package/dist/components/nv-sidebarnavitem.js +1 -1
  130. package/dist/components/nv-sidebarnavsubitem.js +1 -1
  131. package/dist/components/nv-split.js +1 -1
  132. package/dist/components/nv-stack.js +1 -1
  133. package/dist/components/nv-statusindicator.js +1 -1
  134. package/dist/components/nv-table.js +1 -1
  135. package/dist/components/nv-tableheader.js +1 -1
  136. package/dist/components/nv-tag.js +1 -1
  137. package/dist/components/nv-timetest.js +1 -1
  138. package/dist/components/nv-toggle.js +1 -1
  139. package/dist/components/nv-togglebutton.js +1 -1
  140. package/dist/components/nv-togglebuttongroup.js +1 -1
  141. package/dist/components/nv-tooltip.js +1 -1
  142. package/dist/components/{p-D54x8OFu.js → p-1Zs1aHJ4.js} +1 -1
  143. package/dist/components/{p-Dg-Ac5i4.js → p-B4Uw_U8V.js} +1 -1
  144. package/dist/components/{p-yPMU6HZQ.js → p-BFM_8Jgq.js} +1 -1
  145. package/dist/components/{p-BYrgllP3.js → p-B_SethFg.js} +1 -1
  146. package/dist/components/{p-Cx5CLy9v.js → p-Bt5_pj49.js} +1 -1
  147. package/dist/components/{p-MLanePUO.js → p-C-Rs6wG9.js} +1 -1
  148. package/dist/components/p-C_eOV3Z7.js +1 -0
  149. package/dist/components/{p-Bu90dktV.js → p-Co54UCK_.js} +1 -1
  150. package/dist/components/{p-BhRpSdkR.js → p-CsPx96EZ.js} +1 -1
  151. package/dist/components/{p-DP_K3tkj.js → p-DCYvyQ_j.js} +1 -1
  152. package/dist/components/{p-L7U51TAH.js → p-DWvQs_c-.js} +1 -1
  153. package/dist/components/{p-B8yJMa0S.js → p-Ghb9L_N-.js} +1 -1
  154. package/dist/components/{p-CzRlra4z.js → p-Oger3lC0.js} +1 -1
  155. package/dist/components/{p-DQuJvZ4Z.js → p-VppCgviO.js} +1 -1
  156. package/dist/components/{p-Cj6urNtm.js → p-YhjPEgIT.js} +1 -1
  157. package/dist/esm/index.js +9 -0
  158. package/dist/esm/loader.js +1 -1
  159. package/dist/esm/native.js +1 -1
  160. package/dist/esm/nv-fielddropdown.entry.js +100 -22
  161. package/dist/esm/nv-fielddropdownitem.entry.js +1 -1
  162. package/dist/esm/nv-fieldselect.entry.js +44 -6
  163. package/dist/esm/nv-fieldslider.entry.js +3 -3
  164. package/dist/esm/nv-fieldtext.entry.js +4 -4
  165. package/dist/esm/nv-fieldtextarea.entry.js +3 -3
  166. package/dist/esm/nv-fieldtime.entry.js +3 -3
  167. package/dist/esm/nv-icon.entry.js +2 -2
  168. package/dist/esm/nv-iconbutton_2.entry.js +2 -2
  169. package/dist/esm/nv-menu.entry.js +1 -1
  170. package/dist/esm/nv-menuitem.entry.js +1 -1
  171. package/dist/esm/nv-notification.entry.js +1 -1
  172. package/dist/esm/nv-notificationcontainer.entry.js +1 -1
  173. package/dist/esm/nv-pagination-nav.entry.js +1 -1
  174. package/dist/esm/nv-paginationtable.entry.js +1 -1
  175. package/dist/esm/nv-popover.entry.js +1 -1
  176. package/dist/esm/nv-row.entry.js +1 -1
  177. package/dist/esm/nv-sidebar.entry.js +2 -2
  178. package/dist/esm/nv-sidebarcontent.entry.js +1 -1
  179. package/dist/esm/nv-sidebardivider.entry.js +1 -1
  180. package/dist/esm/nv-sidebarfooter.entry.js +1 -1
  181. package/dist/esm/nv-sidebargroup.entry.js +1 -1
  182. package/dist/esm/nv-sidebarheader.entry.js +1 -1
  183. package/dist/esm/nv-sidebarlogo.entry.js +1 -1
  184. package/dist/esm/nv-sidebarnavitem.entry.js +2 -2
  185. package/dist/esm/nv-sidebarnavsubitem.entry.js +1 -1
  186. package/dist/esm/nv-split.entry.js +1 -1
  187. package/dist/esm/nv-stack.entry.js +1 -1
  188. package/dist/esm/nv-statusindicator.entry.js +1 -1
  189. package/dist/esm/nv-table.entry.js +1 -1
  190. package/dist/esm/nv-tableheader.entry.js +1 -1
  191. package/dist/esm/nv-timetest.entry.js +1 -1
  192. package/dist/esm/nv-toggle.entry.js +2 -2
  193. package/dist/esm/nv-togglebutton.entry.js +1 -1
  194. package/dist/esm/nv-togglebuttongroup.entry.js +1 -1
  195. package/dist/esm/nv-tooltip.entry.js +1 -1
  196. package/dist/native/index.esm.js +1 -1
  197. package/dist/native/native.esm.js +1 -1
  198. package/dist/native/{p-189647e4.entry.js → p-007fef99.entry.js} +1 -1
  199. package/dist/native/{p-6ccc84c8.entry.js → p-00f4c8d3.entry.js} +1 -1
  200. package/dist/native/{p-04011d0f.entry.js → p-06eb42e0.entry.js} +1 -1
  201. package/dist/native/{p-93d2bfab.entry.js → p-13c507cd.entry.js} +1 -1
  202. package/dist/native/{p-b2ef61bc.entry.js → p-144ab827.entry.js} +1 -1
  203. package/dist/native/{p-ec919a10.entry.js → p-29b23e1d.entry.js} +1 -1
  204. package/dist/native/{p-c1faed1f.entry.js → p-2b20125e.entry.js} +1 -1
  205. package/dist/native/p-31e192d9.entry.js +1 -0
  206. package/dist/native/{p-dfd364de.entry.js → p-3855de15.entry.js} +1 -1
  207. package/dist/native/{p-37c42bed.entry.js → p-39d5af96.entry.js} +1 -1
  208. package/dist/native/p-3bed118d.entry.js +1 -0
  209. package/dist/native/{p-49745be2.entry.js → p-42dc404a.entry.js} +1 -1
  210. package/dist/native/{p-8faf3e05.entry.js → p-49ceb38e.entry.js} +1 -1
  211. package/dist/native/{p-c305f1c6.entry.js → p-4b8945c0.entry.js} +1 -1
  212. package/dist/native/{p-3f888601.entry.js → p-4cff908a.entry.js} +1 -1
  213. package/dist/native/{p-ffc9e2a0.entry.js → p-513fb9e7.entry.js} +1 -1
  214. package/dist/native/p-5adac760.entry.js +1 -0
  215. package/dist/native/p-6e49d3a1.entry.js +1 -0
  216. package/dist/native/{p-8decb323.entry.js → p-72c461ac.entry.js} +1 -1
  217. package/dist/native/{p-5375ddc6.entry.js → p-77bc9afe.entry.js} +1 -1
  218. package/dist/native/{p-33889f52.entry.js → p-789fdae9.entry.js} +1 -1
  219. package/dist/native/{p-287c67e1.entry.js → p-80ba6f84.entry.js} +1 -1
  220. package/dist/native/p-90397b9d.entry.js +1 -0
  221. package/dist/native/{p-40000df1.entry.js → p-91719d87.entry.js} +1 -1
  222. package/dist/native/p-a5d647f1.entry.js +1 -0
  223. package/dist/native/{p-0c65e726.entry.js → p-a6554d37.entry.js} +1 -1
  224. package/dist/native/{p-859b24ed.entry.js → p-b76682bb.entry.js} +1 -1
  225. package/dist/native/{p-d0dfa700.entry.js → p-bc0b637f.entry.js} +1 -1
  226. package/dist/native/p-bebf7bf7.entry.js +1 -0
  227. package/dist/native/{p-10dee67d.entry.js → p-c81532c9.entry.js} +1 -1
  228. package/dist/native/p-cec93106.entry.js +1 -0
  229. package/dist/native/{p-c5261442.entry.js → p-cfe99a3f.entry.js} +1 -1
  230. package/dist/native/{p-4514a6a4.entry.js → p-d0c5f580.entry.js} +1 -1
  231. package/dist/native/p-ef90ca99.entry.js +1 -0
  232. package/dist/native/{p-be2e4cf0.entry.js → p-f6341ac4.entry.js} +1 -1
  233. package/dist/native/{p-2afcd5e4.entry.js → p-f986b4e5.entry.js} +1 -1
  234. package/dist/types/components/nv-fielddropdown/nv-fielddropdown.d.ts +39 -0
  235. package/dist/types/components/nv-fieldselect/nv-fieldselect.d.ts +28 -0
  236. package/dist/types/components/nv-icon/nv-icons.d.ts +1 -1
  237. package/dist/types/components.d.ts +38 -0
  238. package/dist/vscode-data.json +332 -0
  239. package/hydrate/index.js +199 -79
  240. package/hydrate/index.mjs +199 -79
  241. package/package.json +1 -1
  242. package/dist/components/p-B4qcUV0M.js +0 -1
  243. package/dist/native/p-298d893d.entry.js +0 -1
  244. package/dist/native/p-5690757b.entry.js +0 -1
  245. package/dist/native/p-7c9e1f01.entry.js +0 -1
  246. package/dist/native/p-7cbc09f0.entry.js +0 -1
  247. package/dist/native/p-b99ad8a7.entry.js +0 -1
  248. package/dist/native/p-d4d04530.entry.js +0 -1
  249. package/dist/native/p-dfb46af1.entry.js +0 -1
  250. package/dist/native/p-e7a73a7c.entry.js +0 -1
  251. package/dist/native/p-eab25bfa.entry.js +0 -1
@@ -88,6 +88,13 @@ export class NvFielddropdown {
88
88
  * Enables or disables the filtering feature for the dropdown items.
89
89
  */
90
90
  this.filterable = false;
91
+ /**
92
+ * Shows the inline clear (×) button when a value is selected (or when
93
+ * filterable and the user has typed). The programmatic `clear()` method
94
+ * works regardless of this prop — leave it off when you want to manage
95
+ * clearing the selection from outside the component.
96
+ */
97
+ this.clearable = false;
91
98
  /**
92
99
  * When an item is selected by the user, the dropdown will continue to stay
93
100
  * open.
@@ -181,10 +188,35 @@ export class NvFielddropdown {
181
188
  if (!this.el?.contains(event.target))
182
189
  this.open = false;
183
190
  };
191
+ /**
192
+ * Handles clicks on the inline clear button. When a value is already
193
+ * selected and the user has typed in a filter, clearing should dismiss
194
+ * the filter and revert the input to the selected label rather than
195
+ * wipe the selection. Always emits `cleared` so subscribers see one
196
+ * consistent signal regardless of which path ran.
197
+ * @param {MouseEvent} [event] - The click event from the clear button.
198
+ */
199
+ this.handleClearButtonClick = (event) => {
200
+ // Keyboard-activated clicks have detail === 0; mouse clicks are >= 1.
201
+ // We only restore focus on keyboard activation so we don't steal focus
202
+ // from mouse users (and we don't reopen a closed popover via the focus
203
+ // listener on mouse clicks).
204
+ const isKeyboard = event?.detail === 0;
205
+ if (this.value && this.filterable && this.filterText?.length > 0) {
206
+ this.clearFilter();
207
+ this.cleared.emit();
208
+ if (isKeyboard)
209
+ this.focusField();
210
+ return;
211
+ }
212
+ this.clear();
213
+ if (isKeyboard)
214
+ this.focusField();
215
+ };
184
216
  this.handleFilterInput = () => {
185
217
  this.open = true;
186
- this.filterText = this.inputElement.value;
187
- this.filterTextChanged.emit(this.inputElement.value);
218
+ this.filterText = this.inputElement?.value ?? '';
219
+ this.filterTextChanged.emit(this.filterText);
188
220
  clearTimeout(this.debounceTimer);
189
221
  // Use longer debounce for fuzzy mode (Fuse.js needs more time)
190
222
  // For fuzzy mode, use FUZZY_DEBOUNCE_DELAY (300ms), otherwise use this.debounceDelay
@@ -200,12 +232,12 @@ export class NvFielddropdown {
200
232
  return '';
201
233
  if (this.filterText?.length)
202
234
  return this.filterText;
203
- if (this.options?.length > 1) {
204
- const matchingItem = this.options.find(option => option.value === this.value);
235
+ if ((this.options?.length ?? 0) > 1) {
236
+ const matchingItem = this.options?.find(option => option.value === this.value);
205
237
  return matchingItem?.label ?? matchingItem?.value ?? this.value;
206
238
  }
207
239
  const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitem'));
208
- const matchingItem = items.find(item => item.value === this.value);
240
+ const matchingItem = this.findItemMatchingValue(items);
209
241
  const selectedLabel = matchingItem
210
242
  ? matchingItem.label ??
211
243
  matchingItem.textContent?.trim() ??
@@ -262,8 +294,13 @@ export class NvFielddropdown {
262
294
  event.relatedTarget.tagName.includes('NV-FIELDDROPDOWNITEM')) {
263
295
  return;
264
296
  }
265
- if (event.target != this.toggleElement)
266
- this.open = true;
297
+ // Toggle and clear are inline controls inside the trigger that should
298
+ // not open the popover when focused (keyboard or otherwise).
299
+ if (event.target === this.toggleElement)
300
+ return;
301
+ if (event.target === this.clearElement)
302
+ return;
303
+ this.open = true;
267
304
  }
268
305
  handleFocusOut(event) {
269
306
  if (!(event.relatedTarget instanceof Node))
@@ -320,6 +357,32 @@ export class NvFielddropdown {
320
357
  this.setFilterInputToSelectedValue();
321
358
  }, 0);
322
359
  }
360
+ /**
361
+ * Clears the current selection. Resets the value to an empty string,
362
+ * removes the selected state from items, clears the filter text (when
363
+ * filterable) and emits `valueChanged` (and `filterTextChanged` when the
364
+ * filter was reset). Emits `cleared` when anything was actually reset.
365
+ */
366
+ async clear() {
367
+ const hadValue = Boolean(this.value);
368
+ const hadFilterText = this.filterable && this.filterText?.length > 0;
369
+ if (hadValue) {
370
+ this.value = '';
371
+ this.valueChanged.emit('');
372
+ }
373
+ if (hadFilterText) {
374
+ this.filterText = '';
375
+ this.filterTextChanged.emit('');
376
+ this.filterItems();
377
+ }
378
+ if (hadValue || hadFilterText) {
379
+ this.cleared.emit();
380
+ }
381
+ // Wait for wrapper lifecycle to finish before resetting input display.
382
+ setTimeout(() => {
383
+ this.setFilterInputToSelectedValue();
384
+ }, 0);
385
+ }
323
386
  /**
324
387
  * Toggles the dropdown popover open state
325
388
  * @param {boolean} open - The open state to set, if null, toggles the state
@@ -348,6 +411,21 @@ export class NvFielddropdown {
348
411
  return (this.inputElement.value = '');
349
412
  this.inputElement.value = this.getSelectedLabel();
350
413
  }
414
+ /**
415
+ * Finds the item that matches the current value. Falls back to matching by
416
+ * label when no item matches by value, so that consumers who pass a value
417
+ * matching only the label (e.g. `<nv-fielddropdownitem label="Item 2">`
418
+ * with `value="Item 2"`) still get the correct selected item.
419
+ * @param {HTMLNvFielddropdownitemElement[]} items - The dropdown items to search.
420
+ * @returns {HTMLNvFielddropdownitemElement | undefined} The matching item, or undefined if no match is found.
421
+ */
422
+ findItemMatchingValue(items) {
423
+ if (!this.value)
424
+ return undefined;
425
+ const value = this.value;
426
+ return (items.find(item => item.value === value) ??
427
+ items.find(item => item.label === value));
428
+ }
351
429
  // Will exclude detached items and data-empty
352
430
  getFilterableItems() {
353
431
  return Array.from(this.el.querySelectorAll('nv-fielddropdownitem:not([data-empty]):not([detached])'));
@@ -592,16 +670,10 @@ export class NvFielddropdown {
592
670
  }
593
671
  async updateSelectedItem() {
594
672
  const items = this.getAllItems();
595
- if (this.value) {
596
- items.forEach(item => {
597
- if (item.value === this.value) {
598
- item.selected = true;
599
- }
600
- else {
601
- item.selected = false;
602
- }
603
- });
604
- }
673
+ const matchingItem = this.findItemMatchingValue(items);
674
+ items.forEach(item => {
675
+ item.selected = Boolean(this.value) && item === matchingItem;
676
+ });
605
677
  }
606
678
  //#endregion METHODS
607
679
  /****************************************************************************/
@@ -619,7 +691,9 @@ export class NvFielddropdown {
619
691
  componentDidRender() {
620
692
  // Make sure to show the value when the field is disabled or readonly
621
693
  // as we switch to an input instead of a p in that case
622
- if (!this.filterable && (this.disabled || this.readonly)) {
694
+ if (!this.filterable &&
695
+ (this.disabled || this.readonly) &&
696
+ this.inputElement) {
623
697
  this.inputElement.value = this.getSelectedLabel();
624
698
  }
625
699
  }
@@ -658,11 +732,14 @@ export class NvFielddropdown {
658
732
  ? ariaRequiredAttrValue === 'true' || ariaRequiredAttrValue === ''
659
733
  : undefined;
660
734
  const useNativeRequired = this.required && (!useAriaRequired || ariaRequiredValue === true);
661
- return (h(Host, { key: 'a0a129aeee7140680b618e20e0ba2557835d3aee', role: "combobox", "aria-expanded": this.open.toString(), "aria-haspopup": "listbox", "aria-label": this.label }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: 'e84b1cb668cc910b8fe4f81a4939eb6109829983', htmlFor: this.inputId, onClick: this.syncToggleDropdown.bind(this) }, h("slot", { key: 'b1e59b97c865e87559f7bad61019a05184d27623', name: "label" }, this.label))), h("nv-popover", { key: '31e5b57856dfb48b5c6f212f0f29a95b05eefe06', triggerMode: "controlled", placement: "bottom-start", open: this.open, onOpenChanged: e => this.openChanged.emit(e.detail) }, h("div", { key: 'b828839bf1b2c957afee3aaa1a9c9faf34c15bce', class: "input-wrapper", slot: "trigger" }, h("slot", { key: 'a0d2cc5c6806ed2694310b2e20fa5d4d218194e1', name: "before-input" }), h("div", { key: '812cbc43ba84748db9cbc49eb0f0c22995ac0285', class: "input-container" }, h("slot", { key: '0e79dfcd550c09a9cf45ed9cdae36e15a72be285', name: "leading-input" }), this.filterable || this.disabled || this.readonly ? (h("input", { "data-scope": "focusable", id: this.inputId, type: "search", ref: e => (this.inputElement = e), autofocus: this.autofocus, autocomplete: this.autocomplete, placeholder: this.placeholder, name: this.name, required: useNativeRequired ? this.required : undefined, ...(ariaRequiredValue !== undefined && {
735
+ return (h(Host, { key: '83aecee12e5f0fea2ddc293f1631dc4e55ab3764', role: "combobox", "aria-expanded": this.open.toString(), "aria-haspopup": "listbox", "aria-label": this.label }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: 'adfef46ef0163fb3c902df5df70b5c591a6dd7e1', htmlFor: this.inputId, onClick: this.syncToggleDropdown.bind(this) }, h("slot", { key: 'ed6bd8cc6fcace8604f934ba197c31589bf5e296', name: "label" }, this.label))), h("nv-popover", { key: '9dfa5dd021c2d0803a35b79fd58dd70422dbe6f0', triggerMode: "controlled", placement: "bottom-start", open: this.open, onOpenChanged: e => this.openChanged.emit(e.detail) }, h("div", { key: '62024e3fae662f316a932cce628e58e6917fc624', class: "input-wrapper", slot: "trigger" }, h("slot", { key: '61fe57f847075dc6e1447cc377e7e8f828700b43', name: "before-input" }), h("div", { key: '8139ffe5b0b7d37781c2b435ed1b9c94f2eea9de', class: "input-container" }, h("slot", { key: 'ab2515724a53a1b9e4081bd1944130cd435a0a92', name: "leading-input" }), this.filterable || this.disabled || this.readonly ? (h("input", { "data-scope": "focusable", id: this.inputId, type: "search", ref: e => (this.inputElement = e), autofocus: this.autofocus, autocomplete: this.autocomplete, placeholder: this.placeholder, name: this.name, required: useNativeRequired ? this.required : undefined, ...(ariaRequiredValue !== undefined && {
662
736
  'aria-required': String(ariaRequiredValue),
663
- }), disabled: this.disabled, readOnly: this.readonly, onInput: this.handleFilterInput })) : (h("p", { "data-scope": "focusable", id: this.inputId, ref: el => (this.selectElement = el), class: "non-filterable-text", tabIndex: this.disabled ? -1 : 0 }, this.getSelectedLabel() || this.value || this.placeholder)), this.filterable && this.filterText && (h("nv-iconbutton", { key: 'd84df53cffb3eb54d8263f8b83ea325e1806d036', name: "x", size: "md", emphasis: "lower", class: "clear-button", onClick: this.clearFilter.bind(this), "aria-label": "Clear input" })), this.error && (h("nv-icon", { key: 'aa47af71684d1143d49acea9f652a75af721ea42', name: "alert-circle", class: "validation", size: "md" })), h("nv-iconbutton", { key: 'b3b4f616bfa69a0ec169d38bc4a5997a25bb752a', "data-scope": "toggle-dropdown", ref: el => (this.toggleElement = el), name: this.open ? 'chevron-top' : 'chevron-down', size: "md", emphasis: "lower", "aria-label": this.open ? 'Hide dropdown' : 'Show dropdown', onClick: this.syncToggleDropdown.bind(this), tabIndex: this.disabled ? -1 : 0 })), h("slot", { key: '1186748c136a4738a40bedbd9d4e55ce34d43600', name: "after-input" })), h("div", { key: 'af5fd84039c5a319b0301e41d42eca46ec599a6d', slot: "content", style: this.maxHeight ? { maxHeight: this.maxHeight } : {} }, this.options?.length > 0 && (h("ul", { key: 'b28fae6234d2b5a6d5a350fc91070f2a59c19939' }, this.options.map(option => (h("nv-fielddropdownitem", { label: option.label, value: option.value, disabled: option.disabled, selected: option.value === this.value }))))), h("slot", { key: '1036fac674f016670b916c09f7892d1600c3998a', name: "content" }))), (this.description ||
664
- this.el.querySelector('[slot="description"]')) && (h("div", { key: 'a047c7a480de216be1c83f84e7f52220cc174cc6', class: "description" }, h("slot", { key: '01a54b2fd7f5086c7c7247d5b11628e3012d63dd', name: "description" }, this.description))), (this.errorDescription ||
665
- this.el.querySelector('[slot="error-description"]')) && (h("div", { key: '4cff548c666ea082738bd7f66878c564126dc60c', hidden: !this.error, class: "error-description" }, h("slot", { key: '553170d5254e4841d91eee119756a5466663c5c0', name: "error-description" }, this.errorDescription)))));
737
+ }), disabled: this.disabled, readOnly: this.readonly, onInput: this.handleFilterInput })) : (h("p", { "data-scope": "focusable", id: this.inputId, ref: el => (this.selectElement = el), class: "non-filterable-text", tabIndex: this.disabled ? -1 : 0 }, this.getSelectedLabel() || this.value || this.placeholder)), this.clearable &&
738
+ !this.disabled &&
739
+ !this.readonly &&
740
+ (this.value || (this.filterable && this.filterText)) && (h("nv-iconbutton", { key: 'b467a3949af859fe4e9d19f810a19a8e1d1834c9', ref: el => (this.clearElement = el), "data-scope": "clear", name: "x", size: "md", emphasis: "lower", class: "clear-button", onMouseDown: (e) => e.preventDefault(), onClick: this.handleClearButtonClick, "aria-label": this.value ? 'Clear selection' : 'Clear input', title: this.value ? 'Clear selection' : 'Clear input' })), this.error && (h("nv-icon", { key: '2c05d617da93adddd4994c3063b0e6fe7be017c7', name: "alert-circle", class: "validation", size: "md" })), h("nv-iconbutton", { key: '372a295a58b391a61d240d5133b427c3ddf1edba', "data-scope": "toggle-dropdown", ref: el => (this.toggleElement = el), name: this.open ? 'chevron-top' : 'chevron-down', size: "md", emphasis: "lower", "aria-label": this.open ? 'Hide dropdown' : 'Show dropdown', onClick: this.syncToggleDropdown.bind(this), tabIndex: this.disabled ? -1 : 0 })), h("slot", { key: '95db16c591f0bf7dec95550260b9d6bcd7e084a9', name: "after-input" })), h("div", { key: '46372589dee8ff8509570bd1a3cc33763cf17869', slot: "content", style: this.maxHeight ? { maxHeight: this.maxHeight } : {} }, (this.options?.length ?? 0) > 0 && (h("ul", { key: 'dc2840ef3e798291e49ae179a978c5b3d277ffa2' }, this.options?.map(option => (h("nv-fielddropdownitem", { label: option.label, value: option.value, disabled: option.disabled, selected: option.value === this.value }))))), h("slot", { key: '750ef13e5911fe9bfc9a277b24150a1d3e631d4d', name: "content" }))), (this.description ||
741
+ this.el.querySelector('[slot="description"]')) && (h("div", { key: '34e1fbd85f790f0ea38502d10daadabf2c26c493', class: "description" }, h("slot", { key: '248779124cefa199c5ee3b664c1a26ddfab0d849', name: "description" }, this.description))), (this.errorDescription ||
742
+ this.el.querySelector('[slot="error-description"]')) && (h("div", { key: 'dff99dce8c08ca76a620cf199147a72a0624b3be', hidden: !this.error, class: "error-description" }, h("slot", { key: 'fcdbc2a466f9d13593a5fb6d7a2ba719b0df19dd', name: "error-description" }, this.errorDescription)))));
666
743
  }
667
744
  static get is() { return "nv-fielddropdown"; }
668
745
  static get formAssociated() { return true; }
@@ -1014,6 +1091,26 @@ export class NvFielddropdown {
1014
1091
  "attribute": "filterable",
1015
1092
  "defaultValue": "false"
1016
1093
  },
1094
+ "clearable": {
1095
+ "type": "boolean",
1096
+ "mutable": false,
1097
+ "complexType": {
1098
+ "original": "boolean",
1099
+ "resolved": "boolean",
1100
+ "references": {}
1101
+ },
1102
+ "required": false,
1103
+ "optional": false,
1104
+ "docs": {
1105
+ "tags": [],
1106
+ "text": "Shows the inline clear (\u00D7) button when a value is selected (or when\nfilterable and the user has typed). The programmatic `clear()` method\nworks regardless of this prop \u2014 leave it off when you want to manage\nclearing the selection from outside the component."
1107
+ },
1108
+ "getter": false,
1109
+ "setter": false,
1110
+ "reflect": true,
1111
+ "attribute": "clearable",
1112
+ "defaultValue": "false"
1113
+ },
1017
1114
  "openOnSelect": {
1018
1115
  "type": "boolean",
1019
1116
  "mutable": false,
@@ -1352,6 +1449,21 @@ export class NvFielddropdown {
1352
1449
  "resolved": "string",
1353
1450
  "references": {}
1354
1451
  }
1452
+ }, {
1453
+ "method": "cleared",
1454
+ "name": "cleared",
1455
+ "bubbles": false,
1456
+ "cancelable": true,
1457
+ "composed": true,
1458
+ "docs": {
1459
+ "tags": [],
1460
+ "text": "Emitted when the field is cleared via the inline clear button or the\nprogrammatic `clear()` method. Useful for reacting to user-initiated\nclears without subscribing to every `valueChanged` emission."
1461
+ },
1462
+ "complexType": {
1463
+ "original": "void",
1464
+ "resolved": "void",
1465
+ "references": {}
1466
+ }
1355
1467
  }, {
1356
1468
  "method": "openChanged",
1357
1469
  "name": "openChanged",
@@ -1413,6 +1525,23 @@ export class NvFielddropdown {
1413
1525
  "tags": []
1414
1526
  }
1415
1527
  },
1528
+ "clear": {
1529
+ "complexType": {
1530
+ "signature": "() => Promise<void>",
1531
+ "parameters": [],
1532
+ "references": {
1533
+ "Promise": {
1534
+ "location": "global",
1535
+ "id": "global::Promise"
1536
+ }
1537
+ },
1538
+ "return": "Promise<void>"
1539
+ },
1540
+ "docs": {
1541
+ "text": "Clears the current selection. Resets the value to an empty string,\nremoves the selected state from items, clears the filter text (when\nfilterable) and emits `valueChanged` (and `filterTextChanged` when the\nfilter was reset). Emits `cleared` when anything was actually reset.",
1542
+ "tags": []
1543
+ }
1544
+ },
1416
1545
  "toggleDropdown": {
1417
1546
  "complexType": {
1418
1547
  "signature": "(open?: boolean) => Promise<void>",
@@ -9,13 +9,13 @@ const NvFielddropdownitemDocs = {
9
9
  {
10
10
  name: 'Default',
11
11
  description: 'Basic dropdown item within a fielddropdown',
12
- template: (h("nv-fielddropdown", { label: "Select an option" }, h("nv-fielddropdownitem", { "data-storybook-args": true, value: "item1" }, "Item 1"), h("nv-fielddropdownitem", { value: "item2" }, "Item 2"), h("nv-fielddropdownitem", { value: "item3" }, "Item 3"))),
12
+ template: (h("nv-fielddropdown", { label: "Select an option" }, h("ul", { slot: "content" }, h("nv-fielddropdownitem", { "data-storybook-args": true, value: "item1" }, "Item 1"), h("nv-fielddropdownitem", { value: "item2" }, "Item 2"), h("nv-fielddropdownitem", { value: "item3" }, "Item 3")))),
13
13
  },
14
14
  // value
15
15
  {
16
16
  name: nameof(x => x.value),
17
17
  description: 'Dropdown item with a specific value',
18
- template: (h("nv-fielddropdown", { label: "Select a city" }, h("nv-fielddropdownitem", { value: "paris" }, "Paris"), h("nv-fielddropdownitem", { "data-storybook-args": true, value: "london" }, "London"), h("nv-fielddropdownitem", { value: "tokyo" }, "Tokyo"))),
18
+ template: (h("nv-fielddropdown", { label: "Select a city" }, h("ul", { slot: "content" }, h("nv-fielddropdownitem", { value: "paris" }, "Paris"), h("nv-fielddropdownitem", { "data-storybook-args": true, value: "london" }, "London"), h("nv-fielddropdownitem", { value: "tokyo" }, "Tokyo")))),
19
19
  },
20
20
  // disabled
21
21
  {
@@ -24,7 +24,7 @@ const NvFielddropdownitemDocs = {
24
24
  args: {
25
25
  disabled: true,
26
26
  },
27
- template: (h("nv-fielddropdown", { label: "Select an option" }, h("nv-fielddropdownitem", { value: "item1" }, "Item 1"), h("nv-fielddropdownitem", { "data-storybook-args": true, value: "item2", disabled: true }, "Item 2 (Disabled)"), h("nv-fielddropdownitem", { value: "item3" }, "Item 3"))),
27
+ template: (h("nv-fielddropdown", { label: "Select an option" }, h("ul", { slot: "content" }, h("nv-fielddropdownitem", { value: "item1" }, "Item 1"), h("nv-fielddropdownitem", { "data-storybook-args": true, value: "item2", disabled: true }, "Item 2 (Disabled)"), h("nv-fielddropdownitem", { value: "item3" }, "Item 3")))),
28
28
  },
29
29
  // detached
30
30
  {
@@ -33,25 +33,25 @@ const NvFielddropdownitemDocs = {
33
33
  args: {
34
34
  detached: true,
35
35
  },
36
- template: (h("nv-fielddropdown", { label: "Search items", filterable: true }, h("nv-fielddropdownitem", { "data-storybook-args": true, value: "all", detached: true }, "All Items"), h("nv-fielddropdownitem", { value: "item1" }, "Item 1"), h("nv-fielddropdownitem", { value: "item2" }, "Item 2"), h("nv-fielddropdownitem", { value: "item3" }, "Item 3"))),
36
+ template: (h("nv-fielddropdown", { label: "Search items", filterable: true }, h("ul", { slot: "content" }, h("nv-fielddropdownitem", { "data-storybook-args": true, value: "all", detached: true }, "All Items"), h("nv-fielddropdownitem", { value: "item1" }, "Item 1"), h("nv-fielddropdownitem", { value: "item2" }, "Item 2"), h("nv-fielddropdownitem", { value: "item3" }, "Item 3")))),
37
37
  },
38
38
  // WithIcon
39
39
  {
40
40
  name: 'WithIcon',
41
41
  description: 'Dropdown item with leading icon',
42
- template: (h("nv-fielddropdown", { label: "Select with icons" }, h("nv-fielddropdownitem", { value: "home" }, h("nv-icon", { slot: "leading-icon", name: "home" }), "Home"), h("nv-fielddropdownitem", { value: "user" }, h("nv-icon", { slot: "leading-icon", name: "user" }), "Profile"), h("nv-fielddropdownitem", { value: "settings" }, h("nv-icon", { slot: "leading-icon", name: "settings" }), "Settings"))),
42
+ template: (h("nv-fielddropdown", { label: "Select with icons" }, h("ul", { slot: "content" }, h("nv-fielddropdownitem", { value: "home" }, h("nv-icon", { slot: "leading-icon", name: "home" }), "Home"), h("nv-fielddropdownitem", { value: "user" }, h("nv-icon", { slot: "leading-icon", name: "user" }), "Profile"), h("nv-fielddropdownitem", { value: "settings" }, h("nv-icon", { slot: "leading-icon", name: "settings" }), "Settings")))),
43
43
  },
44
44
  // WithAvatar
45
45
  {
46
46
  name: 'WithAvatar',
47
47
  description: 'Dropdown item with avatar',
48
- template: (h("nv-fielddropdown", { label: "Select user" }, h("nv-fielddropdownitem", { value: "user1" }, h("nv-avatar", { slot: "leading-icon", initials: "JD", size: "xs" }), "John Doe"), h("nv-fielddropdownitem", { value: "user2" }, h("nv-avatar", { slot: "leading-icon", initials: "JS", size: "xs" }), "Jane Smith"))),
48
+ template: (h("nv-fielddropdown", { label: "Select user" }, h("ul", { slot: "content" }, h("nv-fielddropdownitem", { value: "user1" }, h("nv-avatar", { slot: "leading-icon", initials: "JD", size: "xs" }), "John Doe"), h("nv-fielddropdownitem", { value: "user2" }, h("nv-avatar", { slot: "leading-icon", initials: "JS", size: "xs" }), "Jane Smith")))),
49
49
  },
50
50
  // WithBadge
51
51
  {
52
52
  name: 'WithBadge',
53
53
  description: 'Dropdown item with trailing badge',
54
- template: (h("nv-fielddropdown", { label: "Select status" }, h("nv-fielddropdownitem", { value: "active" }, "Active", h("nv-badge", { slot: "trailing-icon", color: "success", label: "New" })), h("nv-fielddropdownitem", { value: "pending" }, "Pending", h("nv-badge", { slot: "trailing-icon", color: "warning", label: "3" })), h("nv-fielddropdownitem", { value: "inactive" }, "Inactive"))),
54
+ template: (h("nv-fielddropdown", { label: "Select status" }, h("ul", { slot: "content" }, h("nv-fielddropdownitem", { value: "active" }, "Active", h("nv-badge", { slot: "trailing-icon", color: "success", label: "New" })), h("nv-fielddropdownitem", { value: "pending" }, "Pending", h("nv-badge", { slot: "trailing-icon", color: "warning", label: "3" })), h("nv-fielddropdownitem", { value: "inactive" }, "Inactive")))),
55
55
  },
56
56
  ],
57
57
  };
@@ -53,7 +53,7 @@ export class NvFielddropdownitem {
53
53
  /****************************************************************************/
54
54
  //#region RENDER
55
55
  render() {
56
- return (h(Host, { key: '9931decf5664d77d8c164859bc4046ca313e13a9', role: "menuitem", tabindex: '-1', onClick: this.handleSelected }, h("slot", { key: '21c6457187f8d5d561e2783b212d5230e85a8f8c' }, h("div", { key: '751615833fcb1d200abd526d9c80822d7bda30b4', class: "text-wrapper" }, h("span", { key: '67a7bcb31cdf32eee18e419e85f28b53b74a4f82', "data-scope": "text" }, this.label))), this.selected && (h("nv-icon", { key: '09b1b6f5366f89ca8d03fe51738c627b899bb454', name: "check", "aria-hidden": "true", "data-scope": "selected" }))));
56
+ return (h(Host, { key: '9931decf5664d77d8c164859bc4046ca313e13a9', role: "menuitem", tabindex: '-1', onClick: this.handleSelected }, this.selected && (h("nv-icon", { key: 'aba64f319fb37bc8f471ebd65d00d0f17158fe41', name: "check", "aria-hidden": "true", "data-scope": "selected" })), h("slot", { key: 'ffafa2e39d704caa576d59bba459503be10f4ffc' }, h("div", { key: '065293dca56bfaec8f89910f88b92a52907fcf28', class: "text-wrapper" }, h("span", { key: '2f85b57db26203bc19b32047707f9281a6d906a0', "data-scope": "text" }, this.label)))));
57
57
  }
58
58
  static get is() { return "nv-fielddropdownitem"; }
59
59
  static get originalStyleUrls() {
@@ -197,6 +197,17 @@ const NvFieldselectDocs = {
197
197
  },
198
198
  template: (h("nv-fieldselect", { "data-storybook-args": true }, h("option", { value: "1" }, "Option 1"), h("option", { value: "2" }, "Option 2"))),
199
199
  },
200
+ // clearable
201
+ {
202
+ name: nameof(x => x.clearable),
203
+ description: 'When set, an inline clear (×) button appears whenever a value is selected so users can wipe the selection in one click. The programmatic `clear()` method works regardless of this prop.',
204
+ args: {
205
+ label: 'Select with clear button',
206
+ value: '2',
207
+ clearable: true,
208
+ },
209
+ template: (h("nv-fieldselect", { "data-storybook-args": true }, h("option", { value: "1" }, "Option 1"), h("option", { value: "2" }, "Option 2"), h("option", { value: "3" }, "Option 3"))),
210
+ },
200
211
  // Placeholder
201
212
  {
202
213
  name: 'Placeholder',
@@ -68,6 +68,12 @@ export class NvFieldselect {
68
68
  * When enabled, allows the select to handle multiple selections.
69
69
  */
70
70
  this.multiple = false;
71
+ /**
72
+ * Shows the inline clear (×) button when a value is selected. The
73
+ * programmatic `clear()` method works regardless of this prop — leave
74
+ * it off when you want to manage clearing from outside the component.
75
+ */
76
+ this.clearable = false;
71
77
  /**
72
78
  * The value of the select field.
73
79
  * - If `multiple` is `false`, it's a single string.
@@ -121,6 +127,21 @@ export class NvFieldselect {
121
127
  this.selectElement.focus();
122
128
  }
123
129
  };
130
+ /**
131
+ * Handles a click on the inline clear button. Stops the click from
132
+ * bubbling up to the select container (which would refocus the select)
133
+ * and clears the value. On keyboard activation (Enter/Space) it also
134
+ * moves focus back to the native `<select>` so keyboard users don't
135
+ * lose their place when the button disappears.
136
+ * @param {MouseEvent} event - The click event from the clear button.
137
+ */
138
+ this.handleClearButtonClick = (event) => {
139
+ event.stopPropagation();
140
+ this.clear();
141
+ // detail === 0 means keyboard-activated; >= 1 means a real mouse click.
142
+ if (event.detail === 0)
143
+ this.selectElement?.focus();
144
+ };
124
145
  }
125
146
  //#endregion EVENTS
126
147
  /****************************************************************************/
@@ -252,6 +273,19 @@ export class NvFieldselect {
252
273
  this.selectElement = this.el.querySelector('select');
253
274
  }
254
275
  }
276
+ /**
277
+ * Clears the current selection. Resets the value to an empty string and
278
+ * emits `valueChanged` and `cleared` when the value actually changed.
279
+ * The `@Watch('value')` watcher takes care of syncing the underlying
280
+ * native `<select>` options and the form value.
281
+ */
282
+ async clear() {
283
+ if (!this.value)
284
+ return;
285
+ this.value = '';
286
+ this.valueChanged.emit('');
287
+ this.cleared.emit();
288
+ }
255
289
  //#endregion METHODS
256
290
  /****************************************************************************/
257
291
  //#region LIFECYCLE
@@ -372,15 +406,18 @@ export class NvFieldselect {
372
406
  ? ariaRequiredAttrValue === 'true' || ariaRequiredAttrValue === ''
373
407
  : undefined;
374
408
  const useNativeRequired = this.required && (!useAriaRequired || ariaRequiredValue === true);
375
- return (h(Host, { key: 'ee72e67a671b7061d3af5f76796d09c0372b38fa' }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: '8bec44fa26d9360b585e0a5bccd4fdd7ed8cfc92', htmlFor: this.inputId }, h("slot", { key: '35b2a393d88b37141a6dd7ea90f860fcee1d840e', name: "label" }, this.label))), h("div", { key: '151b1e03cd50911b024ae692fa7eb25e5c7c8938', class: "select-wrapper" }, h("slot", { key: 'b82c37856a7a616a9addb1bd5a4d79aeeb2587b4', name: "before-input" }), h("div", { key: 'cf5713c682e4ea9e08bb0ee6db5ab369cdaaf713', class: "select-container", onClick: this.handleSelectContainerClick }, h("slot", { key: '4fc79bed93ab1dfdf31a18805b5e72c5b35cd641', name: "leading-input" }), this.internalReadonly && (h("input", { key: '316cc1f0bf08ead5f7f5d8d1306cbc02b91fde54', id: this.inputId + '-readonly', type: "text", value: this.computedDisplayValue, readonly: true, class: "readonly-input", "aria-readonly": "true", "aria-label": this.label, "aria-describedby": this.error
409
+ return (h(Host, { key: '94e1f6453200ac25c9a8bb1161da1332fe964a88' }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: 'cddbd8dcb267c3931f2a97d2409732e203e60d42', htmlFor: this.inputId }, h("slot", { key: 'bfbae02481c4bdac23e2c7c69044c171c2e4c627', name: "label" }, this.label))), h("div", { key: '1070a34841596517c2803aa529b875c86e1cace7', class: "select-wrapper" }, h("slot", { key: '8a36b232f72dcf98aaa0fd1d3fe0ee4a77102254', name: "before-input" }), h("div", { key: '716bd6d6f489b1b23d4f97ddf8b404c9b06cbb6d', class: "select-container", onClick: this.handleSelectContainerClick }, h("slot", { key: '282b5103ab923c70d66fb5cbf68bb741f2f9c436', name: "leading-input" }), this.internalReadonly && (h("input", { key: 'a612673aec7e0fb2a63c0d52a68bc2f74332db44', id: this.inputId + '-readonly', type: "text", value: this.computedDisplayValue, readonly: true, class: "readonly-input", "aria-readonly": "true", "aria-label": this.label, "aria-describedby": this.error
376
410
  ? `${this.inputId}-error`
377
- : `${this.inputId}-description` })), h("select", { key: '1e1676c50ee4915bd6750677b501f6683d34fa25', id: this.inputId, ref: el => (this.selectElement = el), name: this.name, autofocus: this.autofocus, disabled: this.disabled, required: useNativeRequired ? this.required : undefined, ...(ariaRequiredValue !== undefined && {
411
+ : `${this.inputId}-description` })), h("select", { key: '4fe11669e745846bcc14e3c657160287912351f2', id: this.inputId, ref: el => (this.selectElement = el), name: this.name, autofocus: this.autofocus, disabled: this.disabled, required: useNativeRequired ? this.required : undefined, ...(ariaRequiredValue !== undefined && {
378
412
  'aria-required': String(ariaRequiredValue),
379
413
  }), multiple: this.multiple, onChange: this.handleSelectChange, class: this.internalReadonly ? 'hidden' : '', "aria-label": this.label, "aria-describedby": this.error
380
414
  ? `${this.inputId}-error`
381
- : `${this.inputId}-description` }, this.options && this.options.length > 0 ? (this.options.map(option => (h("option", { value: option.value, selected: option.selected, disabled: option.disabled }, option.label)))) : (h("slot", null))), h("div", { key: 'df1132a8bb20d35d94daec1b7e32f5769c9e6ec8', class: "select-icons" }, this.error && (h("nv-icon", { key: '39825cc8efd80f89b29644525d4e9fe9ae9e5edb', name: "alert-circle", class: "validation", size: "md" })), this.success && (h("nv-icon", { key: 'c9123ff11d354283e53470991a4d8755cc89b552', name: "circle-check", class: "validation", size: "md" })), !this.multiple && (h("nv-iconbutton", { key: '7f6dacc97b04100c4ddbbc503d16f31282365232', name: "chevron-down", size: "md", emphasis: "lower", tabindex: -1 })))), h("slot", { key: '61b4d062cc94f90ebe02113950f02940a2765d36', name: "after-input" })), (this.description ||
382
- this.el.querySelector('[slot="description"]')) && (h("div", { key: '0685de6f40b839ea062c6088c60a10d72490fab0', class: "description", id: `${this.inputId}-description` }, h("slot", { key: '1d15fa435a00efef9a75295149c44dfc407fcc63', name: "description" }, this.description))), (this.errorDescription ||
383
- this.el.querySelector('[slot="error-description"]')) && (h("div", { key: '623d7af55f6b523e834159769a2f783fb63052f7', class: "error-description", id: `${this.inputId}-error` }, h("slot", { key: '2f2c9b6ea72ae9093ccd5735813bc5c3415a39cc', name: "error-description" }, this.errorDescription)))));
415
+ : `${this.inputId}-description` }, this.options && this.options.length > 0 ? (this.options.map(option => (h("option", { value: option.value, selected: option.selected, disabled: option.disabled }, option.label)))) : (h("slot", null))), h("div", { key: 'e04e676525522d40410815ea8da80f9c18730e3f', class: "select-icons" }, this.clearable &&
416
+ !this.disabled &&
417
+ !this.internalReadonly &&
418
+ this.value && (h("nv-iconbutton", { key: '176fdf45a3c04290895be367027c38581292c2c0', "data-scope": "clear", name: "x", size: "md", emphasis: "lower", class: "clear-button", onMouseDown: (e) => e.preventDefault(), onClick: this.handleClearButtonClick, "aria-label": "Clear selection", title: "Clear selection" })), this.error && (h("nv-icon", { key: '7eef5e80d744b7bfbcfb3fc857837c58e6ce4e54', name: "alert-circle", class: "validation", size: "md" })), this.success && (h("nv-icon", { key: '68085ced60e2c9aa70aa26db8fa96f0a5407d3c4', name: "circle-check", class: "validation", size: "md" })), !this.multiple && (h("nv-iconbutton", { key: 'c1e85cc79e3438f20ae891fb439b77ba694d8db8', name: "chevron-down", size: "md", emphasis: "lower", tabindex: -1 })))), h("slot", { key: '5534a2610d76d6d23e91ca3010b29f331501c923', name: "after-input" })), (this.description ||
419
+ this.el.querySelector('[slot="description"]')) && (h("div", { key: 'eda00100479bb6325a49db62933f7d325e559491', class: "description", id: `${this.inputId}-description` }, h("slot", { key: 'f976d87998ef48b7e1e493f6064547efa1c212c3', name: "description" }, this.description))), (this.errorDescription ||
420
+ this.el.querySelector('[slot="error-description"]')) && (h("div", { key: '28d55210a573fe85b57752873ca14f0adc65a404', class: "error-description", id: `${this.inputId}-error` }, h("slot", { key: 'ac95ef49e88372d3b69456affbbdaad753a5e5c4', name: "error-description" }, this.errorDescription)))));
384
421
  }
385
422
  static get is() { return "nv-fieldselect"; }
386
423
  static get formAssociated() { return true; }
@@ -713,6 +750,26 @@ export class NvFieldselect {
713
750
  "attribute": "multiple",
714
751
  "defaultValue": "false"
715
752
  },
753
+ "clearable": {
754
+ "type": "boolean",
755
+ "mutable": false,
756
+ "complexType": {
757
+ "original": "boolean",
758
+ "resolved": "boolean",
759
+ "references": {}
760
+ },
761
+ "required": false,
762
+ "optional": false,
763
+ "docs": {
764
+ "tags": [],
765
+ "text": "Shows the inline clear (\u00D7) button when a value is selected. The\nprogrammatic `clear()` method works regardless of this prop \u2014 leave\nit off when you want to manage clearing from outside the component."
766
+ },
767
+ "getter": false,
768
+ "setter": false,
769
+ "reflect": true,
770
+ "attribute": "clearable",
771
+ "defaultValue": "false"
772
+ },
716
773
  "value": {
717
774
  "type": "string",
718
775
  "mutable": true,
@@ -820,8 +877,44 @@ export class NvFieldselect {
820
877
  "resolved": "string",
821
878
  "references": {}
822
879
  }
880
+ }, {
881
+ "method": "cleared",
882
+ "name": "cleared",
883
+ "bubbles": false,
884
+ "cancelable": true,
885
+ "composed": true,
886
+ "docs": {
887
+ "tags": [],
888
+ "text": "Emitted when the field is cleared via the inline clear button or the\nprogrammatic `clear()` method. Useful for reacting to user-initiated\nclears without subscribing to every `valueChanged` emission."
889
+ },
890
+ "complexType": {
891
+ "original": "void",
892
+ "resolved": "void",
893
+ "references": {}
894
+ }
823
895
  }];
824
896
  }
897
+ static get methods() {
898
+ return {
899
+ "clear": {
900
+ "complexType": {
901
+ "signature": "() => Promise<void>",
902
+ "parameters": [],
903
+ "references": {
904
+ "Promise": {
905
+ "location": "global",
906
+ "id": "global::Promise"
907
+ }
908
+ },
909
+ "return": "Promise<void>"
910
+ },
911
+ "docs": {
912
+ "text": "Clears the current selection. Resets the value to an empty string and\nemits `valueChanged` and `cleared` when the value actually changed.\nThe `@Watch('value')` watcher takes care of syncing the underlying\nnative `<select>` options and the form value.",
913
+ "tags": []
914
+ }
915
+ }
916
+ };
917
+ }
825
918
  static get elementRef() { return "el"; }
826
919
  static get watchers() {
827
920
  return [{
@@ -164,6 +164,9 @@ nv-fieldselect .select-wrapper .select-container > .select-icons > nv-iconbutton
164
164
  border-top-right-radius: var(--form-field-radius);
165
165
  border-bottom-right-radius: var(--form-field-radius);
166
166
  }
167
+ nv-fieldselect .select-wrapper .select-container > .select-icons > nv-iconbutton.clear-button {
168
+ pointer-events: auto;
169
+ }
167
170
  nv-fieldselect .select-wrapper .select-container input {
168
171
  display: flex;
169
172
  align-items: center;
@@ -464,11 +464,11 @@ export class NvFieldslider {
464
464
  /****************************************************************************/
465
465
  //#region RENDER
466
466
  render() {
467
- return (h(Host, { key: '1251891d0796093b0b199218304444cb5e530367' }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: 'dfb2f64d6b289ad18ac9b5a8ca6e445bf591add9', htmlFor: this.startInputId }, h("slot", { key: '96cce5982bf52a76f92afcf027277955fe30ce2e', name: "label" }, this.label))), h("div", { key: '84d9150d80d5a971180f04872fb2de07817e2e90', class: "slider-container" }, this.range ? (h(FieldInput, { range: this.range, hasField: this.hasField, value: this.valueInternal, rangeValue: this.rangeValueInternal, index: 0, inputId: this.startInputId, min: this.min, max: this.max, step: this.step, disabled: this.disabled, readonly: this.readonly, onInput: this.handleFieldChange, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue, name: this.name, endName: this.endName })) : null, h("div", { key: 'acea0634b80251ef76b91e85a447dcafa636924d', class: "track-container" }, h("div", { key: 'b323a5da0449af8ca8f9463bbfbceac3e9310796', class: "track", onPointerDown: this.onTrackInteraction }, this.range ? (h(RangeThumb, { rangeValue: this.rangeValueInternal, rawRangePosition: this.rawRangePosition, activeDragThumb: this.activeDragThumb, isDragging: this.isDragging, snap: this.snap, min: this.min, max: this.max, step: this.step, disabled: this.disabled, readonly: this.readonly, onKeyDown: this.onKeyDown, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue })) : (h(SingleThumb, { value: this.valueInternal, min: this.min, max: this.max, step: this.step, rawPosition: this.rawPosition, isDragging: this.isDragging, snap: this.snap, disabled: this.disabled, readonly: this.readonly, onKeyDown: this.onKeyDown, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue }))), h(TickMarks, { key: 'b3fdbe669889f22309a6f6a717f850b117a91cc8', ticks: this.internalTicks, min: this.min, max: this.max })), this.range ? (h(FieldInput, { range: this.range, hasField: this.hasField, value: this.valueInternal, rangeValue: this.rangeValueInternal, index: 1, inputId: this.endInputId, min: this.min, max: this.max, step: this.step, disabled: this.disabled, readonly: this.readonly, onInput: this.handleFieldChange, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue, name: this.name, endName: this.endName })) : (h(FieldInput, { range: this.range, hasField: this.hasField, value: this.valueInternal, rangeValue: this.rangeValueInternal, inputId: this.startInputId, min: this.min, max: this.max, step: this.step, disabled: this.disabled, readonly: this.readonly, onInput: this.handleFieldChange, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue, name: this.name }))), (this.success ||
467
+ return (h(Host, { key: '6426519f29a4a345a2371ef6ba05c6e2f59fd01f' }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: '83583c4f6610032c5ba3b2b6e0d58a1ce6117f8a', htmlFor: this.startInputId }, h("slot", { key: '91bf1a9106d9044e8180b6115510764904d39c15', name: "label" }, this.label))), h("div", { key: 'f5154fb1aa800cda282c924e2ff036df6ba70969', class: "slider-container" }, this.range ? (h(FieldInput, { range: this.range, hasField: this.hasField, value: this.valueInternal, rangeValue: this.rangeValueInternal, index: 0, inputId: this.startInputId, min: this.min, max: this.max, step: this.step, disabled: this.disabled, readonly: this.readonly, onInput: this.handleFieldChange, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue, name: this.name, endName: this.endName })) : null, h("div", { key: '3a11f56bc52e1bb2ff0fb82e14488173dffa5d48', class: "track-container" }, h("div", { key: '48065424f96d4bff452bfb122217a30767563219', class: "track", onPointerDown: this.onTrackInteraction }, this.range ? (h(RangeThumb, { rangeValue: this.rangeValueInternal, rawRangePosition: this.rawRangePosition, activeDragThumb: this.activeDragThumb, isDragging: this.isDragging, snap: this.snap, min: this.min, max: this.max, step: this.step, disabled: this.disabled, readonly: this.readonly, onKeyDown: this.onKeyDown, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue })) : (h(SingleThumb, { value: this.valueInternal, min: this.min, max: this.max, step: this.step, rawPosition: this.rawPosition, isDragging: this.isDragging, snap: this.snap, disabled: this.disabled, readonly: this.readonly, onKeyDown: this.onKeyDown, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue }))), h(TickMarks, { key: '3c03a6c0bb8e8f24d076f29c178bd71eaf9cda0e', ticks: this.internalTicks, min: this.min, max: this.max })), this.range ? (h(FieldInput, { range: this.range, hasField: this.hasField, value: this.valueInternal, rangeValue: this.rangeValueInternal, index: 1, inputId: this.endInputId, min: this.min, max: this.max, step: this.step, disabled: this.disabled, readonly: this.readonly, onInput: this.handleFieldChange, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue, name: this.name, endName: this.endName })) : (h(FieldInput, { range: this.range, hasField: this.hasField, value: this.valueInternal, rangeValue: this.rangeValueInternal, inputId: this.startInputId, min: this.min, max: this.max, step: this.step, disabled: this.disabled, readonly: this.readonly, onInput: this.handleFieldChange, labelBeforeValue: this.labelBeforeValue, labelAfterValue: this.labelAfterValue, name: this.name }))), (this.success ||
468
468
  this.description ||
469
- this.el.querySelector('[slot="description"]')) && (h("div", { key: '53b4e7236c469b87d96a666c4711b0fd9f060be9', class: "description" }, this.success && (h("nv-icon", { key: '332161c24c7aa882de0d07e0e7c4264bf5dc02b0', name: "circle-check", class: "validation", size: "md" })), h("slot", { key: 'd0ab58883e0d3d079511738835eba8a6c5caebd8', name: "description" }, this.description))), (this.error ||
469
+ this.el.querySelector('[slot="description"]')) && (h("div", { key: '7f2adaba3d758f14acc45e04636daca743264b53', class: "description" }, this.success && (h("nv-icon", { key: 'd499915841c2fb34e26af179e5fe1a592306c6ce', name: "circle-check", class: "validation", size: "md" })), h("slot", { key: 'bdd412849474b4ffaf5473005c1dad19cc9bb2ee', name: "description" }, this.description))), (this.error ||
470
470
  this.errorDescription ||
471
- this.el.querySelector('[slot="error-description"]')) && (h("div", { key: '8ead9d45a545ba2e1abad6a855e88c655bbc5254', class: "error-description", hidden: !this.error }, this.error && (h("nv-icon", { key: '09d224201d747651dcd0f0ce22d9d81a784e75eb', name: "alert-circle", class: "validation", size: "md" })), h("slot", { key: '8c8a0e621a54dcf67569ad4e6818b3a4bc0a3a19', name: "error-description" }, this.errorDescription)))));
471
+ this.el.querySelector('[slot="error-description"]')) && (h("div", { key: 'b24b65aed4437a953fba34820a3cd6c385c246b7', class: "error-description", hidden: !this.error }, this.error && (h("nv-icon", { key: '76c21755d1f90aa3f2f64f03b20a57249f5ea568', name: "alert-circle", class: "validation", size: "md" })), h("slot", { key: '59d05da46df9e86b62f65db1d7ed967bb640675a', name: "error-description" }, this.errorDescription)))));
472
472
  }
473
473
  static get is() { return "nv-fieldslider"; }
474
474
  static get formAssociated() { return true; }
@@ -148,11 +148,11 @@ export class NvFieldtext {
148
148
  ? ariaRequiredAttrValue === 'true' || ariaRequiredAttrValue === ''
149
149
  : undefined;
150
150
  const useNativeRequired = this.required && (!useAriaRequired || ariaRequiredValue === true);
151
- return (h(Host, { key: '63089724e21e6c1e216a11a2638f30fee689c82e' }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: 'c6cd68f868bd971708c5e95a5fef80de9dc6512d', htmlFor: this.inputId }, h("slot", { key: '5cf94a89c4229b78a79778ff7aade534ff72e507', name: "label" }, this.label))), h("div", { key: '28c17fd690a3a2bb0e55585d946677d8a3681a0e', class: "input-wrapper" }, h("slot", { key: 'd870c9740c1d9ba4386d963892de1e66778e1bfa', name: "before-input" }), h("div", { key: '09b3bff856699402e949ba15015c21229fafb029', class: "input-container", onClick: this.handleInputContainerClick }, h("slot", { key: '86fdcb7cad564aa79deb5007fc443b2ed5c2bcdf', name: "leading-input" }), h("input", { key: '6b11e70de402487f3bd16c3b4229313d242c905e', id: this.inputId, ref: e => (this.inputElement = e), placeholder: this.placeholder, name: this.name, type: this.type, disabled: this.disabled, readOnly: this.readonly, required: useNativeRequired ? this.required : undefined, ...(ariaRequiredValue !== undefined && {
151
+ return (h(Host, { key: '90ac165e82d023f829f92a29c96752034c23c9f2' }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: 'f530f667afb8d7ca92b08091ed56334344a143f2', htmlFor: this.inputId }, h("slot", { key: 'fc47f6054630cabc3ad1990b015aa092f4aa4340', name: "label" }, this.label))), h("div", { key: '1e391ffe7dcf66df1ca71b0bdac6b2f6e1db0bbd', class: "input-wrapper" }, h("slot", { key: '10b6c0ba26cfa5746f49b5306fa50e9621abef2c', name: "before-input" }), h("div", { key: 'b4b09153ca8604d1b3e0196468fa76cc2a8f9241', class: "input-container", onClick: this.handleInputContainerClick }, h("slot", { key: '0eeca77278eafbc0387e70e4aa2393f094ac011c', name: "leading-input" }), h("input", { key: '6fe1319ef9d8b6f6adad33c6d7aa3fda31bdcbe3', id: this.inputId, ref: e => (this.inputElement = e), placeholder: this.placeholder, name: this.name, type: this.type, disabled: this.disabled, readOnly: this.readonly, required: useNativeRequired ? this.required : undefined, ...(ariaRequiredValue !== undefined && {
152
152
  'aria-required': String(ariaRequiredValue),
153
- }), maxlength: this.maxlength, minlength: this.minlength, pattern: this.pattern, autofocus: this.autofocus, autocomplete: this.autocomplete, multiple: this.multiple, value: this.value, onInput: this.handleInput }), h("slot", { key: 'a0dc3bc46517a3457c0d3d8681a4078d23b2c2ea', name: "trailing-input" }), this.error && (h("nv-icon", { key: '240fc71f78572d94a5e4c5645f2531c58dd9762f', name: "alert-circle", class: "validation", size: "md" })), this.success && (h("nv-icon", { key: '027784ee5c9d4bc37bfab78b991afd6c462bce37', name: "circle-check", class: "validation", size: "md" }))), h("slot", { key: '4fc38f97f3b24b008589e5ba77a6d99c1dfb903d', name: "after-input" })), (this.description ||
154
- this.el.querySelector('[slot="description"]')) && (h("div", { key: '9a784d007b8b94cf426d1b9e6090e37890859dce', class: "description" }, h("slot", { key: '1269822c641095aab99334f969d57a2850568a50', name: "description" }, this.description))), (this.errorDescription ||
155
- this.el.querySelector('[slot="error-description"]')) && (h("div", { key: 'e5b3bb57e05350d65af0a333936cd8a0e91c42c2', hidden: !this.error, class: "error-description" }, h("slot", { key: '70a6d5cbe96d13deb808b3bbed64bb4e935636fa', name: "error-description" }, this.errorDescription)))));
153
+ }), maxlength: this.maxlength, minlength: this.minlength, pattern: this.pattern, autofocus: this.autofocus, autocomplete: this.autocomplete, multiple: this.multiple, value: this.value, onInput: this.handleInput }), h("slot", { key: '8371a6e3dda9c4d61a99246e675826c44b102f85', name: "trailing-input" }), this.error && (h("nv-icon", { key: 'a36ff6b50c314255cb0ff141d199da1da14c0d4e', name: "alert-circle", class: "validation", size: "md" })), this.success && (h("nv-icon", { key: 'b51a8059483bbc78d383b7cf71b5a90bfd2633a4', name: "circle-check", class: "validation", size: "md" }))), h("slot", { key: '6b7eb32b47c9b74e6a567a359617668e7256efcb', name: "after-input" })), (this.description ||
154
+ this.el.querySelector('[slot="description"]')) && (h("div", { key: 'ce97f38d7d31b18df36a92d75cd4dd7dd44063ab', class: "description" }, h("slot", { key: '92cc67f9b9c277e91316236c977e1bc9bd63a0c7', name: "description" }, this.description))), (this.errorDescription ||
155
+ this.el.querySelector('[slot="error-description"]')) && (h("div", { key: '44711fb351ac1da5da1a0f0630a1d7596957664d', hidden: !this.error, class: "error-description" }, h("slot", { key: '4645cc36a7383587f6baa8db0bb2b664f252768c', name: "error-description" }, this.errorDescription)))));
156
156
  }
157
157
  static get is() { return "nv-fieldtext"; }
158
158
  static get formAssociated() { return true; }
@@ -215,11 +215,11 @@ export class NvFieldtextarea {
215
215
  ? ariaRequiredAttrValue === 'true' || ariaRequiredAttrValue === ''
216
216
  : undefined;
217
217
  const useNativeRequired = this.required && (!useAriaRequired || ariaRequiredValue === true);
218
- return (h(Host, { key: '8d31a9e4c294a58a02040dddb427c94caecf4d2e' }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: '4352374d8078448ce5f877d20b526a6725219f76', htmlFor: this.inputId }, h("slot", { key: '1f5dca95213c848f105fe8d4aec5e7a363cfd468', name: "label" }, this.label))), h("div", { key: '831c87ed454b2b7a6dfc84daf903c6bc3e7581f4', class: "textarea-wrapper" }, h("div", { key: '1a3dd73ca1a4f650f02309211154e3fcee02824c', class: "textarea-container", onClick: this.handleTextareaContainerClick }, h("textarea", { key: '97454b0c1845a4ed8f1e2f99285f363affff7c7c', id: this.inputId, ref: e => (this.textareaElement = e), placeholder: this.placeholder, autofocus: this.autofocus, name: this.name, disabled: this.disabled, readOnly: this.readonly, required: useNativeRequired ? this.required : undefined, ...(ariaRequiredValue !== undefined && {
218
+ return (h(Host, { key: '1cddc37522161a4316ae8f82d3daf285ffb785b5' }, (this.label || this.el.querySelector('[slot="label"]')) && (h("label", { key: '0c351922af13d881f90b17cea5d482fd45a34e65', htmlFor: this.inputId }, h("slot", { key: '665bee53de0fd1a1f076ecfcba06be68919881e0', name: "label" }, this.label))), h("div", { key: '22fc452a7657ea9b13a867d57b4242268dde2bca', class: "textarea-wrapper" }, h("div", { key: '333aace09346fae421a7a6654b1f6024fa0f87f7', class: "textarea-container", onClick: this.handleTextareaContainerClick }, h("textarea", { key: '69172853551f5cbb2fc739a13fa5299142b191c1', id: this.inputId, ref: e => (this.textareaElement = e), placeholder: this.placeholder, autofocus: this.autofocus, name: this.name, disabled: this.disabled, readOnly: this.readonly, required: useNativeRequired ? this.required : undefined, ...(ariaRequiredValue !== undefined && {
219
219
  'aria-required': String(ariaRequiredValue),
220
220
  }), maxlength: this.maxlength, minlength: this.minlength, autocomplete: "off", value: this.value, onInput: this.handleTextarea, rows: this.rows, class: clsx(this.resize === 'none' && 'resize-none', this.resize === 'vertical' && 'resize-y', this.resize === 'horizontal' && 'resize-x', this.resize === 'both' && 'resize') }))), (this.description ||
221
- this.el.querySelector('[slot="description"]')) && (h("div", { key: 'd70c40f382d8d8a369e1ce584e4c050e6f6704b4', class: "description" }, h("slot", { key: '2287c2a52e18557f104ff6b2ceab876c41f7d666', name: "description" }, this.description))), (this.errorDescription ||
222
- this.el.querySelector('[slot="error-description"]')) && (h("div", { key: '3bc7bdb991381398ff622c10929848d4f6527533', hidden: !this.error, class: "error-description" }, h("slot", { key: '061f5fba67f18750f50090a78f53a5229e384343', name: "error-description" }, this.errorDescription)))));
221
+ this.el.querySelector('[slot="description"]')) && (h("div", { key: '91fc165e6275f96547eea666d643f9bd5184d06f', class: "description" }, h("slot", { key: '996a87505c112d9cb5c1a6d7877e6bc88ab14556', name: "description" }, this.description))), (this.errorDescription ||
222
+ this.el.querySelector('[slot="error-description"]')) && (h("div", { key: '3d105e76819ca671aa6c23722344ba9acfe90f38', hidden: !this.error, class: "error-description" }, h("slot", { key: '7d721e77b392dbb0bdcf6892f4237f0d8d944c64', name: "error-description" }, this.errorDescription)))));
223
223
  }
224
224
  static get is() { return "nv-fieldtextarea"; }
225
225
  static get formAssociated() { return true; }