@nordhealth/components 4.26.2 → 5.0.0-alpha.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 (545) hide show
  1. package/custom-elements.json +53898 -21499
  2. package/lib/Accordion.js +2 -0
  3. package/lib/Accordion.js.map +1 -0
  4. package/lib/AccordionHeader.js +2 -0
  5. package/lib/AccordionHeader.js.map +1 -0
  6. package/lib/AccordionItem.js +2 -0
  7. package/lib/AccordionItem.js.map +1 -0
  8. package/lib/AccordionPanel.js +2 -0
  9. package/lib/AccordionPanel.js.map +1 -0
  10. package/lib/AccordionTrigger.js +2 -0
  11. package/lib/AccordionTrigger.js.map +1 -0
  12. package/lib/ActiveDescendantController-BnMqM79O.js +2 -0
  13. package/lib/ActiveDescendantController-BnMqM79O.js.map +1 -0
  14. package/lib/Aside.js +5 -7
  15. package/lib/Aside.js.map +1 -1
  16. package/lib/AsideDrawer.js +7 -11
  17. package/lib/AsideDrawer.js.map +1 -1
  18. package/lib/AsideTrigger.js +3 -4
  19. package/lib/AsideTrigger.js.map +1 -1
  20. package/lib/Autocomplete.js +2 -0
  21. package/lib/Autocomplete.js.map +1 -0
  22. package/lib/Avatar.js +1 -1
  23. package/lib/Avatar.js.map +1 -1
  24. package/lib/Badge.js +1 -1
  25. package/lib/Badge.js.map +1 -1
  26. package/lib/Banner.js +1 -1
  27. package/lib/Banner.js.map +1 -1
  28. package/lib/Button.js +7 -12
  29. package/lib/Button.js.map +1 -1
  30. package/lib/ButtonGroup.js +1 -1
  31. package/lib/ButtonGroup.js.map +1 -1
  32. package/lib/Calendar-C1SxrlzN.js +2 -0
  33. package/lib/Calendar-C1SxrlzN.js.map +1 -0
  34. package/lib/Calendar.js +1 -1
  35. package/lib/Card.js +1 -1
  36. package/lib/Card.js.map +1 -1
  37. package/lib/Checkbox.js +1 -1
  38. package/lib/Checkbox.js.map +1 -1
  39. package/lib/CollapseController-BtKNFNyJ.js +2 -0
  40. package/lib/CollapseController-BtKNFNyJ.js.map +1 -0
  41. package/lib/Collapsible.js +2 -0
  42. package/lib/Collapsible.js.map +1 -0
  43. package/lib/CollapsiblePanel.js +2 -0
  44. package/lib/CollapsiblePanel.js.map +1 -0
  45. package/lib/CollapsibleTrigger.js +2 -0
  46. package/lib/CollapsibleTrigger.js.map +1 -0
  47. package/lib/Combobox-By4h1Sp-.js +2 -0
  48. package/lib/Combobox-By4h1Sp-.js.map +1 -0
  49. package/lib/Combobox.js +2 -0
  50. package/lib/Combobox.js.map +1 -0
  51. package/lib/ComboboxBase.js +2 -0
  52. package/lib/ComboboxBase.js.map +1 -0
  53. package/lib/ComboboxEvents.js +2 -0
  54. package/lib/ComboboxEvents.js.map +1 -0
  55. package/lib/ComboboxGroup.js +2 -0
  56. package/lib/ComboboxGroup.js.map +1 -0
  57. package/lib/ComboboxOption.js +2 -0
  58. package/lib/ComboboxOption.js.map +1 -0
  59. package/lib/CommandMenu.js +1 -1
  60. package/lib/CommandMenu.js.map +1 -1
  61. package/lib/CommandMenuAction.js +1 -1
  62. package/lib/CommandMenuAction.js.map +1 -1
  63. package/lib/Component-BJ5O5n8k.js +2 -0
  64. package/lib/Component-BJ5O5n8k.js.map +1 -0
  65. package/lib/DatePicker.js +1 -1
  66. package/lib/DatePicker.js.map +1 -1
  67. package/lib/DateRangeChangeEvent.js +2 -0
  68. package/lib/DateRangeChangeEvent.js.map +1 -0
  69. package/lib/DateRangePicker.js +2 -0
  70. package/lib/DateRangePicker.js.map +1 -0
  71. package/lib/DateRangeSelectEvent.js +2 -0
  72. package/lib/DateRangeSelectEvent.js.map +1 -0
  73. package/lib/Divider.js +1 -1
  74. package/lib/Divider.js.map +1 -1
  75. package/lib/DraftComponentMixin-4qug5Rky.js +2 -0
  76. package/lib/DraftComponentMixin-4qug5Rky.js.map +1 -0
  77. package/lib/Drawer.js +1 -1
  78. package/lib/Drawer.js.map +1 -1
  79. package/lib/Dropdown.js +1 -1
  80. package/lib/Dropdown.js.map +1 -1
  81. package/lib/DropdownGroup.js +1 -1
  82. package/lib/DropdownGroup.js.map +1 -1
  83. package/lib/DropdownItem-BYbOLth6.js +2 -0
  84. package/lib/DropdownItem-BYbOLth6.js.map +1 -0
  85. package/lib/DropdownItem.js +1 -1
  86. package/lib/DropdownItem.js.map +1 -1
  87. package/lib/DropdownSubmenu.js +1 -1
  88. package/lib/DropdownSubmenu.js.map +1 -1
  89. package/lib/EmptyState.js +1 -1
  90. package/lib/EmptyState.js.map +1 -1
  91. package/lib/Field.js +2 -0
  92. package/lib/Field.js.map +1 -0
  93. package/lib/FieldContent.js +2 -0
  94. package/lib/FieldContent.js.map +1 -0
  95. package/lib/FieldControlMixin-BXNZJXu9.js +2 -0
  96. package/lib/FieldControlMixin-BXNZJXu9.js.map +1 -0
  97. package/lib/FieldDescription.js +2 -0
  98. package/lib/FieldDescription.js.map +1 -0
  99. package/lib/FieldError.js +2 -0
  100. package/lib/FieldError.js.map +1 -0
  101. package/lib/FieldGroup.js +2 -0
  102. package/lib/FieldGroup.js.map +1 -0
  103. package/lib/FieldLabel.js +2 -0
  104. package/lib/FieldLabel.js.map +1 -0
  105. package/lib/FieldLegend.js +2 -0
  106. package/lib/FieldLegend.js.map +1 -0
  107. package/lib/FieldSeparator.js +2 -0
  108. package/lib/FieldSeparator.js.map +1 -0
  109. package/lib/FieldSet.js +2 -0
  110. package/lib/FieldSet.js.map +1 -0
  111. package/lib/FieldTitle.js +2 -0
  112. package/lib/FieldTitle.js.map +1 -0
  113. package/lib/Fieldset2.js +2 -0
  114. package/lib/Fieldset2.js.map +1 -0
  115. package/lib/FilterAddButton.js +2 -0
  116. package/lib/FilterAddButton.js.map +1 -0
  117. package/lib/FilterAddButtonEvents.js +2 -0
  118. package/lib/FilterAddButtonEvents.js.map +1 -0
  119. package/lib/FilterBar.js +2 -0
  120. package/lib/FilterBar.js.map +1 -0
  121. package/lib/FilterDateRange.js +2 -0
  122. package/lib/FilterDateRange.js.map +1 -0
  123. package/lib/FilterDateRangeEvents.js +2 -0
  124. package/lib/FilterDateRangeEvents.js.map +1 -0
  125. package/lib/FilterDropdown.js +2 -0
  126. package/lib/FilterDropdown.js.map +1 -0
  127. package/lib/FilterDropdownEvents.js +2 -0
  128. package/lib/FilterDropdownEvents.js.map +1 -0
  129. package/lib/FilterField.js +2 -0
  130. package/lib/FilterField.js.map +1 -0
  131. package/lib/FilterFieldEvents.js +2 -0
  132. package/lib/FilterFieldEvents.js.map +1 -0
  133. package/lib/FilterInput.js +2 -0
  134. package/lib/FilterInput.js.map +1 -0
  135. package/lib/FilterResetButton.js +2 -0
  136. package/lib/FilterResetButton.js.map +1 -0
  137. package/lib/FocusableWhenDisabledController-C_Mn1mfN.js +2 -0
  138. package/lib/FocusableWhenDisabledController-C_Mn1mfN.js.map +1 -0
  139. package/lib/Footer.js +1 -1
  140. package/lib/Footer.js.map +1 -1
  141. package/lib/FormAssociatedMixin-D9aPREgv.js +2 -0
  142. package/lib/FormAssociatedMixin-D9aPREgv.js.map +1 -0
  143. package/lib/FormField-CMgEFZCK.js +2 -0
  144. package/lib/FormField-CMgEFZCK.js.map +1 -0
  145. package/lib/Header.js +1 -1
  146. package/lib/Header.js.map +1 -1
  147. package/lib/Icon.js +1 -1
  148. package/lib/Icon.js.map +1 -1
  149. package/lib/Input.js +1 -1
  150. package/lib/Input.js.map +1 -1
  151. package/lib/Item.js +2 -0
  152. package/lib/Item.js.map +1 -0
  153. package/lib/ItemActions.js +2 -0
  154. package/lib/ItemActions.js.map +1 -0
  155. package/lib/ItemContent.js +2 -0
  156. package/lib/ItemContent.js.map +1 -0
  157. package/lib/ItemDescription.js +2 -0
  158. package/lib/ItemDescription.js.map +1 -0
  159. package/lib/ItemFooter.js +2 -0
  160. package/lib/ItemFooter.js.map +1 -0
  161. package/lib/ItemGroup.js +2 -0
  162. package/lib/ItemGroup.js.map +1 -0
  163. package/lib/ItemHeader.js +2 -0
  164. package/lib/ItemHeader.js.map +1 -0
  165. package/lib/ItemMedia.js +2 -0
  166. package/lib/ItemMedia.js.map +1 -0
  167. package/lib/ItemSeparator.js +2 -0
  168. package/lib/ItemSeparator.js.map +1 -0
  169. package/lib/ItemTitle.js +2 -0
  170. package/lib/ItemTitle.js.map +1 -0
  171. package/lib/Kbd.js +2 -0
  172. package/lib/Kbd.js.map +1 -0
  173. package/lib/KbdGroup.js +2 -0
  174. package/lib/KbdGroup.js.map +1 -0
  175. package/lib/Layout.js +1 -3
  176. package/lib/Layout.js.map +1 -1
  177. package/lib/LocalizeController.js +1 -1
  178. package/lib/LocalizeController.js.map +1 -1
  179. package/lib/Message.js +1 -1
  180. package/lib/Message.js.map +1 -1
  181. package/lib/Meter.js +2 -0
  182. package/lib/Meter.js.map +1 -0
  183. package/lib/Modal.js +1 -1
  184. package/lib/Modal.js.map +1 -1
  185. package/lib/ModalController.js +1 -1
  186. package/lib/ModalController.js.map +1 -1
  187. package/lib/NavGroup.js +1 -1
  188. package/lib/NavGroup.js.map +1 -1
  189. package/lib/NavItem.js +1 -1
  190. package/lib/NavItem.js.map +1 -1
  191. package/lib/NavToggle-BY83xpx0.js +2 -0
  192. package/lib/NavToggle-BY83xpx0.js.map +1 -0
  193. package/lib/NavToggle.js +1 -1
  194. package/lib/Navigation.js +1 -1
  195. package/lib/Navigation.js.map +1 -1
  196. package/lib/Notification.js +1 -1
  197. package/lib/Notification.js.map +1 -1
  198. package/lib/NotificationGroup.js +1 -1
  199. package/lib/NotificationGroup.js.map +1 -1
  200. package/lib/NumberField.js +2 -0
  201. package/lib/NumberField.js.map +1 -0
  202. package/lib/NumberFieldEvents.js +2 -0
  203. package/lib/NumberFieldEvents.js.map +1 -0
  204. package/lib/OpenStateController-CCnZ7up6.js +2 -0
  205. package/lib/OpenStateController-CCnZ7up6.js.map +1 -0
  206. package/lib/OtpField.js +2 -0
  207. package/lib/OtpField.js.map +1 -0
  208. package/lib/OtpFieldEvents.js +2 -0
  209. package/lib/OtpFieldEvents.js.map +1 -0
  210. package/lib/Pagination.js +2 -0
  211. package/lib/Pagination.js.map +1 -0
  212. package/lib/PaginationContent.js +2 -0
  213. package/lib/PaginationContent.js.map +1 -0
  214. package/lib/PaginationEllipsis.js +2 -0
  215. package/lib/PaginationEllipsis.js.map +1 -0
  216. package/lib/PaginationItem.js +2 -0
  217. package/lib/PaginationItem.js.map +1 -0
  218. package/lib/PaginationLink.js +2 -0
  219. package/lib/PaginationLink.js.map +1 -0
  220. package/lib/PaginationNext.js +2 -0
  221. package/lib/PaginationNext.js.map +1 -0
  222. package/lib/PaginationPrevious.js +2 -0
  223. package/lib/PaginationPrevious.js.map +1 -0
  224. package/lib/Popout-DpN7PP9h.js +2 -0
  225. package/lib/Popout-DpN7PP9h.js.map +1 -0
  226. package/lib/Popout.js +1 -1
  227. package/lib/Progress.js +1 -1
  228. package/lib/Progress.js.map +1 -1
  229. package/lib/ProgressBar.js +1 -1
  230. package/lib/ProgressBar.js.map +1 -1
  231. package/lib/Qrcode.js +2 -2
  232. package/lib/Radio.js +1 -1
  233. package/lib/Radio.js.map +1 -1
  234. package/lib/Range.js +1 -1
  235. package/lib/Range.js.map +1 -1
  236. package/lib/ReadonlyMixin-BdJPGtQ3.js +2 -0
  237. package/lib/ReadonlyMixin-BdJPGtQ3.js.map +1 -0
  238. package/lib/ResizeController-14PUwRQy.js +2 -0
  239. package/lib/ResizeController-14PUwRQy.js.map +1 -0
  240. package/lib/ScrollArea.js +2 -0
  241. package/lib/ScrollArea.js.map +1 -0
  242. package/lib/SegmentedControl.js +1 -1
  243. package/lib/SegmentedControl.js.map +1 -1
  244. package/lib/SegmentedControlItem.js +23 -40
  245. package/lib/SegmentedControlItem.js.map +1 -1
  246. package/lib/Select.js +1 -1
  247. package/lib/Select.js.map +1 -1
  248. package/lib/Skeleton.js +1 -1
  249. package/lib/Skeleton.js.map +1 -1
  250. package/lib/Spinner.js +1 -1
  251. package/lib/Spinner.js.map +1 -1
  252. package/lib/Stack.js +1 -1
  253. package/lib/Stack.js.map +1 -1
  254. package/lib/StateAttributesController-BIh96sXZ.js +2 -0
  255. package/lib/StateAttributesController-BIh96sXZ.js.map +1 -0
  256. package/lib/Sticky-CZImMrGj.js +2 -0
  257. package/lib/Sticky-CZImMrGj.js.map +1 -0
  258. package/lib/Tab.js +1 -1
  259. package/lib/Tab.js.map +1 -1
  260. package/lib/TabGroup.js +1 -1
  261. package/lib/TabGroup.js.map +1 -1
  262. package/lib/TabPanel.js +1 -1
  263. package/lib/TabPanel.js.map +1 -1
  264. package/lib/Table.js +1 -1
  265. package/lib/Table.js.map +1 -1
  266. package/lib/Tag.js +1 -1
  267. package/lib/Tag.js.map +1 -1
  268. package/lib/TagGroup.js +1 -1
  269. package/lib/TagGroup.js.map +1 -1
  270. package/lib/TextField-CSKvieoG.js +2 -0
  271. package/lib/TextField-CSKvieoG.js.map +1 -0
  272. package/lib/TextSelectableMixin-Cfv__lHS.js.map +1 -1
  273. package/lib/Textarea.js +1 -1
  274. package/lib/Textarea.js.map +1 -1
  275. package/lib/TimePicker.js +2 -0
  276. package/lib/TimePicker.js.map +1 -0
  277. package/lib/Toast.js +1 -1
  278. package/lib/Toast.js.map +1 -1
  279. package/lib/ToastGroup.js +1 -1
  280. package/lib/ToastGroup.js.map +1 -1
  281. package/lib/Toggle.js +1 -1
  282. package/lib/Toggle.js.map +1 -1
  283. package/lib/Tooltip.js +1 -1
  284. package/lib/Tooltip.js.map +1 -1
  285. package/lib/TopBar.js +1 -1
  286. package/lib/TopBar.js.map +1 -1
  287. package/lib/Truncate.js +1 -1
  288. package/lib/Truncate.js.map +1 -1
  289. package/lib/VisuallyHidden.js +1 -1
  290. package/lib/bundle.js +91 -91
  291. package/lib/bundle.js.map +1 -1
  292. package/lib/combobox-context.js +2 -0
  293. package/lib/combobox-context.js.map +1 -0
  294. package/lib/context-consumer-BJVUulGf.js +7 -0
  295. package/lib/context-consumer-BJVUulGf.js.map +1 -0
  296. package/lib/context-provider-D8lrPLVi.js +12 -0
  297. package/lib/context-provider-D8lrPLVi.js.map +1 -0
  298. package/lib/context-request-event-CCRlXoeR.js +7 -0
  299. package/lib/context-request-event-CCRlXoeR.js.map +1 -0
  300. package/lib/create-context-CJ69ntlY.js +7 -0
  301. package/lib/create-context-CJ69ntlY.js.map +1 -0
  302. package/lib/currency.js +2 -0
  303. package/lib/currency.js.map +1 -0
  304. package/lib/date-adapter.js +1 -1
  305. package/lib/dates-C-ZvzXaC.js +2 -0
  306. package/lib/dates-C-ZvzXaC.js.map +1 -0
  307. package/lib/dates.js +2 -0
  308. package/lib/dates.js.map +1 -0
  309. package/lib/dismiss.js +2 -0
  310. package/lib/dismiss.js.map +1 -0
  311. package/lib/en-us.js +1 -1
  312. package/lib/en-us.js.map +1 -1
  313. package/lib/fi-fi.js +1 -1
  314. package/lib/fi-fi.js.map +1 -1
  315. package/lib/field-context.js +2 -0
  316. package/lib/field-context.js.map +1 -0
  317. package/lib/filter-chip-C97zd4PT.js +2 -0
  318. package/lib/filter-chip-C97zd4PT.js.map +1 -0
  319. package/lib/format.js +2 -0
  320. package/lib/format.js.map +1 -0
  321. package/lib/index.js +1 -1
  322. package/lib/interface-add-small-B-hv2v9J.js +2 -0
  323. package/lib/interface-add-small-B-hv2v9J.js.map +1 -0
  324. package/lib/interface-calendar-Cw2bJfbS.js +2 -0
  325. package/lib/interface-calendar-Cw2bJfbS.js.map +1 -0
  326. package/lib/interface-close-BvKnv9eh.js +2 -0
  327. package/lib/interface-close-BvKnv9eh.js.map +1 -0
  328. package/lib/interface-dropdown-small-CYvgxudU.js +2 -0
  329. package/lib/interface-dropdown-small-CYvgxudU.js.map +1 -0
  330. package/lib/interface-filter-CCsx9-u6.js +2 -0
  331. package/lib/interface-filter-CCsx9-u6.js.map +1 -0
  332. package/lib/interface-remove-small-DUaWSs90.js +2 -0
  333. package/lib/interface-remove-small-DUaWSs90.js.map +1 -0
  334. package/lib/light-dom-styles-DXsbiKU9.js +2 -0
  335. package/lib/light-dom-styles-DXsbiKU9.js.map +1 -0
  336. package/lib/localization.js +1 -1
  337. package/lib/localization.js.map +1 -1
  338. package/lib/localization10.js +2 -0
  339. package/lib/localization10.js.map +1 -0
  340. package/lib/localization11.js +2 -0
  341. package/lib/localization11.js.map +1 -0
  342. package/lib/localization12.js +2 -0
  343. package/lib/localization12.js.map +1 -0
  344. package/lib/localization13.js +2 -0
  345. package/lib/localization13.js.map +1 -0
  346. package/lib/localization14.js +2 -0
  347. package/lib/localization14.js.map +1 -0
  348. package/lib/localization15.js +2 -0
  349. package/lib/localization15.js.map +1 -0
  350. package/lib/localization16.js +2 -0
  351. package/lib/localization16.js.map +1 -0
  352. package/lib/localization17.js +2 -0
  353. package/lib/localization17.js.map +1 -0
  354. package/lib/localization18.js +2 -0
  355. package/lib/localization18.js.map +1 -0
  356. package/lib/localization19.js +2 -0
  357. package/lib/localization19.js.map +1 -0
  358. package/lib/localization2.js +1 -1
  359. package/lib/localization2.js.map +1 -1
  360. package/lib/localization20.js +2 -0
  361. package/lib/localization20.js.map +1 -0
  362. package/lib/localization21.js +2 -0
  363. package/lib/localization21.js.map +1 -0
  364. package/lib/localization22.js +2 -0
  365. package/lib/localization22.js.map +1 -0
  366. package/lib/localization3.js +1 -1
  367. package/lib/localization3.js.map +1 -1
  368. package/lib/localization4.js +1 -1
  369. package/lib/localization4.js.map +1 -1
  370. package/lib/localization5.js +1 -1
  371. package/lib/localization5.js.map +1 -1
  372. package/lib/localization6.js +1 -1
  373. package/lib/localization6.js.map +1 -1
  374. package/lib/localization7.js +1 -1
  375. package/lib/localization7.js.map +1 -1
  376. package/lib/localization8.js +1 -1
  377. package/lib/localization8.js.map +1 -1
  378. package/lib/localization9.js +1 -1
  379. package/lib/localization9.js.map +1 -1
  380. package/lib/navigation-search-CBbIGzo2.js +2 -0
  381. package/lib/navigation-search-CBbIGzo2.js.map +1 -0
  382. package/lib/paginate.js +2 -0
  383. package/lib/paginate.js.map +1 -0
  384. package/lib/parse.js +2 -0
  385. package/lib/parse.js.map +1 -0
  386. package/lib/primitives-Dj0vyf1-.js +2 -0
  387. package/lib/primitives-Dj0vyf1-.js.map +1 -0
  388. package/lib/react.d.ts +505 -0
  389. package/lib/src/accordion/Accordion.d.ts +121 -0
  390. package/lib/src/accordion/AccordionHeader.d.ts +28 -0
  391. package/lib/src/accordion/AccordionItem.d.ts +68 -0
  392. package/lib/src/accordion/AccordionPanel.d.ts +35 -0
  393. package/lib/src/accordion/AccordionTrigger.d.ts +47 -0
  394. package/lib/src/aside-drawer/AsideDrawer.d.ts +2 -0
  395. package/lib/src/aside-trigger/AsideTrigger.d.ts +2 -0
  396. package/lib/src/autocomplete/Autocomplete.d.ts +190 -0
  397. package/lib/src/autocomplete/localization.d.ts +5 -0
  398. package/lib/src/badge/Badge.d.ts +1 -1
  399. package/lib/src/banner/Banner.d.ts +3 -0
  400. package/lib/src/button-group/ButtonGroup.d.ts +1 -1
  401. package/lib/src/calendar/Calendar.d.ts +44 -0
  402. package/lib/src/calendar/DateRangeSelectEvent.d.ts +16 -0
  403. package/lib/src/collapsible/Collapsible.d.ts +69 -0
  404. package/lib/src/collapsible/CollapsiblePanel.d.ts +35 -0
  405. package/lib/src/collapsible/CollapsibleTrigger.d.ts +38 -0
  406. package/lib/src/combobox/Combobox.d.ts +131 -0
  407. package/lib/src/combobox/ComboboxBase.d.ts +421 -0
  408. package/lib/src/combobox/ComboboxEvents.d.ts +25 -0
  409. package/lib/src/combobox/ComboboxGroup.d.ts +34 -0
  410. package/lib/src/combobox/ComboboxOption.d.ts +47 -0
  411. package/lib/src/combobox/combobox-context.d.ts +18 -0
  412. package/lib/src/combobox/localization.d.ts +6 -0
  413. package/lib/src/common/controllers/ActiveDescendantController.d.ts +45 -0
  414. package/lib/src/common/controllers/CollapseController.d.ts +50 -0
  415. package/lib/src/common/controllers/FocusableWhenDisabledController.d.ts +29 -0
  416. package/lib/src/common/controllers/OpenStateController.d.ts +58 -0
  417. package/lib/src/common/controllers/RovingFocusController.d.ts +40 -0
  418. package/lib/src/common/controllers/StateAttributesController.d.ts +47 -0
  419. package/lib/src/common/controllers/TransitionStatusController.d.ts +48 -0
  420. package/lib/src/common/dates.d.ts +13 -0
  421. package/lib/src/common/light-dom-styles.d.ts +17 -0
  422. package/lib/src/common/mixins/FieldControlMixin.d.ts +60 -0
  423. package/lib/src/common/mixins/FormAssociatedMixin.d.ts +8 -25
  424. package/lib/src/common/mixins/TextSelectableMixin.d.ts +1 -0
  425. package/lib/src/common/prefers-reduced-motion.d.ts +7 -0
  426. package/lib/src/date-picker/DatePicker.d.ts +2 -0
  427. package/lib/src/date-range-picker/DateRangeChangeEvent.d.ts +27 -0
  428. package/lib/src/date-range-picker/DateRangePicker.d.ts +307 -0
  429. package/lib/src/date-range-picker/localization.d.ts +42 -0
  430. package/lib/src/dropdown/Dropdown.d.ts +1 -1
  431. package/lib/src/dropdown-group/DropdownGroup.d.ts +3 -1
  432. package/lib/src/dropdown-item/DropdownItem.d.ts +3 -1
  433. package/lib/src/dropdown-submenu/DropdownSubmenu.d.ts +2 -0
  434. package/lib/src/field/Field.d.ts +102 -0
  435. package/lib/src/field/FieldContent.d.ts +22 -0
  436. package/lib/src/field/FieldDescription.d.ts +21 -0
  437. package/lib/src/field/FieldError.d.ts +25 -0
  438. package/lib/src/field/FieldGroup.d.ts +25 -0
  439. package/lib/src/field/FieldLabel.d.ts +41 -0
  440. package/lib/src/field/FieldLegend.d.ts +20 -0
  441. package/lib/src/field/FieldSeparator.d.ts +21 -0
  442. package/lib/src/field/FieldSet.d.ts +28 -0
  443. package/lib/src/field/FieldTitle.d.ts +21 -0
  444. package/lib/src/field/field-context.d.ts +47 -0
  445. package/lib/src/fieldset/Fieldset.d.ts +12 -4
  446. package/lib/src/filter-add-button/FilterAddButton.d.ts +91 -0
  447. package/lib/src/filter-add-button/FilterAddButtonEvents.d.ts +17 -0
  448. package/lib/src/filter-add-button/localization.d.ts +4 -0
  449. package/lib/src/filter-bar/FilterBar.d.ts +37 -0
  450. package/lib/src/filter-date-range/FilterDateRange.d.ts +96 -0
  451. package/lib/src/filter-date-range/FilterDateRangeEvents.d.ts +37 -0
  452. package/lib/src/filter-date-range/localization.d.ts +11 -0
  453. package/lib/src/filter-dropdown/FilterDropdown.d.ts +247 -0
  454. package/lib/src/filter-dropdown/FilterDropdownEvents.d.ts +57 -0
  455. package/lib/src/filter-dropdown/localization.d.ts +14 -0
  456. package/lib/src/filter-field/FilterField.d.ts +89 -0
  457. package/lib/src/filter-field/FilterFieldEvents.d.ts +18 -0
  458. package/lib/src/filter-field/localization.d.ts +8 -0
  459. package/lib/src/filter-input/FilterInput.d.ts +102 -0
  460. package/lib/src/filter-input/localization.d.ts +5 -0
  461. package/lib/src/filter-reset-button/FilterResetButton.d.ts +50 -0
  462. package/lib/src/filter-reset-button/localization.d.ts +4 -0
  463. package/lib/src/index.d.ts +59 -0
  464. package/lib/src/input/Input.d.ts +2 -1
  465. package/lib/src/item/Item.d.ts +44 -0
  466. package/lib/src/item/ItemActions.d.ts +20 -0
  467. package/lib/src/item/ItemContent.d.ts +22 -0
  468. package/lib/src/item/ItemDescription.d.ts +20 -0
  469. package/lib/src/item/ItemFooter.d.ts +20 -0
  470. package/lib/src/item/ItemGroup.d.ts +22 -0
  471. package/lib/src/item/ItemHeader.d.ts +20 -0
  472. package/lib/src/item/ItemMedia.d.ts +28 -0
  473. package/lib/src/item/ItemSeparator.d.ts +21 -0
  474. package/lib/src/item/ItemTitle.d.ts +19 -0
  475. package/lib/src/kbd/Kbd.d.ts +54 -0
  476. package/lib/src/kbd/KbdGroup.d.ts +22 -0
  477. package/lib/src/layout/Layout.d.ts +2 -2
  478. package/lib/src/localization/en-us.d.ts +85 -0
  479. package/lib/src/localization/translation.d.ts +85 -0
  480. package/lib/src/meter/Meter.d.ts +76 -0
  481. package/lib/src/nav-group/NavGroup.d.ts +2 -0
  482. package/lib/src/nav-item/NavItem.d.ts +2 -0
  483. package/lib/src/nav-toggle/NavToggle.d.ts +3 -1
  484. package/lib/src/notification-group/NotificationGroup.d.ts +2 -0
  485. package/lib/src/number-field/NumberField.d.ts +377 -0
  486. package/lib/src/number-field/NumberFieldEvents.d.ts +37 -0
  487. package/lib/src/number-field/currency.d.ts +24 -0
  488. package/lib/src/number-field/format.d.ts +8 -0
  489. package/lib/src/number-field/localization.d.ts +6 -0
  490. package/lib/src/number-field/parse.d.ts +44 -0
  491. package/lib/src/number-field/validate.d.ts +24 -0
  492. package/lib/src/otp-field/OtpField.d.ts +177 -0
  493. package/lib/src/otp-field/OtpFieldEvents.d.ts +38 -0
  494. package/lib/src/otp-field/localization.d.ts +4 -0
  495. package/lib/src/pagination/Pagination.d.ts +51 -0
  496. package/lib/src/pagination/PaginationContent.d.ts +27 -0
  497. package/lib/src/pagination/PaginationEllipsis.d.ts +27 -0
  498. package/lib/src/pagination/PaginationItem.d.ts +24 -0
  499. package/lib/src/pagination/PaginationLink.d.ts +30 -0
  500. package/lib/src/pagination/PaginationNext.d.ts +24 -0
  501. package/lib/src/pagination/PaginationPrevious.d.ts +24 -0
  502. package/lib/src/pagination/localization.d.ts +4 -0
  503. package/lib/src/pagination/paginate.d.ts +20 -0
  504. package/lib/src/popout/Popout.d.ts +9 -0
  505. package/lib/src/scroll-area/ScrollArea.d.ts +101 -0
  506. package/lib/src/segmented-control-item/SegmentedControlItem.d.ts +2 -0
  507. package/lib/src/storybook-utils/dates.d.ts +2 -0
  508. package/lib/src/storybook-utils/dismiss.d.ts +1 -0
  509. package/lib/src/storybook-utils/story-descriptions.d.ts +2 -0
  510. package/lib/src/tab-group/TabGroup.d.ts +2 -0
  511. package/lib/src/tab-panel/TabPanel.d.ts +2 -0
  512. package/lib/src/tag-group/TagGroup.d.ts +2 -0
  513. package/lib/src/time-picker/TimePicker.d.ts +105 -0
  514. package/lib/src/time-picker/localization.d.ts +4 -0
  515. package/lib/src/toast-group/ToastGroup.d.ts +11 -0
  516. package/lib/story-descriptions.js +2 -0
  517. package/lib/story-descriptions.js.map +1 -0
  518. package/lib/translation.js +1 -1
  519. package/lib/translation.js.map +1 -1
  520. package/lib/validate.js +2 -0
  521. package/lib/validate.js.map +1 -0
  522. package/lib/vue.d.ts +407 -0
  523. package/package.json +9 -12
  524. package/lib/Calendar-ChNZdVRO.js +0 -2
  525. package/lib/Calendar-ChNZdVRO.js.map +0 -1
  526. package/lib/Component-DSU3Qp0O.js +0 -2
  527. package/lib/Component-DSU3Qp0O.js.map +0 -1
  528. package/lib/DropdownItem-Cb-7cHMg.js +0 -2
  529. package/lib/DropdownItem-Cb-7cHMg.js.map +0 -1
  530. package/lib/Fieldset.js +0 -2
  531. package/lib/Fieldset.js.map +0 -1
  532. package/lib/FormAssociatedMixin-B4Qj-CQN.js +0 -2
  533. package/lib/FormAssociatedMixin-B4Qj-CQN.js.map +0 -1
  534. package/lib/FormField-BFaVzUjk.js +0 -2
  535. package/lib/FormField-BFaVzUjk.js.map +0 -1
  536. package/lib/NavToggle-DzKbd-El.js +0 -2
  537. package/lib/NavToggle-DzKbd-El.js.map +0 -1
  538. package/lib/Popout-CYqn_dZu.js +0 -2
  539. package/lib/Popout-CYqn_dZu.js.map +0 -1
  540. package/lib/Sticky-DqnqENYN.js +0 -2
  541. package/lib/Sticky-DqnqENYN.js.map +0 -1
  542. package/lib/TextField-B955GOhe.js +0 -2
  543. package/lib/TextField-B955GOhe.js.map +0 -1
  544. package/lib/dates-CAAlPKZi.js +0 -2
  545. package/lib/dates-CAAlPKZi.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ import{_ as e}from"./tslib.es6-CmLYFWVC.js";import{a as t}from"./interface-add-small-B-hv2v9J.js";import{r as i}from"./interface-remove-small-DUaWSs90.js";import{css as n,isServer as r,html as o,nothing as s,LitElement as l}from"lit";import{query as a,property as d,state as u,customElement as c}from"lit/decorators.js";import{classMap as h}from"lit/directives/class-map.js";import{createRef as p,ref as m}from"lit/directives/ref.js";import{F as b}from"./FormDataController-OUt5L5uC.js";import{S as f}from"./StateAttributesController-BIh96sXZ.js";import{N as v}from"./events-Bv6wNHwJ.js";import{i as y}from"./light-dom-styles-DXsbiKU9.js";import{D as g}from"./DraftComponentMixin-4qug5Rky.js";import{F as S}from"./FieldControlMixin-BXNZJXu9.js";import{S as k}from"./SizeMixin-CU9cLbLC.js";import w from"./Icon.js";import{LocalizeController as x}from"./LocalizeController.js";import{resolveCurrencyPlacement as z,getCurrencySymbol as D}from"./currency.js";import{formatNumber as j}from"./format.js";import{NumberFieldChangeEvent as I}from"./NumberFieldEvents.js";import{getNumberLocaleDetails as $,BASE_NON_NUMERIC_SYMBOLS as T,SPACE_SEPARATOR_RE as _,PERCENTAGES as A,PERMILLE as V,PLUS_SIGNS_WITH_ASCII as P,MINUS_SIGNS_WITH_ASCII as N,ARABIC_DETECT_RE as E,PERSIAN_DETECT_RE as C,HAN_DETECT_RE as W,FULLWIDTH_DETECT_RE as L,ANY_MINUS_DETECT_RE as M,ANY_PLUS_DETECT_RE as O,parseNumber as R}from"./parse.js";import{clamp as F,toValidatedNumber as q,hasNumberFormatRoundingOptions as B,removeFloatingPointErrors as U}from"./validate.js";import"./context-consumer-BJVUulGf.js";import"./context-request-event-CCRlXoeR.js";import"./field-context.js";import"./create-context-CJ69ntlY.js";import"./SlotController-Z6eG7LSZ.js";import"./EventController-BBOmvfLa.js";import"./VisuallyHidden.js";import"lit/directives/if-defined.js";import"lit/directives/unsafe-html.js";import"./observe-D0n0zOfU.js";import"./cond-CI1KbneT.js";import"./Component-BJ5O5n8k.js";import"./IconManager.js";import"./translation.js";import"./en-us.js";import"./localization.js";import"./localization2.js";import"./localization3.js";import"./localization4.js";import"./localization5.js";import"./localization6.js";import"./localization7.js";import"./localization8.js";import"./localization9.js";import"./localization10.js";import"./localization11.js";import"./localization12.js";import"./localization13.js";import"./localization14.js";import"./localization15.js";import"./localization16.js";import"./localization17.js";import"./localization18.js";import"./localization19.js";import"./localization20.js";import"./localization21.js";import"./localization22.js";const K=n`nord-number-field,nord-number-field *,nord-number-field :after,nord-number-field :before{box-sizing:border-box}nord-number-field{--n-number-field-control-min-inline-size:8ch;--n-number-field-background:var(--n-input-background,var(--n-color-surface));--n-number-field-border-color:var(--n-input-border-color,var(--n-color-border-strong));--n-number-field-border-radius:var(--n-input-border-radius,var(--n-border-radius-s));--_n-number-field-block-size:var(--n-number-field-block-size,var(--n-space-xl));--_n-number-field-border-color:var(--n-number-field-border-color);--_n-number-field-min-content-block-size:calc(var(--n-line-height-form) + var(--n-space-s)/1.6*2 + 2px);--_n-number-field-padding-block:calc(var(--_n-number-field-block-size)/2 - var(--n-line-height-form)/2 - 1px);--_n-number-field-padding-inline:calc(var(--n-space-s)*1.6);--_n-number-field-font-size:var(--n-font-size-m);--_n-number-field-step-inline-size:var(--n-number-field-step-inline-size,var(--_n-number-field-block-size));display:block}nord-number-field .n-number-field{inline-size:100%}nord-number-field .n-number-field-root{display:contents}nord-number-field .n-scrub{align-items:center;color:var(--n-color-icon);cursor:ew-resize;display:inline-flex;margin-block-end:var(--n-space-xs);touch-action:none;user-select:none}nord-number-field .n-scrub-grip{block-size:var(--n-size-icon-s);display:block;inline-size:auto}nord-number-field.is-scrubbing,nord-number-field.is-scrubbing .n-input,nord-number-field.is-scrubbing .n-scrub{cursor:ew-resize}nord-number-field .n-control{align-items:stretch;background:var(--n-number-field-background);border:1px solid var(--_n-number-field-border-color);border-radius:var(--n-number-field-border-radius);display:flex;inline-size:100%;min-block-size:var(--_n-number-field-block-size);transition:border var(--n-transition-quickly),box-shadow var(--n-transition-quickly),background var(--n-transition-quickly)}nord-number-field .n-control:hover{--_n-number-field-border-color:var(--n-input-border-color,var(--n-color-border-hover))}nord-number-field .n-control:focus-within{--_n-number-field-border-color:var(--n-input-border-color,var(--n-color-accent));box-shadow:0 0 0 1px var(--_n-number-field-border-color)}nord-number-field[disabled] .n-control{--n-number-field-background:var(--n-input-background-inactive,var(--n-color-active));--_n-number-field-border-color:var(--n-input-border-color,var(--n-color-active));cursor:auto}nord-number-field .n-control.is-invalid{--_n-number-field-border-color:var(--n-color-border-danger)}nord-number-field .n-control.is-invalid:focus-within{--_n-number-field-border-color:var(--n-color-status-danger)}nord-number-field .n-input{appearance:none;background:#0000;border:none;color:var(--n-color-text);flex:1;font-family:var(--n-font-family);font-feature-settings:var(--n-font-features);font-size:var(--_n-number-field-font-size);font-variant-numeric:tabular-nums;line-height:var(--n-line-height-form);margin:0;min-inline-size:var(--n-number-field-control-min-inline-size);outline:none;padding-block-end:var(--_n-number-field-padding-block);padding-block-start:var(--_n-number-field-padding-block);padding-inline-end:var(--_n-number-field-padding-inline);padding-inline-start:var(--_n-number-field-padding-inline);text-align:start}nord-number-field .n-control input.n-input:focus,nord-number-field .n-control input.n-input:focus-visible,nord-number-field .n-control input.n-input:focus-within{background:#0000;border:none;box-shadow:none;outline:none}nord-number-field .n-input::placeholder{color:var(--n-color-text-weakest);opacity:1}nord-number-field[disabled] .n-input{color:var(--n-color-text-weakest)}nord-number-field .n-number-field-slot{align-items:center;color:var(--n-color-text-weaker);display:inline-flex;flex:0 0 auto;font-family:var(--n-font-family);font-size:var(--_n-number-field-font-size);gap:var(--n-space-xs);line-height:var(--n-line-height-form);white-space:nowrap}nord-number-field .n-number-field-slot:empty{display:none}nord-number-field .n-number-field-slot-start{padding-inline-start:var(--_n-number-field-padding-inline)}nord-number-field .n-number-field-slot-end{padding-inline-end:var(--_n-number-field-padding-inline)}nord-number-field .n-number-field-slot nord-icon{--_n-icon-size:var(--n-size-icon-s)}nord-number-field[disabled] .n-number-field-slot{color:var(--n-color-text-weakest)}nord-number-field .n-currency-symbol{color:var(--n-color-text-weaker);font-variant-numeric:tabular-nums;user-select:none}nord-number-field .n-step{align-items:center;appearance:none;background:#0000;border:none;color:var(--n-color-icon);cursor:pointer;display:flex;flex-shrink:0;inline-size:var(--_n-number-field-step-inline-size);justify-content:center;margin:0;padding:0;transition:color var(--n-transition-quickly),background var(--n-transition-quickly);user-select:none}nord-number-field .n-step:hover:not([disabled]){background:var(--n-color-button-hover);color:var(--n-color-text)}nord-number-field .n-step:active:not([disabled]){background:var(--n-color-active)}nord-number-field .n-step[disabled]{color:var(--n-color-text-weakest);cursor:auto}nord-number-field .n-decrement{border-inline-end:1px solid var(--_n-number-field-border-color)}nord-number-field .n-increment{border-inline-start:1px solid var(--_n-number-field-border-color)}nord-number-field .n-step nord-icon{--_n-icon-size:var(--n-size-icon-s)}nord-number-field[size=s]{--_n-number-field-block-size:var(--n-number-field-block-size,calc(var(--n-space-l) + var(--n-space-xs)));--_n-number-field-padding-block:calc(var(--_n-number-field-block-size)/2 - var(--n-line-height-form)/2 - 1px);--_n-number-field-padding-inline:var(--n-space-s);--_n-number-field-font-size:var(--n-font-size-s);--_n-number-field-step-inline-size:var(--n-number-field-step-inline-size,var(--_n-number-field-block-size))}nord-number-field[size=s] .n-step nord-icon{--_n-icon-size:var(--n-size-icon-xs)}nord-number-field[size=l]{--_n-number-field-block-size:max(var(--n-number-field-block-size,calc(var(--n-space-xxl) - var(--n-space-l))),var(--_n-number-field-min-content-block-size));--_n-number-field-padding-block:calc(var(--_n-number-field-block-size)/2 - var(--n-line-height-form)/2 - 1px);--_n-number-field-font-size:var(--n-font-size-l);--_n-number-field-step-inline-size:var(--n-number-field-step-inline-size,var(--_n-number-field-block-size))}nord-number-field[size=l] .n-step nord-icon{--_n-icon-size:var(--n-size-icon-m)}`;w.registerIcon(t),w.registerIcon(i);let H=1;function Z(e,t){return Number.isFinite(e)&&e>0?e:t}let G=class extends(g(k(S(l)))){constructor(){super(...arguments),this.numberFieldId="nord-number-field-"+H++,this.inputId=`${this.numberFieldId}-input`,this.localize=new x(this),this.inputRef=p(),this.formData=new b(this,{value:()=>null==this.value?void 0:String(this.value)}),this.stateAttributes=new f(this,(()=>({invalid:this.effectiveInvalid})),{trackFocus:!0}),this.formAncestor=null,this.value=null,this.step=1,this.largeStep=10,this.smallStep=.1,this.snapOnStep=!1,this.allowOutOfRange=!1,this.integer=!1,this.allowWheelScrub=!1,this.scrub=!1,this.disabled=!1,this.readonly=!1,this.invalid=!1,this.hideControls=!1,this.currencyPlacement="auto",this.inputText="",this.scrubbing=!1,this.allowInputSync=!0,this.hasTouchedInput=!1,this.skipNextClick=!1,this.scrubAccumulator=0,this.scrubMoved=!1,this.scrubPointerDownTarget=null,this.onScrubMove=e=>this.handleScrubMove(e),this.onScrubUp=e=>this.handleScrubUp(e),this.onWheel=e=>this.handleWheel(e),this.wheelAttached=!1}get ownInvalid(){return this.invalid||super.ownInvalid}set form(e){const t=this._formId;this._formId=e,this.requestUpdate("form",t)}get form(){if(this._formId){return this.getRootNode().querySelector(`form#${this._formId}`)}return this.formAncestor}get minWithDefault(){var e;return null!==(e=this.min)&&void 0!==e?e:Number.MIN_SAFE_INTEGER}get maxWithDefault(){var e;return null!==(e=this.max)&&void 0!==e?e:Number.MAX_SAFE_INTEGER}get minWithZeroDefault(){var e;return null!==(e=this.min)&&void 0!==e?e:0}get allowsNegative(){return this.minWithDefault<0}get numericStep(){return"any"===this.step?1:Z(this.step,1)}get effectiveLargeStep(){return Z(this.largeStep,10)}get effectiveSmallStep(){return Z(this.smallStep,.1)}formatDisplay(e){return this.formatValue?this.formatValue(e,this.locale,this.format):j(e,this.locale,this.format)}connectedCallback(){var e,t;super.connectedCallback(),y(this,K),this.formAncestor=this.closest("form"),null!==(e=this.ariaObserver)&&void 0!==e||(this.ariaObserver=new MutationObserver((()=>this.requestUpdate()))),this.ariaObserver.observe(this,{attributes:!0,attributeFilter:["aria-label","aria-labelledby","aria-describedby"]}),null!==(t=this.slotObserver)&&void 0!==t||(this.slotObserver=new MutationObserver((()=>this.requestUpdate()))),this.slotObserver.observe(this,{childList:!0}),this.allowInputSync&&(this.inputText=this.formatDisplay(this.value))}disconnectedCallback(){var e,t;super.disconnectedCallback(),null===(e=this.ariaObserver)||void 0===e||e.disconnect(),this.ariaObserver=void 0,null===(t=this.slotObserver)||void 0===t||t.disconnect(),this.slotObserver=void 0,this.formAncestor=null,this.stopHold(),this.detachWheel(),this.removeScrubListeners()}createRenderRoot(){if(r)return this;const e=document.createElement("div");return e.className="n-number-field-root",this.appendChild(e),e}relocateSlots(){if(r)return;const e=(e,t)=>{if(t)for(const i of Array.from(this.children))i.getAttribute("slot")===e&&i.parentElement!==t&&t.appendChild(i)};e("start",this.startZone),e("end",this.endZone)}willUpdate(e){if(e.has("value")&&this.allowInputSync&&!this.allowOutOfRange&&null!=this.value){const e=F(this.value,this.minWithDefault,this.maxWithDefault);e!==this.value&&(this.value=e)}e.has("value")&&this.integer&&null!=this.value&&!Number.isInteger(this.value)&&(this.value=Math.round(this.value)),this.allowInputSync&&(e.has("value")||e.has("format")||e.has("locale"))&&(this.inputText=this.formatDisplay(this.value))}updated(e){var t;super.updated(e),this.relocateSlots();const i=this.allowWheelScrub&&!this.disabled&&!this.readonly;if(i&&!this.wheelAttached?this.attachWheel():!i&&this.wheelAttached&&this.detachWheel(),this.pendingSelection){const[e,i]=this.pendingSelection;this.pendingSelection=void 0,null===(t=this.inputRef.value)||void 0===t||t.setSelectionRange(e,i)}}focus(e){var t;null===(t=this.inputRef.value)||void 0===t||t.focus(e)}isTextReason(e){return"input-change"===e||"input-blur"===e||"input-paste"===e||"input-clear"===e||"none"===e}getStepAmount(e){return(null==e?void 0:e.altKey)?this.effectiveSmallStep:(null==e?void 0:e.shiftKey)?this.effectiveLargeStep:this.numericStep}setValue(e,{reason:t,direction:i,event:n}){var r;const o=!this.allowOutOfRange||!this.isTextReason(t),s=q(e,{step:i?this.getStepAmount(n)*i:void 0,format:this.format,minWithDefault:this.minWithDefault,maxWithDefault:this.maxWithDefault,minWithZeroDefault:this.minWithZeroDefault,snapOnStep:this.snapOnStep,small:null!==(r=null==n?void 0:n.altKey)&&void 0!==r&&r,clamp:o}),l=this.isTextReason(t),a=s!==this.value||l&&(e!==this.value||!1===this.allowInputSync);return a&&(this.value=s,this.dispatchEvent(new v("input"))),this.allowInputSync&&(this.inputText=this.formatDisplay(s)),this.requestUpdate(),a}incrementValue(e,{direction:t,currentValue:i,event:n,reason:r}){var o;const s=i??this.value,l="number"==typeof s?s+e*t:Math.max(0,null!==(o=this.min)&&void 0!==o?o:0);return this.setValue(l,{reason:r,direction:t,event:n})}commit(e){this.dispatchEvent(new I(this.value,e))}getAllowedNonNumericKeys(){var e,t,i;const{decimal:n,group:r,currency:o,literal:s}=$(this.locale,this.format),l=new Set;T.forEach((e=>l.add(e))),n&&l.add(n),r&&(l.add(r),_.test(r)&&l.add(" "));const a=null===(e=this.format)||void 0===e?void 0:e.style,d="percent"===a||"unit"===a&&"percent"===(null===(t=this.format)||void 0===t?void 0:t.unit),u="percent"===a||"unit"===a&&"permille"===(null===(i=this.format)||void 0===i?void 0:i.unit);if(d&&A.forEach((e=>l.add(e))),u&&V.forEach((e=>l.add(e))),"currency"===a&&o&&l.add(o),s&&(Array.from(s).forEach((e=>l.add(e))),_.test(s)&&l.add(" ")),P.forEach((e=>l.add(e))),this.minWithDefault<0&&N.forEach((e=>l.add(e))),this.integer)for(const e of[n,".",".","٫"])e&&e!==r&&l.delete(e);return l}handleKeydown(e){if(e.defaultPrevented||this.readonly||this.disabled)return;this.allowInputSync=!0;if(!new Set(["ArrowUp","ArrowDown","PageUp","PageDown","Home","End"]).has(e.key)){if(this.mask)return;const t=this.getAllowedNonNumericKeys(),i=e.key>="0"&&e.key<="9",n=e.key.length>1;return void(229===e.which||e.ctrlKey||e.metaKey||e.altKey||i||n||t.has(e.key)||E.test(e.key)||C.test(e.key)||W.test(e.key)||L.test(e.key)||this.allowsNegative&&M.test(e.key)||O.test(e.key)||e.preventDefault())}const t=this.parseValue?this.parseValue(this.inputText,this.locale,this.format):R(this.inputText,this.locale,this.format);switch(e.key){case"ArrowUp":e.preventDefault(),this.incrementValue(this.getStepAmount(e),{direction:1,currentValue:t,event:e,reason:"keyboard"}),this.commit("keyboard");break;case"ArrowDown":e.preventDefault(),this.incrementValue(this.getStepAmount(e),{direction:-1,currentValue:t,event:e,reason:"keyboard"}),this.commit("keyboard");break;case"PageUp":e.preventDefault(),this.incrementValue(this.effectiveLargeStep,{direction:1,currentValue:t,reason:"keyboard"}),this.commit("keyboard");break;case"PageDown":e.preventDefault(),this.incrementValue(this.effectiveLargeStep,{direction:-1,currentValue:t,reason:"keyboard"}),this.commit("keyboard");break;case"Home":null!=this.min&&Number.isFinite(this.min)&&(e.preventDefault(),this.setValue(this.min,{reason:"keyboard"}),this.commit("keyboard"));break;case"End":null!=this.max&&Number.isFinite(this.max)&&(e.preventDefault(),this.setValue(this.max,{reason:"keyboard"}),this.commit("keyboard"))}}isValidCharacterString(e){const t=this.getAllowedNonNumericKeys();return Array.from(e).every((e=>e>="0"&&e<="9"||E.test(e)||W.test(e)||C.test(e)||L.test(e)||this.allowsNegative&&M.test(e)||t.has(e)))}handleInput(e){var t,i;e.stopPropagation(),this.allowInputSync=!1;const n=e.target;let r=n.value;const o=this.mask;if(o&&""!==r.trim()){const e=o({value:r,selectionStart:null!==(t=n.selectionStart)&&void 0!==t?t:r.length,selectionEnd:null!==(i=n.selectionEnd)&&void 0!==i?i:r.length},{locale:this.locale,format:this.format});r=e.value,this.pendingSelection=[e.selectionStart,e.selectionEnd]}if(""===r.trim())return this.inputText="",this.pendingSelection=void 0,void this.setValue(null,{reason:"input-clear"});if(!this.mask&&!this.isValidCharacterString(r))return;this.inputText=r;const s=this.parseValue?this.parseValue(r,this.locale,this.format):R(r,this.locale,this.format);null!==s&&this.setValue(s,{reason:"input-change"})}handlePaste(e){var t,i;if(e.defaultPrevented||this.readonly||this.disabled)return;if(this.mask)return;const n=null!==(i=null===(t=e.clipboardData)||void 0===t?void 0:t.getData("text/plain"))&&void 0!==i?i:"";e.preventDefault();const r=this.parseValue?this.parseValue(n,this.locale,this.format):R(n,this.locale,this.format);null!==r&&(this.allowInputSync=!0,this.setValue(r,{reason:"input-paste"}))}handleFocus(e){if(e.defaultPrevented||this.readonly||this.disabled)return;if(this.hasTouchedInput)return;this.hasTouchedInput=!0;const t=e.currentTarget,i=t.value.length;t.setSelectionRange(i,i)}handleBlur(e){if(e.defaultPrevented||this.readonly||this.disabled)return;if(this.allowInputSync=!0,""===this.inputText.trim())return this.setValue(null,{reason:"input-clear"}),void this.commit("input-clear");const t=this.parseValue?this.parseValue(this.inputText,this.locale,this.format):R(this.inputText,this.locale,this.format);if(null===t){const e=this.formatDisplay(this.value);return void(this.inputText!==e&&(this.inputText=e))}const i=B(this.format)?U(t,this.format):t;i!==this.value&&this.setValue(i,{reason:"input-blur"});const n=this.formatDisplay(this.value);this.inputText!==n&&(this.inputText=n),this.commit("input-blur")}commitDirtyInput(e,t){this.allowInputSync=!0;const i=this.parseValue?this.parseValue(this.inputText,this.locale,this.format):R(this.inputText,this.locale,this.format);null!==i&&this.setValue(i,{reason:e,direction:t})}handleStepPointerDown(e,t){var i;const n=!e.button||0===e.button;if(e.defaultPrevented||this.readonly||this.disabled||!n)return;const r=1===t?"increment-press":"decrement-press";this.skipNextClick=!0,this.activePointerId=e.pointerId,this.commitDirtyInput(r,t),"touch"!==e.pointerType&&"pen"!==e.pointerType&&(null===(i=this.inputRef.value)||void 0===i||i.focus()),this.allowInputSync=!0,this.incrementValue(this.getStepAmount(e),{direction:t,event:e,reason:r});const o=e.currentTarget;try{o.setPointerCapture(e.pointerId)}catch(e){}this.holdStartTimer=setTimeout((()=>{this.holdTickTimer=setInterval((()=>{this.allowInputSync=!0,this.incrementValue(this.getStepAmount(e),{direction:t,event:e,reason:r})}),60)}),400)}handleStepPointerStop(e,t){if(void 0!==this.activePointerId&&this.activePointerId!==e.pointerId)return;const i=null!=this.holdStartTimer||null!=this.holdTickTimer;this.stopHold(),this.activePointerId=void 0,(this.skipNextClick||i)&&this.commit(1===t?"increment-press":"decrement-press")}handleStepClick(e,t){const i=1===t?"increment-press":"decrement-press";if(e.defaultPrevented||this.readonly||this.disabled)return;if(this.skipNextClick)return void(this.skipNextClick=!1);this.commitDirtyInput(i,t),this.allowInputSync=!0;this.incrementValue(this.getStepAmount(e),{direction:t,event:e,reason:i})&&this.commit(i)}stopHold(){null!=this.holdStartTimer&&(clearTimeout(this.holdStartTimer),this.holdStartTimer=void 0),null!=this.holdTickTimer&&(clearInterval(this.holdTickTimer),this.holdTickTimer=void 0)}get incrementDisabled(){return this.disabled||this.readonly||null!=this.value&&this.value>=this.maxWithDefault}get decrementDisabled(){return this.disabled||this.readonly||null!=this.value&&this.value<=this.minWithDefault}attachWheel(){const e=this.inputRef.value;e&&(e.addEventListener("wheel",this.onWheel,{passive:!1}),this.wheelAttached=!0)}detachWheel(){const e=this.inputRef.value;null==e||e.removeEventListener("wheel",this.onWheel),this.wheelAttached=!1}handleWheel(e){if(e.ctrlKey||this.inputRef.value!==this.getActiveElement())return;e.preventDefault(),this.allowInputSync=!0;const t=this.getStepAmount(e);this.incrementValue(t,{direction:e.deltaY>0?-1:1,event:e,reason:"wheel"})}getActiveElement(){return this.getRootNode().activeElement}handleScrubPointerDown(e){var t;const i=!e.button||0===e.button;if(e.defaultPrevented||this.readonly||this.disabled||!i)return;"mouse"===e.pointerType&&(e.preventDefault(),null===(t=this.inputRef.value)||void 0===t||t.focus()),this.scrubbing=!0,this.scrubMoved=!1,this.scrubAccumulator=0,this.scrubPointerDownTarget=e.target;const n=this.ownerWindow();n.addEventListener("pointermove",this.onScrubMove,!0),n.addEventListener("pointerup",this.onScrubUp,!0)}handleScrubMove(e){if(this.scrubbing&&(e.preventDefault(),this.scrubAccumulator+=e.movementX,Math.abs(this.scrubAccumulator)>=2)){this.scrubAccumulator=0,this.scrubMoved=!0;const t=e.movementX,i=Math.abs(t*this.getStepAmount(e));0!==i&&(this.allowInputSync=!0,this.incrementValue(i,{direction:t>=0?1:-1,event:e,reason:"scrub"}))}}handleScrubUp(e){this.removeScrubListeners(),this.scrubbing=!1,this.commit("scrub"),!this.scrubMoved&&this.scrubPointerDownTarget&&this.scrubPointerDownTarget.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0})),this.scrubMoved=!1,this.scrubPointerDownTarget=null}removeScrubListeners(){const e=this.ownerWindow();e.removeEventListener("pointermove",this.onScrubMove,!0),e.removeEventListener("pointerup",this.onScrubUp,!0)}handleScrubTouchStart(e){this.disabled||this.readonly||1===e.touches.length&&e.preventDefault()}ownerWindow(){var e;return null!==(e=this.ownerDocument.defaultView)&&void 0!==e?e:window}get computedInputMode(){if(null!=this.min&&this.min<0)return"text";if(this.integer)return"numeric";const e="any"===this.step||Number.isInteger(this.numericStep),t=null==this.min||Number.isInteger(this.min)&&this.min>=0,i=null==this.max||Number.isInteger(this.max);return e&&t&&i?"numeric":"decimal"}get resolvedCurrencyPlacement(){return"start"===this.currencyPlacement||"end"===this.currencyPlacement?this.currencyPlacement:this.currency?z(this.locale,this.currency):"start"}render(){var e,t;const i=this.inputId,n=this.controlAriaLabel,r=this.controlAriaLabelledby,l=this.currency?D(this.locale,this.currency):void 0,a=this.currency?this.resolvedCurrencyPlacement:void 0,d=this.currency?`${i}-currency`:void 0,u=[this.controlAriaDescribedby,d].filter(Boolean).join(" ")||void 0,c=e=>null!=l&&a===e?o`<span id="${d}" class="n-currency-symbol" aria-hidden="true">${l}</span>`:s;return o`${this.renderLabel()}<div class="${h({"n-number-field":!0,"is-scrubbing":this.scrubbing})}">${this.scrub?o`<div class="n-scrub" role="presentation" aria-hidden="true" @pointerdown="${this.handleScrubPointerDown}" @touchstart="${this.handleScrubTouchStart}"><svg class="n-scrub-grip" width="24" height="14" viewBox="0 0 24 14" fill="currentColor" aria-hidden="true"><path d="M19.5 5.5L6.49737 5.51844V2L1 6.9999L6.5 12L6.49737 8.5L19.5 8.5V12L25 6.9999L19.5 2V5.5Z"></path></svg></div>`:s}<div class="${h({"n-control":!0,"is-invalid":this.effectiveInvalid})}">${this.hideControls?s:o`<button class="${h({"n-step":!0,"n-decrement":!0})}" type="button" tabindex="-1" aria-label="${this.localize.term("decreaseLabel")}" aria-controls="${i}" aria-readonly="${this.readonly?"true":s}" ?disabled="${this.decrementDisabled}" @pointerdown="${e=>this.handleStepPointerDown(e,-1)}" @pointerup="${e=>this.handleStepPointerStop(e,-1)}" @pointerleave="${e=>this.handleStepPointerStop(e,-1)}" @pointercancel="${e=>this.handleStepPointerStop(e,-1)}" @click="${e=>this.handleStepClick(e,-1)}"><nord-icon name="interface-remove-small"></nord-icon></button>`} <span class="n-number-field-slot n-number-field-slot-start">${c("start")}</span> <input ${m(this.inputRef)} class="n-input" type="text" id="${i}" inputmode="${this.computedInputMode}" .value="${this.inputText}" placeholder="${null!==(e=this.placeholder)&&void 0!==e?e:s}" ?disabled="${this.effectiveDisabled}" ?readonly="${this.readonly}" ?required="${this.required}" autocomplete="off" autocorrect="off" spellcheck="false" aria-roledescription="${this.localize.term("roleDescription")}" aria-label="${null!=n?n:s}" aria-labelledby="${null!=r?r:s}" aria-describedby="${null!=u?u:s}" aria-invalid="${null!==(t=this.controlAriaInvalid)&&void 0!==t?t:s}" aria-required="${this.required?"true":s}" aria-readonly="${this.readonly?"true":s}" @input="${this.handleInput}" @blur="${this.handleBlur}" @focus="${this.handleFocus}" @keydown="${this.handleKeydown}" @paste="${this.handlePaste}"> <span class="n-number-field-slot n-number-field-slot-end">${c("end")}</span> ${this.hideControls?s:o`<button class="${h({"n-step":!0,"n-increment":!0})}" type="button" tabindex="-1" aria-label="${this.localize.term("increaseLabel")}" aria-controls="${i}" aria-readonly="${this.readonly?"true":s}" ?disabled="${this.incrementDisabled}" @pointerdown="${e=>this.handleStepPointerDown(e,1)}" @pointerup="${e=>this.handleStepPointerStop(e,1)}" @pointerleave="${e=>this.handleStepPointerStop(e,1)}" @pointercancel="${e=>this.handleStepPointerStop(e,1)}" @click="${e=>this.handleStepClick(e,1)}"><nord-icon name="interface-add-small"></nord-icon></button>`}</div></div>${this.renderError()} ${this.isHintBelow?this.renderHint():s}`}};e([a(".n-number-field-slot-start")],G.prototype,"startZone",void 0),e([a(".n-number-field-slot-end")],G.prototype,"endZone",void 0),e([d({converter:function(e){if(null==e||""===e.trim())return null;const t=Number(e);return Number.isNaN(t)?null:t}})],G.prototype,"value",void 0),e([d({reflect:!0,type:Number})],G.prototype,"min",void 0),e([d({reflect:!0,type:Number})],G.prototype,"max",void 0),e([d({reflect:!0,converter:function(e){return null==e?1:"any"===e?"any":Z(Number(e),1)}})],G.prototype,"step",void 0),e([d({reflect:!0,type:Number,attribute:"large-step"})],G.prototype,"largeStep",void 0),e([d({reflect:!0,type:Number,attribute:"small-step"})],G.prototype,"smallStep",void 0),e([d({reflect:!0,type:Boolean,attribute:"snap-on-step"})],G.prototype,"snapOnStep",void 0),e([d({reflect:!0,type:Boolean,attribute:"allow-out-of-range"})],G.prototype,"allowOutOfRange",void 0),e([d({reflect:!0,type:Boolean})],G.prototype,"integer",void 0),e([d({reflect:!0,type:Boolean,attribute:"allow-wheel-scrub"})],G.prototype,"allowWheelScrub",void 0),e([d({reflect:!0,type:Boolean})],G.prototype,"scrub",void 0),e([d({attribute:!1})],G.prototype,"format",void 0),e([d({attribute:!1})],G.prototype,"formatValue",void 0),e([d({attribute:!1})],G.prototype,"parseValue",void 0),e([d({attribute:!1})],G.prototype,"mask",void 0),e([d({reflect:!0})],G.prototype,"locale",void 0),e([d({reflect:!0})],G.prototype,"placeholder",void 0),e([d({reflect:!0})],G.prototype,"name",void 0),e([d({reflect:!0,type:Boolean})],G.prototype,"disabled",void 0),e([d({reflect:!0,type:Boolean})],G.prototype,"readonly",void 0),e([d({reflect:!0,type:Boolean})],G.prototype,"invalid",void 0),e([d({reflect:!0,type:Boolean,attribute:"hide-controls"})],G.prototype,"hideControls",void 0),e([d({reflect:!0})],G.prototype,"currency",void 0),e([d({reflect:!0,attribute:"currency-placement"})],G.prototype,"currencyPlacement",void 0),e([u()],G.prototype,"inputText",void 0),e([u()],G.prototype,"scrubbing",void 0),e([d()],G.prototype,"form",null),G=e([c("nord-number-field")],G);var X=G;export{I as NumberFieldChangeEvent,X as default,D as getCurrencySymbol,z as resolveCurrencyPlacement};
2
+ //# sourceMappingURL=NumberField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberField.js","sources":["../src/number-field/NumberField.ts"],"sourcesContent":["import type { PropertyValues, ReactiveControllerHost } from 'lit'\nimport type { InputMixinInterface } from '../common/mixins/InputMixin.js'\nimport type { NumberFieldChangeReason } from './NumberFieldEvents.js'\nimport * as addIcon from '@nordhealth/icons/lib/assets/interface-add-small.js'\nimport * as removeIcon from '@nordhealth/icons/lib/assets/interface-remove-small.js'\nimport { html, isServer, LitElement, nothing } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\n\nimport { FormDataController } from '../common/controllers/FormDataController.js'\nimport { StateAttributesController } from '../common/controllers/StateAttributesController.js'\nimport { NordEvent } from '../common/events.js'\nimport { injectLightDomStyles } from '../common/light-dom-styles.js'\nimport { DraftComponentMixin } from '../common/mixins/DraftComponentMixin.js'\nimport { FieldControlMixin } from '../common/mixins/FieldControlMixin.js'\nimport { SizeMixin } from '../common/mixins/SizeMixin.js'\nimport Icon from '../icon/Icon.js'\nimport { LocalizeController } from '../localization/LocalizeController.js'\nimport { getCurrencySymbol, resolveCurrencyPlacement } from './currency.js'\nimport { formatNumber } from './format.js'\nimport style from './NumberField.css'\nimport { NumberFieldChangeEvent } from './NumberFieldEvents.js'\nimport {\n ANY_MINUS_DETECT_RE,\n ANY_PLUS_DETECT_RE,\n ARABIC_DETECT_RE,\n BASE_NON_NUMERIC_SYMBOLS,\n FULLWIDTH_DETECT_RE,\n getNumberLocaleDetails,\n HAN_DETECT_RE,\n MINUS_SIGNS_WITH_ASCII,\n parseNumber,\n PERCENTAGES,\n PERMILLE,\n PERSIAN_DETECT_RE,\n PLUS_SIGNS_WITH_ASCII,\n SPACE_SEPARATOR_RE,\n} from './parse.js'\nimport {\n clamp,\n hasNumberFormatRoundingOptions,\n removeFloatingPointErrors,\n toValidatedNumber,\n} from './validate.js'\n\nexport { getCurrencySymbol, resolveCurrencyPlacement } from './currency.js'\nexport { NumberFieldChangeEvent } from './NumberFieldEvents.js'\nexport type { NumberFieldChangeReason } from './NumberFieldEvents.js'\n\n/**\n * The editable state of the inner input handed to (and returned from) a custom\n * `mask` function: the current text and the caret/selection offsets. The shape\n * mirrors a mask library's element state (e.g. Maskito's `ElementState`), so a\n * mask transformer can be adapted with a thin wrapper.\n */\nexport interface NumberFieldMaskState {\n value: string\n selectionStart: number\n selectionEnd: number\n}\n\n/** Contextual info passed to a custom `mask` function alongside the editable state. */\nexport interface NumberFieldMaskContext {\n locale?: string | string[]\n format?: Intl.NumberFormatOptions\n}\n\n/** Signature of a custom `mask` transformer function. */\nexport type NumberFieldMaskInput = (\n state: NumberFieldMaskState,\n context: NumberFieldMaskContext,\n) => NumberFieldMaskState\n\nIcon.registerIcon(addIcon)\nIcon.registerIcon(removeIcon)\n\n/** Press-and-hold timing (ms) and pointer thresholds, ported from Base UI constants. */\nconst START_AUTO_CHANGE_DELAY = 400\nconst CHANGE_VALUE_TICK_DELAY = 60\nconst SCRUB_PIXEL_SENSITIVITY = 2\n// Base UI's DEFAULT_STEP (1) is the fallback when getStepAmount() returns\n// undefined; here getStepAmount always resolves to a concrete number (step is\n// never undefined and 'any' is normalised to 1), so no separate fallback is needed.\n\n/** Per-instance counter so light-DOM ids (input + scrub label `for`) stay unique. */\nlet numberFieldCount = 1\n\n/** A keyboard-like event carrying the modifier flags `getStepAmount` reads. */\ninterface StepEventLike {\n altKey?: boolean\n shiftKey?: boolean\n}\n\n/** Converts the `value` attribute (a numeric string) to `number | null`. */\nfunction valueConverter(attr: string | null): number | null {\n if (attr == null || attr.trim() === '') {\n return null\n }\n const num = Number(attr)\n return Number.isNaN(num) ? null : num\n}\n\n/** A step must be a finite, strictly-positive number; otherwise fall back. */\nfunction sanitizeStep(value: number, fallback: number): number {\n return Number.isFinite(value) && value > 0 ? value : fallback\n}\n\n/**\n * Converts the `step` attribute, keeping the literal `'any'` but coercing\n * numbers. Rejects NaN / non-positive values, falling back to `1`, since a\n * zero or negative step makes stepping (and snap-on-step) meaningless.\n */\nfunction stepConverter(attr: string | null): number | 'any' {\n if (attr == null) {\n return 1\n }\n if (attr === 'any') {\n return 'any'\n }\n return sanitizeStep(Number(attr), 1)\n}\n\n/**\n * Number Field is a control for entering a numeric value, with decrement and\n * increment stepper buttons, optional drag-to-scrub, and locale-aware\n * formatting. It ports the behaviour of Base UI's Number Field: arrow/Page\n * stepping, Home/End to the bounds, press-and-hold auto-repeat, optional\n * wheel/scrub, clamping, and `Intl.NumberFormat` formatting.\n *\n * Number Field is a control only — it has no built-in label, hint or error.\n * Compose it inside a [Field](/components/field/) with a\n * [Field Label](/components/field-label/) to give it a label, hint and error,\n * the same way you would a native input.\n *\n * FORM PARTICIPATION: the value is submitted as the raw numeric string under the\n * host `name` via `FormDataController` (the inner input has no `name`, avoiding a\n * double submit). Unlike Base UI there is no hidden native number input, and —\n * like the other new Nord controls — Number Field does NOT use\n * `ElementInternals`, so it performs no native constraint validation: `required`,\n * `min`, `max` and `step` are NOT enforced as form-blocking validity. `min`/`max`\n * govern interactive stepping and (unless `allow-out-of-range` is set) clamp the\n * value; `required` only surfaces as `required`/`aria-required` on the inner input\n * for assistive technology. Authors must validate constraints themselves and\n * reflect failures via `invalid` and a `nord-field-error`.\n *\n * ACCESSIBILITY NOTE: the inner control is a text input (with `inputmode`) and\n * `aria-roledescription=\"Number field\"`, NOT `role=\"spinbutton\"` and NOT a\n * native `type=\"number\"`. A text input lets us show locale-formatted text\n * (currency, percent, grouping) while keeping full text editing — assistive tech\n * reads the formatted value from the input's text. We do NOT add\n * `aria-valuenow`/`valuemin`/`valuemax`/`valuetext`: those are only valid on a\n * range role (e.g. `spinbutton`/`slider`) and would fail `aria-allowed-attr`\n * validation on a text input. This mirrors what Base UI's `NumberFieldInput`\n * actually ships (only `aria-roledescription`).\n *\n * @status draft\n * @category form\n * @lightDom true\n *\n * @fires {NumberFieldChangeEvent} change - Dispatched when the value is committed (on blur, keyboard step, or pointer-up after a button hold or scrub). Carries the numeric value and a `reason`.\n * @fires {NordEvent} input - Dispatched as the value changes during interaction (typing a parseable value, clearing, each step, each button tick, each wheel notch, each scrub increment).\n *\n * @slot start - Leading content inside the control, before the input (e.g. a unit or currency symbol). Sits after the decrement stepper button.\n * @slot end - Trailing content inside the control, after the input (e.g. a unit label or `%`). Sits before the increment stepper button.\n *\n * @localization increaseLabel - Accessible label for the increment stepper button.\n * @localization decreaseLabel - Accessible label for the decrement stepper button.\n * @localization roleDescription - Role description announced for the input (aria-roledescription).\n *\n * @cssprop [--n-number-field-control-min-inline-size=8ch] - Minimum inline size (width) of the numeric input portion of the control.\n * @cssprop [--n-number-field-step-inline-size=var(--n-space-xl)] - Inline size (width) of each increment/decrement stepper button.\n * @cssprop [--n-number-field-background=var(--n-input-background, var(--n-color-surface))] - Background of the control.\n * @cssprop [--n-number-field-border-color=var(--n-input-border-color, var(--n-color-border-strong))] - Border color of the control.\n * @cssprop [--n-number-field-border-radius=var(--n-input-border-radius, var(--n-border-radius-s))] - Corner radius of the control.\n *\n * @attr {boolean} data-invalid - Present while the field is invalid (mirrors the `invalid` property). Style hook for the whole control.\n * @attr {boolean} data-focused - Present while the control has focus. Style hook for focus-within treatments.\n */\n@customElement('nord-number-field')\nexport default class NumberField extends DraftComponentMixin(SizeMixin(FieldControlMixin(LitElement))) {\n /** Stable, unique id base for this instance's light-DOM ARIA wiring. */\n private numberFieldId = `nord-number-field-${numberFieldCount++}`\n\n // The built-in `<label for>` (from FieldControlMixin) must point at the real\n // focusable input, so override the mixin's default id with the input's id.\n protected override inputId = `${this.numberFieldId}-input`\n\n private localize = new LocalizeController<'nord-number-field'>(this)\n\n private inputRef = createRef<HTMLInputElement>()\n\n // NumberField's `value` is `number | null`, which doesn't overlap with the\n // controller's `InputMixinInterface` host type (`value: string`). The\n // controller only reads `form`/`name`/`disabled` and the `value()` option (not\n // `host.value`), so casting the host through `unknown` is safe — same approach\n // as the combobox, which widens rather than narrows `value`.\n private formData = new FormDataController(\n this as unknown as ReactiveControllerHost & InputMixinInterface,\n { value: () => (this.value == null ? undefined : String(this.value)) },\n )\n\n /** Reflects state to Base-UI-style `data-*` attributes (data-invalid, data-focused). */\n private stateAttributes = new StateAttributesController(\n this,\n () => ({ invalid: this.effectiveInvalid }),\n { trackFocus: true },\n )\n\n // The control's own invalid state for the field context: its `invalid` prop or\n // a built-in `error` (when used standalone).\n protected override get ownInvalid() {\n return this.invalid || super.ownInvalid\n }\n\n /** Re-renders when the host's forwarded ARIA labelling attributes change. */\n private ariaObserver?: MutationObserver\n\n // Landing zones for relocated `slot=\"start\"`/`slot=\"end\"` host children. The\n // control renders into light DOM, so real `<slot>` projection isn't available.\n @query('.n-number-field-slot-start') private startZone?: HTMLElement\n @query('.n-number-field-slot-end') private endZone?: HTMLElement\n\n // Watches for `slot=\"start\"`/`slot=\"end\"` children being added or removed so\n // they get relocated into their landing zones on the next render.\n private slotObserver?: MutationObserver\n\n // ----- Form association (own implementation, mirroring InputMixin) ----------\n // NumberField does NOT use InputMixin because it diverges from `value: string`;\n // it provides its own `name`/`disabled`/`form` so the FormDataController host\n // shape (name/disabled/form) is satisfied.\n\n private formAncestor: HTMLFormElement | null = null\n private _formId?: string\n\n /**\n * The raw numeric value of the field, or `null` when empty.\n *\n * The `value` attribute may be set as a numeric string in HTML; it is coerced\n * with a custom converter (`Number(v)`, `NaN -> null`).\n */\n @property({ converter: valueConverter }) value: number | null = null\n\n /**\n * The minimum allowed value. Step interactions and blur-clamping clamp to it,\n * and the decrement button disables at/below it. Home jumps to it only when it\n * is finite.\n */\n @property({ reflect: true, type: Number }) min?: number\n\n /**\n * The maximum allowed value. Step interactions and blur-clamping clamp to it,\n * and the increment button disables at/above it. End jumps to it only when it\n * is finite.\n */\n @property({ reflect: true, type: Number }) max?: number\n\n /**\n * Amount each arrow press / button click / wheel notch changes the value.\n * `'any'` disables step semantics (treated as `1` internally for stepping).\n */\n @property({ reflect: true, converter: stepConverter }) step: number | 'any' = 1\n\n /** Step used for PageUp/PageDown and Shift+Arrow. */\n @property({ reflect: true, type: Number, attribute: 'large-step' }) largeStep = 10\n\n /** Step used when Alt/Option is held with Arrow keys. */\n @property({ reflect: true, type: Number, attribute: 'small-step' }) smallStep = 0.1\n\n /** When `true`, stepping snaps the value to the nearest multiple of the step. */\n @property({ reflect: true, type: Boolean, attribute: 'snap-on-step' }) snapOnStep = false\n\n /**\n * When `true`, direct text entry may go outside `min`/`max` without clamping\n * (so range validation can flag it); step interactions still clamp.\n */\n @property({ reflect: true, type: Boolean, attribute: 'allow-out-of-range' }) allowOutOfRange = false\n\n /**\n * Restricts the field to whole numbers. The decimal separator can no longer be\n * typed, pasted or programmatic fractional values are rounded to the nearest\n * integer, and the built-in `mask` caps the fraction to zero. The soft keyboard\n * shows the plain numeric keypad.\n */\n @property({ reflect: true, type: Boolean }) integer = false\n\n /** When `true`, scrolling the mouse wheel while focused changes the value. */\n @property({ reflect: true, type: Boolean, attribute: 'allow-wheel-scrub' }) allowWheelScrub = false\n\n /** When `true`, renders a drag handle so the user can click-drag to change the value. */\n @property({ reflect: true, type: Boolean }) scrub = false\n\n /**\n * `Intl.NumberFormat` options used to format the displayed text. Set as a\n * property only (e.g. `{ style: 'currency', currency: 'EUR' }`).\n */\n @property({ attribute: false }) format?: Intl.NumberFormatOptions\n\n /**\n * Overrides the default `Intl.NumberFormat`-based formatting of the displayed\n * text. Receives the current numeric value (`null` when the field is empty),\n * the active `locale`, and the `format` options, and must return the string to\n * display. Following the default behaviour, a `null` value should map to an\n * empty string. Set as a property only.\n */\n @property({ attribute: false })\n formatValue?: (value: number | null, locale?: string | string[], options?: Intl.NumberFormatOptions) => string\n\n /**\n * Overrides the default locale-aware parsing of the typed text. Receives the\n * raw input text, the active `locale`, and the `format` options, and must\n * return the parsed number, or `null` when the text is empty or cannot be\n * parsed. Set as a property only.\n */\n @property({ attribute: false })\n parseValue?: (text: string, locale?: string | string[], options?: Intl.NumberFormatOptions) => number | null\n\n /**\n * An optional custom edit-time mask: a function that reshapes the input text on\n * every insertion, deletion, and paste, and reports where the caret should\n * land. This is the live-typing counterpart to `formatValue` (which formats an\n * already-committed value). Use it to insert grouping separators, localise the\n * decimal, or cap fraction digits as the user types — typically by wrapping a\n * mask library (e.g. Maskito's `maskitoTransform(elementState, options)`).\n *\n * The field does NOT format live on its own: without a mask, the text is kept\n * as typed and the auto (`Intl`) formatting is applied only on blur and on\n * paste. When a mask is set it becomes the source of truth for the text — the\n * per-character guard is bypassed (the mask decides validity) and paste lands\n * natively so it flows through the mask. Keep the mask output parseable in, and\n * consistent with, the active `locale`/`format`. Set as a property.\n */\n @property({ attribute: false })\n mask?: NumberFieldMaskInput\n\n /** BCP-47 locale(s) for `Intl` formatting/parsing. Defaults to the runtime locale. */\n @property({ reflect: true }) locale?: string | string[]\n\n /** Placeholder text shown when the field is empty. */\n @property({ reflect: true }) placeholder?: string\n\n /** Form field name. The value is submitted under this name via FormDataController. */\n @property({ reflect: true }) name?: string\n\n /** Disables the control. */\n @property({ reflect: true, type: Boolean }) disabled = false\n\n /** Read-only: the user cannot change the value, but the value is still submitted. */\n @property({ reflect: true, type: Boolean }) readonly = false\n\n /** Applies error styling and sets `aria-invalid=\"true\"` on the inner input. */\n @property({ reflect: true, type: Boolean }) invalid = false\n\n /** Hides the increment/decrement stepper buttons (still steppable via keyboard). */\n @property({ reflect: true, type: Boolean, attribute: 'hide-controls' }) hideControls = false\n\n /**\n * ISO 4217 currency code (e.g. `USD`, `EUR`, `SEK`). Setting it enables the\n * currency convenience: a decorative, locale-aware symbol is rendered into the\n * `start`/`end` slot resolved from `currencyPlacement`, and the currency is\n * folded into the input's accessible description so assistive tech announces it.\n *\n * This is layered on top of the generic `start`/`end` slots — for a fully\n * custom symbol, omit `currency` and slot your own content instead. It is\n * independent of `format`: the symbol lives beside the number rather than in\n * the formatted text, so it composes cleanly with `mask`.\n */\n @property({ reflect: true }) currency?: string\n\n /**\n * Which side the `currency` symbol is placed on. `'auto'` (the default)\n * derives the side from the `locale`/`currency` pair via `Intl` (symbol-first\n * locales like en-US → `start`, symbol-last locales like de-DE → `end`);\n * `'start'`/`'end'` force the side. Has no effect unless `currency` is set.\n */\n @property({ reflect: true, attribute: 'currency-placement' }) currencyPlacement: 'start' | 'end' | 'auto' = 'auto'\n\n /** The text shown in the input — formatted, unless the user is mid-edit. */\n @state() private inputText = ''\n\n /** Whether the user is scrubbing (adds an `is-scrubbing` cursor). */\n @state() private scrubbing = false\n\n /**\n * While the user is actively typing this is `false`, so we don't reformat\n * mid-keystroke. Reset to `true` on blur / keydown-step / button / wheel / scrub.\n */\n private allowInputSync = true\n\n /** Set after the first focus so we only move the caret to the end once. */\n private hasTouchedInput = false\n\n /**\n * Caret/selection a mask asked us to place after it rewrote the text. Applied\n * in `updated()` once Lit has committed the new `.value` (which resets the\n * caret to the end).\n */\n private pendingSelection?: [number, number]\n\n // ----- press-and-hold timers ----------------------------------------------\n private holdStartTimer?: ReturnType<typeof setTimeout>\n private holdTickTimer?: ReturnType<typeof setInterval>\n private activePointerId?: number\n /** When a mouse pointerdown handled the change, suppress the synthetic click. */\n private skipNextClick = false\n\n // ----- scrub state ---------------------------------------------------------\n private scrubAccumulator = 0\n private scrubMoved = false\n private scrubPointerDownTarget: EventTarget | null = null\n private onScrubMove = (e: PointerEvent) => this.handleScrubMove(e)\n private onScrubUp = (e: PointerEvent) => this.handleScrubUp(e)\n\n /** Bound non-passive wheel listener (attached only while wheel scrub is enabled). */\n private onWheel = (e: WheelEvent) => this.handleWheel(e)\n private wheelAttached = false\n\n // ----- form-id getter/setter (copied from InputMixin) ----------------------\n set form(id: string) {\n const oldVal = this._formId\n this._formId = id\n this.requestUpdate('form', oldVal)\n }\n\n @property()\n get form(): HTMLFormElement | null {\n if (this._formId) {\n const root = this.getRootNode() as ShadowRoot | Document\n return root.querySelector<HTMLFormElement>(`form#${this._formId}`)\n }\n return this.formAncestor\n }\n\n /** The effective lower bound for clamping, mirroring Base UI `minWithDefault`. */\n private get minWithDefault(): number {\n return this.min ?? Number.MIN_SAFE_INTEGER\n }\n\n /** The effective upper bound for clamping, mirroring Base UI `maxWithDefault`. */\n private get maxWithDefault(): number {\n return this.max ?? Number.MAX_SAFE_INTEGER\n }\n\n /** The base used by `incrementValue` when stepping from empty. */\n private get minWithZeroDefault(): number {\n return this.min ?? 0\n }\n\n /**\n * Whether a negative value is allowed, gating the minus sign in the input. A\n * `min` of `0` or higher forbids negatives; an unset or negative `min` allows\n * them (mirroring `minWithDefault`, which backs unset `min` with a value < 0).\n */\n private get allowsNegative(): boolean {\n return this.minWithDefault < 0\n }\n\n /**\n * The numeric step used for stepping; `'any'` behaves as `1`. Guards against a\n * non-positive / NaN `step` set directly as a property (which bypasses the\n * attribute converter) by falling back to `1`.\n */\n private get numericStep(): number {\n return this.step === 'any' ? 1 : sanitizeStep(this.step, 1)\n }\n\n /** The PageUp/PageDown + Shift step, guarded against non-positive / NaN values. */\n private get effectiveLargeStep(): number {\n return sanitizeStep(this.largeStep, 10)\n }\n\n /** The Alt/Option step, guarded against non-positive / NaN values. */\n private get effectiveSmallStep(): number {\n return sanitizeStep(this.smallStep, 0.1)\n }\n\n /**\n * The canonical displayed text for a value: the `formatValue` override if set,\n * otherwise the locale `Intl` format. Applied on blur and on paste.\n */\n private formatDisplay(value: number | null): string {\n if (this.formatValue) {\n return this.formatValue(value, this.locale, this.format)\n }\n return formatNumber(value, this.locale, this.format)\n }\n\n connectedCallback() {\n super.connectedCallback()\n injectLightDomStyles(this, style)\n\n // Cache the form ancestor; it only changes on (re)connection.\n this.formAncestor = this.closest('form')\n\n // An external label (e.g. nord-field-label) names the control by setting\n // aria-label / aria-labelledby on the host; forward it to the inner input.\n this.ariaObserver ??= new MutationObserver(() => this.requestUpdate())\n this.ariaObserver.observe(this, {\n attributes: true,\n attributeFilter: ['aria-label', 'aria-labelledby', 'aria-describedby'],\n })\n\n // Relocate `slot=\"start\"`/`slot=\"end\"` children when they are added or\n // removed; the control is light DOM, so there are no real `<slot>` elements.\n this.slotObserver ??= new MutationObserver(() => this.requestUpdate())\n this.slotObserver.observe(this, { childList: true })\n\n // Format the initial value if one was set before connect.\n if (this.allowInputSync) {\n this.inputText = this.formatDisplay(this.value)\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n this.ariaObserver?.disconnect()\n this.ariaObserver = undefined\n this.slotObserver?.disconnect()\n this.slotObserver = undefined\n this.formAncestor = null\n this.stopHold()\n this.detachWheel()\n this.removeScrubListeners()\n }\n\n // Render in the light DOM so the control participates in the document tree\n // (form labelling, Tailwind), like the other new Nord components, but into a\n // layout-transparent (`display: contents`) wrapper rather than the host\n // itself, so slotted `slot=\"start\"`/`slot=\"end\"` children can live as\n // untouched siblings instead of being wiped by this element's own render\n // (mirrors `nord-filter-input` / `nord-combobox`). On the server there is no\n // DOM to append to, so render into the host directly.\n protected createRenderRoot() {\n if (isServer) {\n return this\n }\n const root = document.createElement('div')\n root.className = 'n-number-field-root'\n this.appendChild(root)\n return root\n }\n\n /**\n * Relocates the host's `slot=\"start\"`/`slot=\"end\"` children into the matching\n * landing zone inside the control. Only direct host children are considered,\n * and a child already sitting in its zone is left untouched, so repeated\n * updates are idempotent and don't disturb focus, caret or pointer state.\n */\n private relocateSlots() {\n if (isServer) {\n return\n }\n\n const move = (name: 'start' | 'end', target?: HTMLElement) => {\n if (!target) {\n return\n }\n for (const child of Array.from(this.children)) {\n if (child.getAttribute('slot') === name && child.parentElement !== target) {\n target.appendChild(child)\n }\n }\n }\n\n move('start', this.startZone)\n move('end', this.endZone)\n }\n\n protected willUpdate(changed: PropertyValues<this>) {\n // A programmatic `value` set (the property changing while the user is NOT\n // mid-edit) must respect the bounds when out-of-range entry isn't allowed.\n // Interactive clamping is handled in `setValue`, which always runs with\n // `allowInputSync === false` during typing; gating on `allowInputSync` here\n // means we only clamp non-interactive sources and never fight live input.\n if (\n changed.has('value')\n && this.allowInputSync\n && !this.allowOutOfRange\n && this.value != null\n ) {\n const clamped = clamp(this.value, this.minWithDefault, this.maxWithDefault)\n if (clamped !== this.value) {\n this.value = clamped\n }\n }\n\n // A whole-number field never holds a fraction; round any that slips in via a\n // programmatic set or a pasted decimal so the model stays integral.\n if (changed.has('value') && this.integer && this.value != null && !Number.isInteger(this.value)) {\n this.value = Math.round(this.value)\n }\n\n // Keep the displayed text in sync when the value or formatting changes\n // programmatically, but never overwrite text the user is actively editing.\n if (\n this.allowInputSync\n && (changed.has('value') || changed.has('format') || changed.has('locale'))\n ) {\n this.inputText = this.formatDisplay(this.value)\n }\n }\n\n protected updated(changed: PropertyValues) {\n super.updated(changed)\n\n // Move any `slot=\"start\"`/`slot=\"end\"` host children into their landing\n // zones inside the control. The control is light DOM, so real `<slot>`\n // projection isn't available; relocating keeps the public API like `nord-input`.\n this.relocateSlots()\n\n // Attach or detach the non-passive wheel listener as conditions change.\n const wheelWanted = this.allowWheelScrub && !this.disabled && !this.readonly\n if (wheelWanted && !this.wheelAttached) {\n this.attachWheel()\n }\n else if (!wheelWanted && this.wheelAttached) {\n this.detachWheel()\n }\n\n // A mask rewrote the text this cycle; Lit has now committed the new `.value`\n // (which parks the caret at the end), so restore the caret/selection the\n // mask requested. Runs in `updated` (before paint) so there is no flash.\n if (this.pendingSelection) {\n const [start, end] = this.pendingSelection\n this.pendingSelection = undefined\n this.inputRef.value?.setSelectionRange(start, end)\n }\n }\n\n /** Focus the inner input (mirrors combobox `focus`). */\n focus(options?: FocusOptions) {\n this.inputRef.value?.focus(options)\n }\n\n // ---------------------------------------------------------------------------\n // value model\n // ---------------------------------------------------------------------------\n\n /** The reasons that DON'T clamp when `allowOutOfRange` is set (direct text entry). */\n private isTextReason(reason: NumberFieldChangeReason): boolean {\n return (\n reason === 'input-change'\n || reason === 'input-blur'\n || reason === 'input-paste'\n || reason === 'input-clear'\n || reason === 'none'\n )\n }\n\n /**\n * The amount a single step changes the value, mirroring Base UI `getStepAmount`:\n * Alt -> smallStep, Shift -> largeStep, otherwise step.\n */\n private getStepAmount(event?: StepEventLike): number {\n if (event?.altKey) {\n return this.effectiveSmallStep\n }\n if (event?.shiftKey) {\n return this.effectiveLargeStep\n }\n return this.numericStep\n }\n\n /**\n * Validate, store, format and announce a new value.\n *\n * Returns whether a `change`/value update fired so callers can mirror Base UI's\n * commit semantics.\n */\n private setValue(\n unvalidated: number | null,\n {\n reason,\n direction,\n event,\n }: { reason: NumberFieldChangeReason, direction?: 1 | -1, event?: StepEventLike },\n ): boolean {\n // Only direct text entry may stay out of range when allowOutOfRange is set;\n // step interactions (keyboard/buttons/wheel/scrub) always clamp.\n const shouldClamp = !this.allowOutOfRange || !this.isTextReason(reason)\n\n const validated = toValidatedNumber(unvalidated, {\n step: direction ? this.getStepAmount(event) * direction : undefined,\n format: this.format,\n minWithDefault: this.minWithDefault,\n maxWithDefault: this.maxWithDefault,\n minWithZeroDefault: this.minWithZeroDefault,\n snapOnStep: this.snapOnStep,\n small: event?.altKey ?? false,\n clamp: shouldClamp,\n })\n\n const isTextReason = this.isTextReason(reason)\n const shouldFire\n = validated !== this.value\n || (isTextReason && (unvalidated !== this.value || this.allowInputSync === false))\n\n if (shouldFire) {\n this.value = validated\n // Fired as the value changes during interaction.\n this.dispatchEvent(new NordEvent('input'))\n }\n\n // Keep the visible input in sync immediately for programmatic/step changes;\n // during direct typing we gate on allowInputSync so we don't clobber the text.\n if (this.allowInputSync) {\n this.inputText = this.formatDisplay(validated)\n }\n\n this.requestUpdate()\n return shouldFire\n }\n\n /**\n * Step the value by `amount * direction`, mirroring Base UI `incrementValue`.\n * Stepping from empty starts at `max(0, min ?? 0)`.\n */\n private incrementValue(\n amount: number,\n {\n direction,\n currentValue,\n event,\n reason,\n }: {\n direction: 1 | -1\n currentValue?: number | null\n event?: StepEventLike\n reason: NumberFieldChangeReason\n },\n ): boolean {\n const prev = currentValue == null ? this.value : currentValue\n const next\n = typeof prev === 'number' ? prev + amount * direction : Math.max(0, this.min ?? 0)\n return this.setValue(next, { reason, direction, event })\n }\n\n /** Dispatch the committed `change` event with the current value + reason. */\n private commit(reason: NumberFieldChangeReason) {\n this.dispatchEvent(new NumberFieldChangeEvent(this.value, reason))\n }\n\n // ---------------------------------------------------------------------------\n // keyboard\n // ---------------------------------------------------------------------------\n\n /**\n * The set of non-numeric keys allowed in the input, mirroring Base UI's\n * `getAllowedNonNumericKeys` (locale decimal/group/currency/percent + signs).\n */\n private getAllowedNonNumericKeys(): Set<string> {\n // This guard only runs when no mask is active (`mask=\"off\"`); the built-in and\n // custom masks decide validity themselves and bypass it.\n const { decimal, group, currency, literal } = getNumberLocaleDetails(this.locale, this.format)\n const keys = new Set<string>()\n\n BASE_NON_NUMERIC_SYMBOLS.forEach(symbol => keys.add(symbol))\n if (decimal) {\n keys.add(decimal)\n }\n if (group) {\n keys.add(group)\n if (SPACE_SEPARATOR_RE.test(group)) {\n keys.add(' ')\n }\n }\n\n const formatStyle = this.format?.style\n const allowPercent\n = formatStyle === 'percent' || (formatStyle === 'unit' && this.format?.unit === 'percent')\n const allowPermille\n = formatStyle === 'percent' || (formatStyle === 'unit' && this.format?.unit === 'permille')\n\n if (allowPercent) {\n PERCENTAGES.forEach(key => keys.add(key))\n }\n if (allowPermille) {\n PERMILLE.forEach(key => keys.add(key))\n }\n if (formatStyle === 'currency' && currency) {\n keys.add(currency)\n }\n if (literal) {\n Array.from(literal).forEach(char => keys.add(char))\n if (SPACE_SEPARATOR_RE.test(literal)) {\n keys.add(' ')\n }\n }\n\n PLUS_SIGNS_WITH_ASCII.forEach(key => keys.add(key))\n if (this.minWithDefault < 0) {\n MINUS_SIGNS_WITH_ASCII.forEach(key => keys.add(key))\n }\n\n // A whole-number field drops every decimal separator (the locale's own plus\n // the universal ASCII/fullwidth/Arabic glyphs that `BASE_NON_NUMERIC_SYMBOLS`\n // seeds), but keeps the group separator so grouped input still parses — even\n // where the group char (e.g. de-DE `.`) coincides with a decimal glyph.\n if (this.integer) {\n for (const separator of [decimal, '.', '.', '٫']) {\n if (separator && separator !== group) {\n keys.delete(separator)\n }\n }\n }\n\n return keys\n }\n\n private handleKeydown(e: KeyboardEvent) {\n if (e.defaultPrevented || this.readonly || this.disabled) {\n return\n }\n\n this.allowInputSync = true\n\n const stepKeys = new Set(['ArrowUp', 'ArrowDown', 'PageUp', 'PageDown', 'Home', 'End'])\n\n if (!stepKeys.has(e.key)) {\n // A custom mask governs which characters are valid and reshapes the text on\n // the `input` event, so let every key through when one is set.\n if (this.mask) {\n return\n }\n\n // Let typing through, but reject characters that can never be part of a\n // number (porting Base UI's allowed-key guard for parity). Composition\n // (which===229), navigation keys, and modifier combos always pass.\n const allowed = this.getAllowedNonNumericKeys()\n const isAsciiDigit = e.key >= '0' && e.key <= '9'\n const isNamedKey = e.key.length > 1 // ArrowLeft, Backspace, Tab, Enter, …\n const passes\n = e.which === 229\n || e.ctrlKey\n || e.metaKey\n || (e.altKey)\n || isAsciiDigit\n || isNamedKey\n || allowed.has(e.key)\n || ARABIC_DETECT_RE.test(e.key)\n || PERSIAN_DETECT_RE.test(e.key)\n || HAN_DETECT_RE.test(e.key)\n || FULLWIDTH_DETECT_RE.test(e.key)\n || (this.allowsNegative && ANY_MINUS_DETECT_RE.test(e.key))\n || ANY_PLUS_DETECT_RE.test(e.key)\n\n if (!passes) {\n e.preventDefault()\n }\n return\n }\n\n // Parse the current (possibly unblurred) text so edits are honoured.\n const currentValue = this.parseValue\n ? this.parseValue(this.inputText, this.locale, this.format)\n : parseNumber(this.inputText, this.locale, this.format)\n\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault()\n this.incrementValue(this.getStepAmount(e), {\n direction: 1,\n currentValue,\n event: e,\n reason: 'keyboard',\n })\n this.commit('keyboard')\n break\n case 'ArrowDown':\n e.preventDefault()\n this.incrementValue(this.getStepAmount(e), {\n direction: -1,\n currentValue,\n event: e,\n reason: 'keyboard',\n })\n this.commit('keyboard')\n break\n case 'PageUp':\n e.preventDefault()\n // PageUp/Down always use largeStep regardless of modifiers.\n this.incrementValue(this.effectiveLargeStep, { direction: 1, currentValue, reason: 'keyboard' })\n this.commit('keyboard')\n break\n case 'PageDown':\n e.preventDefault()\n this.incrementValue(this.effectiveLargeStep, { direction: -1, currentValue, reason: 'keyboard' })\n this.commit('keyboard')\n break\n case 'Home':\n if (this.min != null && Number.isFinite(this.min)) {\n e.preventDefault()\n this.setValue(this.min, { reason: 'keyboard' })\n this.commit('keyboard')\n }\n break\n case 'End':\n if (this.max != null && Number.isFinite(this.max)) {\n e.preventDefault()\n this.setValue(this.max, { reason: 'keyboard' })\n this.commit('keyboard')\n }\n break\n default:\n break\n }\n }\n\n // ---------------------------------------------------------------------------\n // input / paste / focus / blur\n // ---------------------------------------------------------------------------\n\n /**\n * Whether every character in `text` could legitimately be part of a number in\n * the current locale/format, mirroring Base UI `NumberFieldInput.onChange`'s\n * `isValidCharacterString`. The keydown guard only sees physical keystrokes;\n * this catches disallowed characters arriving via IME composition,\n * drag-and-drop, or a programmatic `input.value` set, so they never land in\n * the bound value.\n */\n private isValidCharacterString(text: string): boolean {\n const allowed = this.getAllowedNonNumericKeys()\n return Array.from(text).every((ch) => {\n const isAsciiDigit = ch >= '0' && ch <= '9'\n return (\n isAsciiDigit\n || ARABIC_DETECT_RE.test(ch)\n || HAN_DETECT_RE.test(ch)\n || PERSIAN_DETECT_RE.test(ch)\n || FULLWIDTH_DETECT_RE.test(ch)\n || (this.allowsNegative && ANY_MINUS_DETECT_RE.test(ch))\n || allowed.has(ch)\n )\n })\n }\n\n private handleInput(e: Event) {\n e.stopPropagation()\n\n // While typing, don't reformat the text from underneath the user.\n this.allowInputSync = false\n\n const input = e.target as HTMLInputElement\n let text = input.value\n\n // A custom mask, when set, reshapes the raw text (grouping separators,\n // decimal-separator localisation, fraction cap, …) and tells us where the\n // caret should land afterwards.\n const mask = this.mask\n if (mask && text.trim() !== '') {\n const masked = mask(\n {\n value: text,\n selectionStart: input.selectionStart ?? text.length,\n selectionEnd: input.selectionEnd ?? text.length,\n },\n { locale: this.locale, format: this.format },\n )\n text = masked.value\n this.pendingSelection = [masked.selectionStart, masked.selectionEnd]\n }\n\n if (text.trim() === '') {\n this.inputText = ''\n this.pendingSelection = undefined\n this.setValue(null, { reason: 'input-clear' })\n return\n }\n\n // Reject input that contains characters that can never be part of a number\n // (composition / drag-drop / programmatic sets bypass the keydown guard);\n // bail before committing so disallowed characters never reach the value. A\n // mask governs character validity itself, so skip the generic guard for it.\n if (!this.mask && !this.isValidCharacterString(text)) {\n return\n }\n\n this.inputText = text\n const parsed = this.parseValue\n ? this.parseValue(text, this.locale, this.format)\n : parseNumber(text, this.locale, this.format)\n if (parsed !== null) {\n this.setValue(parsed, { reason: 'input-change' })\n }\n }\n\n private handlePaste(e: ClipboardEvent) {\n if (e.defaultPrevented || this.readonly || this.disabled) {\n return\n }\n\n // With a custom mask, let the paste land natively; the resulting `input`\n // event runs through the mask, which reshapes pasted text like any insertion.\n if (this.mask) {\n return\n }\n\n const pasted = e.clipboardData?.getData('text/plain') ?? ''\n // Prevent the native change so we control the parsed text.\n e.preventDefault()\n\n const parsed = this.parseValue\n ? this.parseValue(pasted, this.locale, this.format)\n : parseNumber(pasted, this.locale, this.format)\n if (parsed !== null) {\n // Apply the auto (Intl) formatting to pasted content immediately, the same\n // as on blur. `allowInputSync` lets `setValue` refresh the displayed text.\n this.allowInputSync = true\n this.setValue(parsed, { reason: 'input-paste' })\n }\n }\n\n private handleFocus(e: FocusEvent) {\n if (e.defaultPrevented || this.readonly || this.disabled) {\n return\n }\n\n if (this.hasTouchedInput) {\n return\n }\n this.hasTouchedInput = true\n\n // Browsers select the start by default; move the caret to the end on first focus.\n const target = e.currentTarget as HTMLInputElement\n const length = target.value.length\n target.setSelectionRange(length, length)\n }\n\n private handleBlur(e: FocusEvent) {\n if (e.defaultPrevented || this.readonly || this.disabled) {\n return\n }\n\n this.allowInputSync = true\n\n if (this.inputText.trim() === '') {\n this.setValue(null, { reason: 'input-clear' })\n this.commit('input-clear')\n return\n }\n\n const parsed = this.parseValue\n ? this.parseValue(this.inputText, this.locale, this.format)\n : parseNumber(this.inputText, this.locale, this.format)\n if (parsed === null) {\n // The typed text can't be parsed — e.g. stray signs or decimals the\n // lenient per-character guard let through (\"--.-1,234\"). Rather than leave\n // the garbage sitting in the field, revert the display to the last\n // committed value (its canonical format, or empty when there is none). The\n // value itself is unchanged, so no change event fires.\n const reverted = this.formatDisplay(this.value)\n if (this.inputText !== reverted) {\n this.inputText = reverted\n }\n return\n }\n\n const hasRounding = hasNumberFormatRoundingOptions(this.format)\n const committed = hasRounding ? removeFloatingPointErrors(parsed, this.format) : parsed\n\n const shouldUpdate = committed !== this.value\n if (shouldUpdate) {\n this.setValue(committed, { reason: 'input-blur' })\n }\n\n // Normalise the displayed text to the canonical formatted value.\n const canonical = this.formatDisplay(this.value)\n if (this.inputText !== canonical) {\n this.inputText = canonical\n }\n\n this.commit('input-blur')\n }\n\n // ---------------------------------------------------------------------------\n // stepper buttons (press-and-hold)\n // ---------------------------------------------------------------------------\n\n /** Sync the (possibly dirty) input text into `value` before a button press. */\n private commitDirtyInput(reason: NumberFieldChangeReason, direction: 1 | -1) {\n this.allowInputSync = true\n const parsed = this.parseValue\n ? this.parseValue(this.inputText, this.locale, this.format)\n : parseNumber(this.inputText, this.locale, this.format)\n if (parsed !== null) {\n this.setValue(parsed, { reason, direction })\n }\n }\n\n private handleStepPointerDown(e: PointerEvent, direction: 1 | -1) {\n const isMainButton = !e.button || e.button === 0\n if (e.defaultPrevented || this.readonly || this.disabled || !isMainButton) {\n return\n }\n\n const reason: NumberFieldChangeReason\n = direction === 1 ? 'increment-press' : 'decrement-press'\n\n // Pointerdown handles the change here, so suppress the follow-up click\n // (including the synthetic click browsers fire after touch).\n this.skipNextClick = true\n this.activePointerId = e.pointerId\n\n // Sync the dirty input value before stepping.\n this.commitDirtyInput(reason, direction)\n\n if (e.pointerType !== 'touch' && e.pointerType !== 'pen') {\n // Focus the input so keyboard interaction can continue.\n this.inputRef.value?.focus()\n }\n\n // One immediate step, then auto-repeat after the start delay.\n this.allowInputSync = true\n this.incrementValue(this.getStepAmount(e), { direction, event: e, reason })\n\n const target = e.currentTarget as HTMLButtonElement\n try {\n target.setPointerCapture(e.pointerId)\n }\n catch {\n // Ignore: capture isn't essential, pointerup is still observed.\n }\n\n this.holdStartTimer = setTimeout(() => {\n this.holdTickTimer = setInterval(() => {\n this.allowInputSync = true\n this.incrementValue(this.getStepAmount(e), { direction, event: e, reason })\n }, CHANGE_VALUE_TICK_DELAY)\n }, START_AUTO_CHANGE_DELAY)\n }\n\n private handleStepPointerStop(e: PointerEvent, direction: 1 | -1) {\n // Ignore stop events from a different pointer than the one that started.\n if (this.activePointerId !== undefined && this.activePointerId !== e.pointerId) {\n return\n }\n const wasHolding = this.holdStartTimer != null || this.holdTickTimer != null\n this.stopHold()\n this.activePointerId = undefined\n\n // Commit on pointer-up if the pointer press drove the change.\n if (this.skipNextClick || wasHolding) {\n this.commit(direction === 1 ? 'increment-press' : 'decrement-press')\n }\n }\n\n private handleStepClick(e: MouseEvent, direction: 1 | -1) {\n const reason: NumberFieldChangeReason\n = direction === 1 ? 'increment-press' : 'decrement-press'\n\n if (e.defaultPrevented || this.readonly || this.disabled) {\n return\n }\n\n // Pointerdown already handled the change; this suppresses the follow-up click.\n if (this.skipNextClick) {\n this.skipNextClick = false\n return\n }\n\n this.commitDirtyInput(reason, direction)\n this.allowInputSync = true\n const changed = this.incrementValue(this.getStepAmount(e as StepEventLike), {\n direction,\n event: e as StepEventLike,\n reason,\n })\n if (changed) {\n this.commit(reason)\n }\n }\n\n private stopHold() {\n if (this.holdStartTimer != null) {\n clearTimeout(this.holdStartTimer)\n this.holdStartTimer = undefined\n }\n if (this.holdTickTimer != null) {\n clearInterval(this.holdTickTimer)\n this.holdTickTimer = undefined\n }\n }\n\n /** Whether the increment button should be disabled. */\n private get incrementDisabled(): boolean {\n return (\n this.disabled\n || this.readonly\n || (this.value != null && this.value >= this.maxWithDefault)\n )\n }\n\n /** Whether the decrement button should be disabled. */\n private get decrementDisabled(): boolean {\n return (\n this.disabled\n || this.readonly\n || (this.value != null && this.value <= this.minWithDefault)\n )\n }\n\n // ---------------------------------------------------------------------------\n // wheel\n // ---------------------------------------------------------------------------\n\n private attachWheel() {\n const input = this.inputRef.value\n if (!input) {\n return\n }\n input.addEventListener('wheel', this.onWheel, { passive: false })\n this.wheelAttached = true\n }\n\n private detachWheel() {\n const input = this.inputRef.value\n input?.removeEventListener('wheel', this.onWheel)\n this.wheelAttached = false\n }\n\n private handleWheel(e: WheelEvent) {\n // Allow pinch-zoom (ctrlKey) and ignore when the input isn't focused.\n if (e.ctrlKey || this.inputRef.value !== this.getActiveElement()) {\n return\n }\n e.preventDefault()\n this.allowInputSync = true\n const amount = this.getStepAmount(e as StepEventLike)\n this.incrementValue(amount, {\n direction: e.deltaY > 0 ? -1 : 1,\n event: e as StepEventLike,\n reason: 'wheel',\n })\n }\n\n /** The active element within this node's root (document or shadow root). */\n private getActiveElement(): Element | null {\n const root = this.getRootNode() as Document | ShadowRoot\n return root.activeElement\n }\n\n // ---------------------------------------------------------------------------\n // scrub\n //\n // NOTE: this is a SIMPLIFIED port of Base UI's ScrubArea. Pointer Lock, the\n // virtual cursor, and teleport are intentionally OUT OF SCOPE — this is a\n // basic relative drag (movementX * step, gated by pixelSensitivity), like the\n // combobox's \"no virtualization\" note.\n // ---------------------------------------------------------------------------\n\n private handleScrubPointerDown(e: PointerEvent) {\n const isMainButton = !e.button || e.button === 0\n if (e.defaultPrevented || this.readonly || this.disabled || !isMainButton) {\n return\n }\n\n if (e.pointerType === 'mouse') {\n e.preventDefault()\n this.inputRef.value?.focus()\n }\n\n this.scrubbing = true\n this.scrubMoved = false\n this.scrubAccumulator = 0\n this.scrubPointerDownTarget = e.target\n\n const win = this.ownerWindow()\n win.addEventListener('pointermove', this.onScrubMove, true)\n win.addEventListener('pointerup', this.onScrubUp, true)\n }\n\n private handleScrubMove(e: PointerEvent) {\n if (!this.scrubbing) {\n return\n }\n // Prevent text selection while dragging.\n e.preventDefault()\n\n this.scrubAccumulator += e.movementX\n\n if (Math.abs(this.scrubAccumulator) >= SCRUB_PIXEL_SENSITIVITY) {\n this.scrubAccumulator = 0\n this.scrubMoved = true\n const dValue = e.movementX\n const amount = Math.abs(dValue * this.getStepAmount(e as StepEventLike))\n if (amount !== 0) {\n this.allowInputSync = true\n this.incrementValue(amount, {\n direction: dValue >= 0 ? 1 : -1,\n event: e as StepEventLike,\n reason: 'scrub',\n })\n }\n }\n }\n\n private handleScrubUp(e: PointerEvent) {\n this.removeScrubListeners()\n this.scrubbing = false\n this.commit('scrub')\n\n // If no movement happened, synthesise a click on the original target so a\n // click-without-drag still focuses the input.\n if (!this.scrubMoved && this.scrubPointerDownTarget) {\n this.scrubPointerDownTarget.dispatchEvent(\n new MouseEvent('click', { bubbles: true, cancelable: true }),\n )\n }\n this.scrubMoved = false\n this.scrubPointerDownTarget = null\n }\n\n private removeScrubListeners() {\n const win = this.ownerWindow()\n win.removeEventListener('pointermove', this.onScrubMove, true)\n win.removeEventListener('pointerup', this.onScrubUp, true)\n }\n\n private handleScrubTouchStart(e: TouchEvent) {\n if (this.disabled || this.readonly) {\n return\n }\n if (e.touches.length === 1) {\n // Stop the page scrolling while dragging.\n e.preventDefault()\n }\n }\n\n private ownerWindow(): Window {\n return this.ownerDocument.defaultView ?? window\n }\n\n // ---------------------------------------------------------------------------\n // render\n // ---------------------------------------------------------------------------\n\n /**\n * The `inputmode` for the inner input.\n *\n * Mirrors Base UI's `setDynamicInputModeForIOS` intent: the iOS numeric and\n * decimal soft keyboards have no minus key, so when negatives are explicitly\n * allowed (an explicit `min < 0`) we yield `text` so the user can type a\n * minus sign on iOS. Otherwise the base mode is `numeric` when step/min/max\n * are all integers and min >= 0, and `decimal` when fractional values are in\n * play (so the iOS keyboard exposes a decimal point).\n *\n * Base UI swaps to `text`/`decimal` at runtime only on iOS; we compute the\n * mode statically, and `text`/`decimal` are harmless supersets on platforms\n * whose numeric keyboard already has the relevant keys. We gate the `text`\n * mode on the explicit `min` prop (not the `Number.MIN_SAFE_INTEGER`-backed\n * `minWithDefault`) so an unconstrained field keeps the friendlier `numeric`\n * keypad, matching Base UI's default of `numeric`.\n */\n private get computedInputMode(): 'numeric' | 'decimal' | 'text' {\n // iOS numeric/decimal keyboards lack a minus key; fall back to text so a\n // negative value can be entered when negatives are explicitly allowed.\n if (this.min != null && this.min < 0) {\n return 'text'\n }\n // Whole-number fields never accept a decimal point, so the numeric keypad\n // (no decimal key) is always the right soft keyboard.\n if (this.integer) {\n return 'numeric'\n }\n const stepIsInt = this.step === 'any' || Number.isInteger(this.numericStep)\n const minOk = this.min == null || (Number.isInteger(this.min) && this.min >= 0)\n const maxOk = this.max == null || Number.isInteger(this.max)\n return stepIsInt && minOk && maxOk ? 'numeric' : 'decimal'\n }\n\n /**\n * The resolved side for the `currency` symbol: the explicit `currencyPlacement`\n * when it is `'start'`/`'end'`, otherwise derived from the locale/currency via\n * `Intl`. Only meaningful when `currency` is set.\n */\n private get resolvedCurrencyPlacement(): 'start' | 'end' {\n if (this.currencyPlacement === 'start' || this.currencyPlacement === 'end') {\n return this.currencyPlacement\n }\n return this.currency ? resolveCurrencyPlacement(this.locale, this.currency) : 'start'\n }\n\n render() {\n const inputId = this.inputId\n\n // Naming/description from the field context (in a field), the built-in\n // <label for>/hint/error (standalone), or consumer-set host aria-* — all\n // resolved by the FieldControlMixin getters.\n const ariaLabel = this.controlAriaLabel\n const ariaLabelledby = this.controlAriaLabelledby\n\n // Currency convenience: a decorative, locale-aware symbol placed in the\n // resolved slot. It is `aria-hidden` (the number lives in the input's text),\n // so we fold its id into `aria-describedby` — a directly-referenced element\n // still contributes to the accessible description even when hidden — so\n // assistive tech announces the currency alongside the value. This is the\n // non-destructive analogue of NFE's aria-label composition: it works in every\n // labelling mode (field label, `aria-label`, `label` prop) without clobbering\n // the accessible name.\n const currencySymbol = this.currency ? getCurrencySymbol(this.locale, this.currency) : undefined\n const currencyPlacement = this.currency ? this.resolvedCurrencyPlacement : undefined\n const currencySymbolId = this.currency ? `${inputId}-currency` : undefined\n const ariaDescribedby\n = [this.controlAriaDescribedby, currencySymbolId].filter(Boolean).join(' ') || undefined\n\n const renderCurrencySymbol = (side: 'start' | 'end') =>\n currencySymbol != null && currencyPlacement === side\n ? html`<span id=${currencySymbolId} class=\"n-currency-symbol\" aria-hidden=\"true\">${currencySymbol}</span>`\n : nothing\n\n return html`\n ${this.renderLabel()}\n\n <div\n class=${classMap({\n 'n-number-field': true,\n 'is-scrubbing': this.scrubbing,\n })}\n >\n ${this.scrub\n ? html`\n <!-- A drag-to-scrub handle. It is purely a pointer affordance\n (role=\"presentation\"); the field's accessible name still comes from\n the external nord-field-label pointed at the input id, so keyboard\n and AT users are unaffected. The grip mirrors Base UI's ew-resize\n cursor icon. -->\n <div\n class=\"n-scrub\"\n role=\"presentation\"\n aria-hidden=\"true\"\n @pointerdown=${this.handleScrubPointerDown}\n @touchstart=${this.handleScrubTouchStart}\n >\n <svg\n class=\"n-scrub-grip\"\n width=\"24\"\n height=\"14\"\n viewBox=\"0 0 24 14\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M19.5 5.5L6.49737 5.51844V2L1 6.9999L6.5 12L6.49737 8.5L19.5 8.5V12L25 6.9999L19.5 2V5.5Z\"\n ></path>\n </svg>\n </div>\n `\n : nothing}\n\n <div class=${classMap({ 'n-control': true, 'is-invalid': this.effectiveInvalid })}>\n ${this.hideControls\n ? nothing\n : html`\n <button\n class=${classMap({ 'n-step': true, 'n-decrement': true })}\n type=\"button\"\n tabindex=\"-1\"\n aria-label=${this.localize.term('decreaseLabel')}\n aria-controls=${inputId}\n aria-readonly=${this.readonly ? 'true' : nothing}\n ?disabled=${this.decrementDisabled}\n @pointerdown=${(e: PointerEvent) => this.handleStepPointerDown(e, -1)}\n @pointerup=${(e: PointerEvent) => this.handleStepPointerStop(e, -1)}\n @pointerleave=${(e: PointerEvent) => this.handleStepPointerStop(e, -1)}\n @pointercancel=${(e: PointerEvent) => this.handleStepPointerStop(e, -1)}\n @click=${(e: MouseEvent) => this.handleStepClick(e, -1)}\n >\n <nord-icon name=\"interface-remove-small\"></nord-icon>\n </button>\n `}\n\n <span class=\"n-number-field-slot n-number-field-slot-start\">${renderCurrencySymbol('start')}</span>\n\n <input\n ${ref(this.inputRef)}\n class=\"n-input\"\n type=\"text\"\n id=${inputId}\n inputmode=${this.computedInputMode}\n .value=${this.inputText}\n placeholder=${this.placeholder ?? nothing}\n ?disabled=${this.effectiveDisabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n autocomplete=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n aria-roledescription=${this.localize.term('roleDescription')}\n aria-label=${ariaLabel ?? nothing}\n aria-labelledby=${ariaLabelledby ?? nothing}\n aria-describedby=${ariaDescribedby ?? nothing}\n aria-invalid=${this.controlAriaInvalid ?? nothing}\n aria-required=${this.required ? 'true' : nothing}\n aria-readonly=${this.readonly ? 'true' : nothing}\n @input=${this.handleInput}\n @blur=${this.handleBlur}\n @focus=${this.handleFocus}\n @keydown=${this.handleKeydown}\n @paste=${this.handlePaste}\n />\n\n <span class=\"n-number-field-slot n-number-field-slot-end\">${renderCurrencySymbol('end')}</span>\n\n ${this.hideControls\n ? nothing\n : html`\n <button\n class=${classMap({ 'n-step': true, 'n-increment': true })}\n type=\"button\"\n tabindex=\"-1\"\n aria-label=${this.localize.term('increaseLabel')}\n aria-controls=${inputId}\n aria-readonly=${this.readonly ? 'true' : nothing}\n ?disabled=${this.incrementDisabled}\n @pointerdown=${(e: PointerEvent) => this.handleStepPointerDown(e, 1)}\n @pointerup=${(e: PointerEvent) => this.handleStepPointerStop(e, 1)}\n @pointerleave=${(e: PointerEvent) => this.handleStepPointerStop(e, 1)}\n @pointercancel=${(e: PointerEvent) => this.handleStepPointerStop(e, 1)}\n @click=${(e: MouseEvent) => this.handleStepClick(e, 1)}\n >\n <nord-icon name=\"interface-add-small\"></nord-icon>\n </button>\n `}\n </div>\n </div>\n\n ${this.renderError()}\n ${this.isHintBelow ? this.renderHint() : nothing}\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nord-number-field': NumberField\n }\n}\n"],"names":["Icon","registerIcon","addIcon","removeIcon","numberFieldCount","sanitizeStep","value","fallback","Number","isFinite","NumberField","DraftComponentMixin","SizeMixin","FieldControlMixin","LitElement","constructor","this","numberFieldId","inputId","localize","LocalizeController","inputRef","createRef","formData","FormDataController","undefined","String","stateAttributes","StateAttributesController","invalid","effectiveInvalid","trackFocus","formAncestor","step","largeStep","smallStep","snapOnStep","allowOutOfRange","integer","allowWheelScrub","scrub","disabled","readonly","hideControls","currencyPlacement","inputText","scrubbing","allowInputSync","hasTouchedInput","skipNextClick","scrubAccumulator","scrubMoved","scrubPointerDownTarget","onScrubMove","e","handleScrubMove","onScrubUp","handleScrubUp","onWheel","handleWheel","wheelAttached","ownInvalid","super","form","id","oldVal","_formId","requestUpdate","getRootNode","querySelector","minWithDefault","_a","min","MIN_SAFE_INTEGER","maxWithDefault","max","MAX_SAFE_INTEGER","minWithZeroDefault","allowsNegative","numericStep","effectiveLargeStep","effectiveSmallStep","formatDisplay","formatValue","locale","format","formatNumber","connectedCallback","injectLightDomStyles","style","closest","ariaObserver","MutationObserver","observe","attributes","attributeFilter","_b","slotObserver","childList","disconnectedCallback","disconnect","stopHold","detachWheel","removeScrubListeners","createRenderRoot","isServer","root","document","createElement","className","appendChild","relocateSlots","move","name","target","child","Array","from","children","getAttribute","parentElement","startZone","endZone","willUpdate","changed","has","clamped","clamp","isInteger","Math","round","updated","wheelWanted","attachWheel","pendingSelection","start","end","setSelectionRange","focus","options","isTextReason","reason","getStepAmount","event","altKey","shiftKey","setValue","unvalidated","direction","shouldClamp","validated","toValidatedNumber","small","shouldFire","dispatchEvent","NordEvent","incrementValue","amount","currentValue","prev","next","commit","NumberFieldChangeEvent","getAllowedNonNumericKeys","decimal","group","currency","literal","getNumberLocaleDetails","keys","Set","BASE_NON_NUMERIC_SYMBOLS","forEach","symbol","add","SPACE_SEPARATOR_RE","test","formatStyle","allowPercent","unit","allowPermille","_c","PERCENTAGES","key","PERMILLE","char","PLUS_SIGNS_WITH_ASCII","MINUS_SIGNS_WITH_ASCII","separator","delete","handleKeydown","defaultPrevented","mask","allowed","isAsciiDigit","isNamedKey","length","which","ctrlKey","metaKey","ARABIC_DETECT_RE","PERSIAN_DETECT_RE","HAN_DETECT_RE","FULLWIDTH_DETECT_RE","ANY_MINUS_DETECT_RE","ANY_PLUS_DETECT_RE","preventDefault","parseValue","parseNumber","isValidCharacterString","text","every","ch","handleInput","stopPropagation","input","trim","masked","selectionStart","selectionEnd","parsed","handlePaste","pasted","clipboardData","getData","handleFocus","currentTarget","handleBlur","reverted","committed","hasNumberFormatRoundingOptions","removeFloatingPointErrors","canonical","commitDirtyInput","handleStepPointerDown","isMainButton","button","activePointerId","pointerId","pointerType","setPointerCapture","holdStartTimer","setTimeout","holdTickTimer","setInterval","handleStepPointerStop","wasHolding","handleStepClick","clearTimeout","clearInterval","incrementDisabled","decrementDisabled","addEventListener","passive","removeEventListener","getActiveElement","deltaY","activeElement","handleScrubPointerDown","win","ownerWindow","movementX","abs","dValue","MouseEvent","bubbles","cancelable","handleScrubTouchStart","touches","ownerDocument","defaultView","window","computedInputMode","stepIsInt","minOk","maxOk","resolvedCurrencyPlacement","resolveCurrencyPlacement","render","ariaLabel","controlAriaLabel","ariaLabelledby","controlAriaLabelledby","currencySymbol","getCurrencySymbol","currencySymbolId","ariaDescribedby","controlAriaDescribedby","filter","Boolean","join","renderCurrencySymbol","side","html","nothing","renderLabel","classMap","term","ref","placeholder","effectiveDisabled","required","controlAriaInvalid","renderError","isHintBelow","renderHint","__decorate","query","prototype","property","converter","attr","num","isNaN","reflect","type","attribute","state","customElement"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{N as e}from"./events-Bv6wNHwJ.js";class t extends e{constructor(e,s){super(t.eventName),this.value=e,this.reason=s}get detail(){return this.value}}t.eventName="change";export{t as NumberFieldChangeEvent};
2
+ //# sourceMappingURL=NumberFieldEvents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberFieldEvents.js","sources":["../src/number-field/NumberFieldEvents.ts"],"sourcesContent":["import { NordEvent } from '../common/events.js'\n\n/**\n * The reason a number field value changed, mirroring Base UI's reason union.\n *\n * - `input-change` — a parseable value was typed (or set programmatically as text)\n * - `input-clear` — the field was emptied\n * - `input-blur` — the value was reformatted (and clamped, if enabled) on blur\n * - `input-paste` — a value was pasted\n * - `keyboard` — an Arrow / Page / Home / End key stepped the value\n * - `increment-press` / `decrement-press` — a stepper button changed the value\n * - `wheel` — the mouse wheel scrubbed the value\n * - `scrub` — the scrub area was dragged\n * - `none` — a programmatic / autofill change with no specific reason\n */\nexport type NumberFieldChangeReason\n = | 'input-change'\n | 'input-clear'\n | 'input-blur'\n | 'input-paste'\n | 'keyboard'\n | 'increment-press'\n | 'decrement-press'\n | 'wheel'\n | 'scrub'\n | 'none'\n\n/**\n * Dispatched when the number field value is committed (on blur, on keyboard\n * step, or on pointer-up after a button hold or scrub drag). Carries the raw\n * numeric value and the reason it changed, mirroring Base UI `onValueCommitted`.\n *\n * The bare event name is `change`, so it composes with native form expectations\n * exactly like the combobox's `change`.\n */\nexport class NumberFieldChangeEvent extends NordEvent {\n static eventName = 'change'\n\n constructor(\n /** The committed numeric value, or `null` when the field is empty. */\n public readonly value: number | null,\n /** What triggered the commit. */\n public readonly reason: NumberFieldChangeReason,\n ) {\n super(NumberFieldChangeEvent.eventName)\n }\n\n /** Convenience accessor mirroring `CustomEvent.detail`. */\n get detail() {\n return this.value\n }\n}\n"],"names":["NumberFieldChangeEvent","NordEvent","constructor","value","reason","super","eventName","this","detail"],"mappings":"yCAmCM,MAAOA,UAA+BC,EAG1C,WAAAC,CAEkBC,EAEAC,GAEhBC,MAAML,EAAuBM,WAJbC,KAAKJ,MAALA,EAEAI,KAAMH,OAANA,CAGjB,CAGD,UAAII,GACF,OAAOD,KAAKJ,KACb,EAdMH,EAASM,UAAG"}
@@ -0,0 +1,2 @@
1
+ import{N as o}from"./events-Bv6wNHwJ.js";class s{constructor(o,s){this.host=o,this.options=s,this.onPopoutOpen=o=>{o.stopPropagation()},this.onPopoutClose=o=>{o.stopPropagation(),this.options.setOpen(!1)},o.addController(this)}hostUpdate(){var o,s;this.options.isOpen()&&(null===(s=(o=this.options).isInert)||void 0===s?void 0:s.call(o))&&this.options.setOpen(!1)}hostUpdated(){var s,t,i,n,p,e;const h=this.options.isOpen();if(h===this.previousOpen)return;const l=void 0===this.previousOpen;this.previousOpen=h,l||(h?(null===(s=this.options.popout())||void 0===s||s.show(),null===(i=(t=this.options).onOpen)||void 0===i||i.call(t),this.host.dispatchEvent(new o("open"))):(null===(n=this.options.popout())||void 0===n||n.hide(!1),null===(e=(p=this.options).onClose)||void 0===e||e.call(p),this.host.dispatchEvent(new o("close"))))}show(){var o,s;this.options.isOpen()||(null===(s=(o=this.options).isInert)||void 0===s?void 0:s.call(o))||this.options.setOpen(!0)}hide(){this.options.isOpen()&&this.options.setOpen(!1)}toggle(){this.options.isOpen()?this.hide():this.show()}}export{s as O};
2
+ //# sourceMappingURL=OpenStateController-CCnZ7up6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenStateController-CCnZ7up6.js","sources":["../src/common/controllers/OpenStateController.ts"],"sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit'\n\nimport { NordEvent } from '../events.js'\n\nexport interface PopoutLike {\n show: () => Promise<unknown>\n hide: (moveFocusToButton?: boolean) => Promise<unknown>\n}\n\nexport interface OpenStateOptions {\n /** Reads the host's `open` state. */\n isOpen: () => boolean\n /** Writes the host's `open` state. */\n setOpen: (open: boolean) => void\n /** The `nord-popout` to drive (queried lazily; may be undefined before render). */\n popout: () => PopoutLike | undefined\n /** True when the host can't be opened (disabled and/or read-only). */\n isInert?: () => boolean\n /** Side effects to run when the popout has opened (seed state, reset scroll…). */\n onOpen?: () => void\n /** Side effects to run when the popout has closed (clear search…). */\n onClose?: () => void\n}\n\n/**\n * Coordinates a host's `open` property with its `nord-popout` overlay, so all\n * the popout-backed components open/close consistently. Setting `open` drives\n * `popout.show()`/`hide()` (the popout only fires events / manages the top layer\n * through those, not via an attribute); the popout's own `open`/`close` events\n * sync `open` back and the host emits exactly one canonical `open`/`close`.\n * Opening is rejected while the host is inert (disabled / read-only).\n *\n * Wire the popout's events to {@link onPopoutOpen}/{@link onPopoutClose} in the\n * template, and call {@link show}/{@link hide}/{@link toggle} from triggers.\n */\nexport class OpenStateController implements ReactiveController {\n private previousOpen?: boolean\n\n constructor(\n private host: ReactiveControllerHost & HTMLElement,\n private options: OpenStateOptions,\n ) {\n host.addController(this)\n }\n\n hostUpdate() {\n // Reject an open while inert before render, so it folds into this cycle\n // (no extra update) and `hostUpdated` then keeps the popout closed.\n if (this.options.isOpen() && this.options.isInert?.()) {\n this.options.setOpen(false)\n }\n }\n\n hostUpdated() {\n const open = this.options.isOpen()\n if (open === this.previousOpen) {\n return\n }\n const first = this.previousOpen === undefined\n this.previousOpen = open\n\n // The first observed value is the settled initial state — don't drive the\n // popout or emit an event for it (and avoid touching the popout @query\n // before the first render).\n if (first) {\n return\n }\n\n // `open` is the source of truth: drive the popout and emit the one canonical\n // event here. show()/hide() are idempotent, so the round trip with\n // onPopoutClose (which syncs `open` when the popout self-closes) doesn't loop.\n if (open) {\n void this.options.popout()?.show()\n this.options.onOpen?.()\n this.host.dispatchEvent(new NordEvent('open'))\n }\n else {\n void this.options.popout()?.hide(false)\n this.options.onClose?.()\n this.host.dispatchEvent(new NordEvent('close'))\n }\n }\n\n /** Open the popout programmatically (no-op when already open or inert). */\n show() {\n if (this.options.isOpen() || this.options.isInert?.()) {\n return\n }\n this.options.setOpen(true)\n }\n\n /** Close the popout programmatically (no-op when already closed). */\n hide() {\n if (!this.options.isOpen()) {\n return\n }\n this.options.setOpen(false)\n }\n\n /** Toggle the popout (respecting the inert guard). */\n toggle() {\n if (this.options.isOpen()) {\n this.hide()\n }\n else {\n this.show()\n }\n }\n\n /**\n * Bind to the popout's `@open`. The canonical `open` is property-driven (see\n * `hostUpdated`) — the host opens via {@link show}/{@link toggle} from its\n * trigger — so this only swallows the popout's own bubbling event. (It must\n * NOT set `open` here: the popout's `open` fires asynchronously and could\n * otherwise re-open after a quick close.)\n */\n onPopoutOpen = (e: Event) => {\n e.stopPropagation()\n }\n\n /**\n * Bind to the popout's `@close`: swallow the popout's own event and sync\n * `open` so the host (via `hostUpdated`) emits the one canonical `close` when\n * the popout closes itself (e.g. light dismiss).\n */\n onPopoutClose = (e: Event) => {\n e.stopPropagation()\n this.options.setOpen(false)\n }\n}\n"],"names":["OpenStateController","constructor","host","options","this","onPopoutOpen","e","stopPropagation","onPopoutClose","setOpen","addController","hostUpdate","isOpen","_b","_a","isInert","call","hostUpdated","open","previousOpen","first","undefined","popout","show","_c","onOpen","dispatchEvent","NordEvent","_d","hide","_f","onClose","toggle"],"mappings":"+CAmCaA,EAGX,WAAAC,CACUC,EACAC,GADAC,KAAIF,KAAJA,EACAE,KAAOD,QAAPA,EA4EVC,KAAAC,aAAgBC,IACdA,EAAEC,iBAAiB,EAQrBH,KAAAI,cAAiBF,IACfA,EAAEC,kBACFH,KAAKD,QAAQM,SAAQ,EAAM,EArF3BP,EAAKQ,cAAcN,KACpB,CAED,UAAAO,WAGMP,KAAKD,QAAQS,WAAoC,QAAxBC,GAAAC,EAAAV,KAAKD,SAAQY,eAAW,IAAAF,OAAA,EAAAA,EAAAG,KAAAF,KACnDV,KAAKD,QAAQM,SAAQ,EAExB,CAED,WAAAQ,mBACE,MAAMC,EAAOd,KAAKD,QAAQS,SAC1B,GAAIM,IAASd,KAAKe,aAChB,OAEF,MAAMC,OAA8BC,IAAtBjB,KAAKe,aACnBf,KAAKe,aAAeD,EAKhBE,IAOAF,GAC0B,QAAvBJ,EAAAV,KAAKD,QAAQmB,gBAAU,IAAAR,GAAAA,EAAAS,eAC5BC,KAAApB,KAAKD,SAAQsB,+BACbrB,KAAKF,KAAKwB,cAAc,IAAIC,EAAU,WAGZ,QAArBC,EAAAxB,KAAKD,QAAQmB,gBAAQ,IAAAM,GAAAA,EAAEC,MAAK,WACjCC,KAAA1B,KAAKD,SAAQ4B,gCACb3B,KAAKF,KAAKwB,cAAc,IAAIC,EAAU,WAEzC,CAGD,IAAAJ,WACMnB,KAAKD,QAAQS,WAAoC,QAAxBC,GAAAC,EAAAV,KAAKD,SAAQY,eAAW,IAAAF,OAAA,EAAAA,EAAAG,KAAAF,KAGrDV,KAAKD,QAAQM,SAAQ,EACtB,CAGD,IAAAoB,GACOzB,KAAKD,QAAQS,UAGlBR,KAAKD,QAAQM,SAAQ,EACtB,CAGD,MAAAuB,GACM5B,KAAKD,QAAQS,SACfR,KAAKyB,OAGLzB,KAAKmB,MAER"}
@@ -0,0 +1,2 @@
1
+ import{_ as t}from"./tslib.es6-CmLYFWVC.js";import{css as e,nothing as i,html as o,LitElement as n}from"lit";import{property as l,customElement as s}from"lit/decorators.js";import{ifDefined as r}from"lit/directives/if-defined.js";import{F as a}from"./FormDataController-OUt5L5uC.js";import{S as d}from"./StateAttributesController-BIh96sXZ.js";import{o as h}from"./observe-D0n0zOfU.js";import{N as u}from"./events-Bv6wNHwJ.js";import{i as c}from"./light-dom-styles-DXsbiKU9.js";import{D as p}from"./DraftComponentMixin-4qug5Rky.js";import{F as v}from"./FieldControlMixin-BXNZJXu9.js";import{I as f}from"./InputMixin-LetXsCyv.js";import{S as g}from"./SizeMixin-CU9cLbLC.js";import{LocalizeController as m}from"./LocalizeController.js";import{OtpFieldCompleteEvent as b,OtpFieldInvalidEvent as y}from"./OtpFieldEvents.js";import"./context-consumer-BJVUulGf.js";import"./context-request-event-CCRlXoeR.js";import"./field-context.js";import"./create-context-CJ69ntlY.js";import"./SlotController-Z6eG7LSZ.js";import"./EventController-BBOmvfLa.js";import"./VisuallyHidden.js";import"./translation.js";import"./en-us.js";import"./localization.js";import"./localization2.js";import"./localization3.js";import"./localization4.js";import"./localization5.js";import"./localization6.js";import"./localization7.js";import"./localization8.js";import"./localization9.js";import"./localization10.js";import"./localization11.js";import"./localization12.js";import"./localization13.js";import"./localization14.js";import"./localization15.js";import"./localization16.js";import"./localization17.js";import"./localization18.js";import"./localization19.js";import"./localization20.js";import"./localization21.js";import"./localization22.js";const z=e`nord-otp-field,nord-otp-field *,nord-otp-field :after,nord-otp-field :before{box-sizing:border-box}nord-otp-field{--n-otp-field-gap:var(--n-space-s);--n-otp-field-background:var(--n-color-surface);--n-otp-field-border-color:var(--n-color-border-strong);--n-otp-field-border-radius:var(--n-border-radius-s);--_n-otp-field-cell-size:var(--n-otp-field-cell-size,var(--n-space-xl));--_n-otp-field-min-content-block-size:calc(var(--n-line-height-form) + var(--n-space-s)/1.6*2 + 2px);--_n-otp-field-font-size:var(--n-otp-field-font-size,var(--n-font-size-m));display:block}nord-otp-field .n-otp-field{align-items:center;display:flex;gap:var(--n-otp-field-gap)}nord-otp-field .n-cell{appearance:none;background:var(--n-otp-field-background);block-size:var(--_n-otp-field-cell-size);border:1px solid var(--n-otp-field-border-color);border-radius:var(--n-otp-field-border-radius);color:var(--n-color-text);flex-shrink:0;font-family:var(--n-font-family);font-feature-settings:var(--n-font-features);font-size:var(--_n-otp-field-font-size);inline-size:var(--_n-otp-field-cell-size);line-height:var(--n-line-height-form);margin:0;padding:0;text-align:center;transition:border var(--n-transition-quickly),box-shadow var(--n-transition-quickly),background var(--n-transition-quickly)}nord-otp-field .n-cell::placeholder{color:var(--n-color-text-weakest);opacity:1}nord-otp-field .n-cell:hover{border-color:var(--n-color-border-hover)}nord-otp-field .n-cell:focus{border-color:var(--n-color-accent);box-shadow:0 0 0 1px var(--n-color-accent);outline:none}nord-otp-field[invalid] .n-cell{border-color:var(--n-color-border-danger)}nord-otp-field[invalid] .n-cell:focus{border-color:var(--n-color-status-danger);box-shadow:0 0 0 1px var(--n-color-status-danger)}nord-otp-field[disabled] .n-cell{background:var(--n-color-active);border-color:var(--n-color-active);color:var(--n-color-text-weakest);cursor:not-allowed}nord-otp-field[readonly] .n-cell{cursor:default}nord-otp-field .n-separator{background:var(--n-color-border-strong);block-size:1px;flex-shrink:0;inline-size:var(--n-space-s)}nord-otp-field .n-hidden-input{block-size:1px;inline-size:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;clip:rect(0,0,0,0);border:0;white-space:nowrap}nord-otp-field[size=s]{--_n-otp-field-cell-size:var(--n-otp-field-cell-size,calc(var(--n-space-l) + var(--n-space-xs)));--_n-otp-field-font-size:var(--n-otp-field-font-size,var(--n-font-size-s))}nord-otp-field[size=l]{--_n-otp-field-cell-size:max(var(--n-otp-field-cell-size,calc(var(--n-space-xxl) - var(--n-space-l))),var(--_n-otp-field-min-content-block-size));--_n-otp-field-font-size:var(--n-otp-field-font-size,var(--n-font-size-l))}`,x={numeric:{slotPattern:"\\d{1}",rootPattern:t=>`\\d{${t}}`,regexp:/\D/g,inputMode:"numeric"},alphanumeric:{slotPattern:"[a-zA-Z0-9]{1}",rootPattern:t=>`[a-zA-Z0-9]{${t}}`,regexp:/[^a-z0-9]/gi,inputMode:"text"}};function $(t,e,i){const o=function(t){return(null!=t?t:"").replace(/\s/g,"")}(t),n=function(t,e){return t.replace(e.regexp,"")}(o,i),l=o.length>n.length,s=e<0?0:e,r=Array.from(n);return[r.slice(0,s).join(""),l||r.length>s]}function j(t,e,i){return $(t,e,i)[0]}function k(t,e,i,o,n){const l=j(i,o,n);return j(`${t.slice(0,e)}${l}${t.slice(e+l.length)}`,o,n)}function I(t,e){return e<0||e>=t.length?t:`${t.slice(0,e)}${t.slice(e+1)}`}let w=1,A=class extends(p(g(v(f(n))))){constructor(){super(...arguments),this.otpId="nord-otp-field-"+w++,this.localize=new m(this),this.formData=new a(this,{value:()=>this.value||void 0}),this.stateAttributes=new d(this,(()=>({invalid:this.invalid})),{trackFocus:!0}),this.pendingFocus=null,this.pendingComplete=null,this.focused=!1,this.focusedIndex=0,this.length=6,this.type="numeric",this.readonly=!1,this.mask=!1,this.invalid=!1,this.autocomplete="one-time-code",this.groupSize=0,this._value="",this.lastReason="input-change"}get ownInvalid(){return this.invalid||super.ownInvalid}get complete(){return this.length>0&&this._value.length===this.length}get value(){return this._value}set value(t){const e=this._value,i=j(t,this.length,this.config);i!==e&&(this._value=i,this.requestUpdate("value",e))}get config(){var t;return null!==(t=x[this.type])&&void 0!==t?t:x.numeric}get hasValidLength(){return Number.isInteger(this.length)&&this.length>0}get activeIndex(){const t=Math.max(this.length-1,0);return this.focused?Math.min(Math.max(this.focusedIndex,0),t):Math.min(this.value.length,t)}connectedCallback(){var t;super.connectedCallback(),c(this,z),this.inputId=this.cellId(0),null!==(t=this.ariaObserver)&&void 0!==t||(this.ariaObserver=new MutationObserver((()=>this.requestUpdate()))),this.ariaObserver.observe(this,{attributes:!0,attributeFilter:["aria-label","aria-labelledby","aria-describedby"]})}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this.ariaObserver)||void 0===t||t.disconnect(),this.ariaObserver=void 0}createRenderRoot(){return this}renormalize(){const t=j(this._value,this.length,this.config);t!==this._value&&(this._value=t,this.requestUpdate())}flushPending(){if(null!=this.pendingComplete){const t=this.pendingComplete;this.pendingComplete=null,t===this.value&&this.dispatchEvent(new b(t))}if(null!=this.pendingFocus){const t=this.pendingFocus;this.pendingFocus=null,t.value===this.value&&this.focusInput(t.index)}}get cells(){return Array.from(this.querySelectorAll("input.n-cell"))}focusInput(t){const e=this.cells,i=e[Math.min(Math.max(t,0),Math.max(e.length-1,0))];null==i||i.focus(),null==i||i.select()}queueFocusInput(t,e){this.pendingFocus={index:t,value:e}}focus(t){var e;null===(e=this.cells[this.activeIndex])||void 0===e||e.focus(t)}setValue(t){const e=j(t,this.length,this.config),i=this.value.length===this.length,o=e.length===this.length&&(!i||"input-paste"===this.lastReason);return e===this.value?(o&&(this.pendingComplete=e,this.requestUpdate()),null):(this.value=e,this.dispatchEvent(new u("input")),this.dispatchEvent(new u("change")),this.pendingComplete=o?e:null,e)}reportInvalid(t){this.dispatchEvent(new y(t))}handleMousedown(t,e){t.defaultPrevented||this.disabled||(t.preventDefault(),this.focusInput(e))}handleInput(t,e){var i;if(t.stopPropagation(),this.disabled||this.readonly)return;const o=t.target,n=o.value,[l,s]=$(n,this.length,this.config);if(s&&(this.lastReason="input-change",this.reportInvalid(n)),""===l){const t=null!==(i=this.value[e])&&void 0!==i?i:"";return void(""===n?(this.lastReason="input-clear",this.setValue(I(this.value,e))):(o.value=t,o.select()))}this.lastReason="input-change";const r=k(this.value,e,l,this.length,this.config),a=this.setValue(r);null!=a&&this.queueFocusInput(Math.min(e+l.length,this.length-1),a)}handleKeydown(t,e){var i;if(this.disabled)return;const o=Math.max(this.length-1,0),n=Math.min(this.value.length,o),l=(t.ctrlKey||t.metaKey)&&!t.altKey,s="rtl"===this.resolveDirection(),r=s?"ArrowRight":"ArrowLeft",a=s?"ArrowLeft":"ArrowRight";if(t.key===r)return this.stopEvent(t),void this.focusInput(l?0:Math.max(0,e-1));if(t.key===a)return this.stopEvent(t),void this.focusInput(l?n:Math.min(o,e+1));if("Home"===t.key||"ArrowUp"===t.key)return this.stopEvent(t),void this.focusInput(0);if("End"===t.key||"ArrowDown"===t.key)return this.stopEvent(t),void this.focusInput(n);if(this.readonly)return;if("Backspace"===t.key&&l)return this.stopEvent(t),this.lastReason="keyboard",void(null!=this.setValue("")&&this.queueFocusInput(0,""));if("Delete"===t.key){this.stopEvent(t),this.lastReason="keyboard";const i=I(this.value,e),o=this.setValue(i);return void(null!=o&&this.queueFocusInput(e,o))}const d=null!==(i=this.value[e])&&void 0!==i?i:"",h=t.currentTarget,u=0===h.selectionStart&&h.selectionEnd===h.value.length;if(1===t.key.length&&u&&d===t.key)return this.stopEvent(t),void(e<this.length-1&&this.focusInput(e+1));if("Backspace"===t.key){this.stopEvent(t),this.lastReason="keyboard";const i=Math.max(0,e-1),o=""===d?i:e,n=this.setValue(I(this.value,o));null!=n&&this.queueFocusInput(i,n)}}handlePaste(t,e){var i,o;if(this.disabled||this.readonly)return;let n="";try{n=null!==(o=null===(i=t.clipboardData)||void 0===i?void 0:i.getData("text/plain"))&&void 0!==o?o:""}catch(t){return}t.preventDefault();const[l,s]=$(n,this.length,this.config);if(this.lastReason="input-paste",s&&this.reportInvalid(n),""===l)return;const r=k(this.value,e,l,this.length,this.config),a=this.setValue(r);null!=a&&this.queueFocusInput(Math.min(e+l.length,this.length-1),a)}handleFocus(t,e){if(this.disabled)return;if(e>this.value.length)return void this.focusInput(Math.min(this.value.length,this.length-1));this.focusedIndex=e,this.focused=!0,this.requestUpdate();t.currentTarget.select()}handleBlur(t){t.relatedTarget instanceof Node&&this.contains(t.relatedTarget)||(this.focused=!1,this.requestUpdate())}handleHiddenFocus(){this.focusInput(0)}handleHiddenInput(t){if(t.stopPropagation(),this.disabled||this.readonly)return;const e=t.target,[i,o]=$(e.value,this.length,this.config);this.lastReason="input-change",o&&this.reportInvalid(e.value);const n=this.setValue(i);null!=n&&""!==n&&this.queueFocusInput(n.length-1,n)}resolveDirection(){var t,e;return"rtl"===(null!==(e=null===(t=this.closest("[dir]"))||void 0===t?void 0:t.getAttribute("dir"))&&void 0!==e?e:"undefined"!=typeof document?document.documentElement.getAttribute("dir"):null)?"rtl":"ltr"}stopEvent(t){t.preventDefault(),t.stopPropagation()}cellId(t){var e;return`${null!==(e=this.getAttribute("id"))&&void 0!==e?e:this.otpId}-${t+1}`}render(){if(!this.hasValidLength)return i;const t=this.config,e=this.value,n=this.activeIndex,l=`${this.otpId}-group`,s=this.controlAriaLabel,a=this.controlAriaLabelledby,d=this.controlAriaDescribedby,h=[];for(let i=0;i<this.length;i++)h.push(this.renderCell(i,e,t,n,s,a)),this.groupSize>0&&(i+1)%this.groupSize==0&&i<this.length-1&&h.push(o`<span class="n-separator" aria-hidden="true"></span>`);return o`${this.renderLabel()}<div class="n-otp-field" id="${l}" role="group" aria-label="${r(s)}" aria-labelledby="${r(a)}" aria-describedby="${r(d)}">${h}</div><input class="n-hidden-input" type="text" aria-hidden="true" tabindex="-1" .value="${e}" autocomplete="${this.autocomplete}" inputmode="${t.inputMode}" minlength="${this.length}" maxlength="${this.length}" pattern="${t.rootPattern(this.length)}" ?disabled="${this.effectiveDisabled}" ?readonly="${this.readonly}" ?required="${this.required}" aria-invalid="${r(!this.effectiveDisabled&&this.effectiveInvalid?"true":void 0)}" @focus="${this.handleHiddenFocus}" @input="${this.handleHiddenInput}"> ${this.renderError()} ${this.isHintBelow?this.renderHint():i}`}renderCell(t,e,i,n,l,s){var a;const d=null!==(a=e[t])&&void 0!==a?a:"",h=""!==d,u=0===t?void 0:this.localize.term("characterLabel",t+1,this.length),c=0===t?s:void 0,p=0===t?l:void 0;return o`<input class="n-cell" id="${this.cellId(t)}" .value="${d}" type="${this.mask?"password":"text"}" inputmode="${i.inputMode}" autocomplete="${0===t?this.autocomplete:"off"}" autocorrect="off" spellcheck="false" enterkeyhint="${t===this.length-1?"done":"next"}" maxlength="${r(0===t?this.length:void 0)}" pattern="${i.slotPattern}" placeholder="${r(this.placeholder)}" tabindex="${n===t?0:-1}" ?disabled="${this.effectiveDisabled}" ?readonly="${this.readonly}" aria-label="${r(null!=u?u:p)}" aria-labelledby="${r(null==u?c:void 0)}" aria-invalid="${r(!this.effectiveDisabled&&this.effectiveInvalid?"true":void 0)}" data-filled="${r(h?"":void 0)}" @mousedown="${e=>this.handleMousedown(e,t)}" @input="${e=>this.handleInput(e,t)}" @keydown="${e=>this.handleKeydown(e,t)}" @paste="${e=>this.handlePaste(e,t)}" @focus="${e=>this.handleFocus(e,t)}" @blur="${t=>this.handleBlur(t)}">`}updated(t){super.updated(t),this.toggleAttribute("complete",this.complete),this.toggleAttribute("data-complete",this.complete),this.toggleAttribute("data-filled",this.value.length>0),this.toggleAttribute("data-disabled",this.disabled),this.toggleAttribute("data-readonly",this.readonly),this.toggleAttribute("data-required",this.required),this.flushPending()}};t([l({reflect:!0,type:Number})],A.prototype,"length",void 0),t([l({reflect:!0})],A.prototype,"type",void 0),t([l({reflect:!0,type:Boolean})],A.prototype,"readonly",void 0),t([l({reflect:!0,type:Boolean})],A.prototype,"mask",void 0),t([l({reflect:!0})],A.prototype,"placeholder",void 0),t([l({reflect:!0,type:Boolean})],A.prototype,"invalid",void 0),t([l()],A.prototype,"autocomplete",void 0),t([l({reflect:!0,type:Number,attribute:"group-size"})],A.prototype,"groupSize",void 0),t([l()],A.prototype,"value",null),t([h("length"),h("type")],A.prototype,"renormalize",null),A=t([s("nord-otp-field")],A);var M=A;export{b as OtpFieldCompleteEvent,y as OtpFieldInvalidEvent,M as default};
2
+ //# sourceMappingURL=OtpField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtpField.js","sources":["../src/otp-field/OtpField.ts"],"sourcesContent":["import type { PropertyValues } from 'lit'\nimport { html, LitElement, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { FormDataController } from '../common/controllers/FormDataController.js'\nimport { StateAttributesController } from '../common/controllers/StateAttributesController.js'\nimport { observe } from '../common/decorators/observe.js'\nimport { NordEvent } from '../common/events.js'\nimport { injectLightDomStyles } from '../common/light-dom-styles.js'\nimport { DraftComponentMixin } from '../common/mixins/DraftComponentMixin.js'\nimport { FieldControlMixin } from '../common/mixins/FieldControlMixin.js'\nimport { InputMixin } from '../common/mixins/InputMixin.js'\nimport { SizeMixin } from '../common/mixins/SizeMixin.js'\nimport { LocalizeController } from '../localization/LocalizeController.js'\nimport style from './OtpField.css'\nimport { OtpFieldCompleteEvent, OtpFieldInvalidEvent } from './OtpFieldEvents.js'\n\nexport { OtpFieldCompleteEvent, OtpFieldInvalidEvent } from './OtpFieldEvents.js'\n\n/** The character sets the field accepts, mirroring Base UI's `validationType`. */\nexport type OtpFieldType = 'numeric' | 'alphanumeric'\n\ninterface OtpValidationConfig {\n /** Pattern for a single cell input, e.g. `'\\\\d{1}'`. */\n slotPattern: string\n /** Builds the full-value pattern for the hidden input, e.g. `'\\\\d{6}'`. */\n rootPattern: (length: number) => string\n /** Strips characters not allowed by this type. */\n regexp: RegExp\n /** Virtual-keyboard hint for cells and the hidden input. */\n inputMode: 'numeric' | 'text'\n}\n\n// Kept as a table (rather than inline branches) so adding Base UI's `alpha` /\n// `none` types later is a one-line change.\nconst OTP_VALIDATION_CONFIG: Record<OtpFieldType, OtpValidationConfig> = {\n numeric: {\n slotPattern: '\\\\d{1}',\n rootPattern: length => `\\\\d{${length}}`,\n regexp: /\\D/g,\n inputMode: 'numeric',\n },\n alphanumeric: {\n slotPattern: '[a-zA-Z0-9]{1}',\n rootPattern: length => `[a-zA-Z0-9]{${length}}`,\n regexp: /[^a-z0-9]/gi,\n inputMode: 'text',\n },\n}\n\n/** Strips all whitespace from a raw OTP string. */\nfunction stripWhitespace(value: string | null | undefined): string {\n return (value ?? '').replace(/\\s/g, '')\n}\n\n/** Removes characters not permitted by the type's regexp. */\nfunction applyValidation(value: string, config: OtpValidationConfig): string {\n return value.replace(config.regexp, '')\n}\n\n/**\n * Normalizes user-entered OTP text: strips whitespace, filters by `type`, then\n * clamps to `length` by Unicode code point so multi-byte characters never split\n * across a cell. Returns the normalized value plus whether any character was\n * rejected (so the caller can fire `value-invalid`).\n */\nfunction normalizeWithDetails(\n value: string | null | undefined,\n length: number,\n config: OtpValidationConfig,\n): readonly [value: string, didRejectCharacters: boolean] {\n const stripped = stripWhitespace(value)\n const normalized = applyValidation(stripped, config)\n const didReject = stripped.length > normalized.length\n\n // Slice by code points so multi-byte characters do not split across slots.\n const maxLength = length < 0 ? 0 : length\n const characters = Array.from(normalized)\n\n return [\n characters.slice(0, maxLength).join(''),\n didReject || characters.length > maxLength,\n ]\n}\n\n/** Convenience wrapper returning only the normalized value. */\nfunction normalize(value: string | null | undefined, length: number, config: OtpValidationConfig): string {\n return normalizeWithDetails(value, length, config)[0]\n}\n\n/**\n * Replaces characters starting at `index`, then re-normalizes so paste and\n * multi-character edits stay contiguous and length-bounded.\n */\nfunction replaceValue(\n current: string,\n index: number,\n next: string,\n length: number,\n config: OtpValidationConfig,\n): string {\n const normalized = normalize(next, length, config)\n const prefix = current.slice(0, index)\n const suffix = current.slice(index + normalized.length)\n\n return normalize(`${prefix}${normalized}${suffix}`, length, config)\n}\n\n/** Splices a single character out of the value at `index`. */\nfunction removeCharacter(current: string, index: number): string {\n if (index < 0 || index >= current.length) {\n return current\n }\n\n return `${current.slice(0, index)}${current.slice(index + 1)}`\n}\n\n/** Per-instance counter so light-DOM ids stay unique when the host has no `id`. */\nlet otpFieldCount = 1\n\n/**\n * OTP Field is a segmented one-time-code input: it renders `length` individual\n * character cells plus a visually-hidden input that holds the full value, enabling\n * SMS / keychain autofill and native `pattern`/`required` validation. Typing fills\n * and auto-advances, Backspace clears and moves back, the arrow keys navigate, and\n * pasting a code distributes its characters across the cells.\n *\n * OTP Field is a control only — it has no built-in label, hint or error. Compose\n * it inside a [Field](/components/field/) with a [Field Label](/components/field-label/)\n * (connected with `for`) to give it an accessible name, helper text and an error\n * message, exactly like a native input.\n *\n * @status draft\n * @category form\n * @lightDom true\n *\n * @fires {NordEvent} input - Dispatched whenever the OTP value changes through user interaction (typing, Backspace/Delete, paste, autofill).\n * @fires {NordEvent} change - Dispatched alongside `input` when the committed value changes via user interaction.\n * @fires {OtpFieldCompleteEvent} complete - Dispatched after the value updates when every cell becomes filled.\n * @fires {OtpFieldInvalidEvent} value-invalid - Dispatched when typed or pasted text contained characters rejected by `type`.\n *\n * @localization characterLabel - Per-cell accessible label, given the 1-based cell position and total cell count.\n *\n * @attr {boolean} data-invalid - Present while the field is invalid (mirrors the \\`invalid\\` property). Style hook for the whole control.\n * @attr {boolean} data-focused - Present while any cell has focus. Style hook for focus-within treatments.\n *\n * @cssprop [--n-otp-field-gap=var(--n-space-s)] - Gap between cells (and between groups when `group-size` is used).\n * @cssprop [--n-otp-field-cell-size=var(--n-space-xl)] - Controls the block-size and inline-size of each square cell. When unset, size maps to the shared control block sizes.\n * @cssprop [--n-otp-field-background=var(--n-color-surface)] - Cell background.\n * @cssprop [--n-otp-field-border-color=var(--n-color-border-strong)] - Cell border color (resting).\n * @cssprop [--n-otp-field-border-radius=var(--n-border-radius-s)] - Cell corner radius.\n * @cssprop [--n-otp-field-font-size=var(--n-font-size-m)] - Cell character font size.\n */\n@customElement('nord-otp-field')\nexport default class OtpField extends DraftComponentMixin(SizeMixin(FieldControlMixin(InputMixin(LitElement)))) {\n /** Stable, unique id base for light-DOM ARIA wiring of this instance. */\n private otpId = `nord-otp-field-${otpFieldCount++}`\n\n private localize = new LocalizeController<'nord-otp-field'>(this)\n\n private formData = new FormDataController(this, { value: () => this.value || undefined })\n\n /** Reflects `invalid` to `data-invalid` and focus-within to `data-focused`. */\n private stateAttributes = new StateAttributesController(\n this,\n () => ({ invalid: this.invalid }),\n { trackFocus: true },\n )\n\n /** Re-renders when the host's forwarded ARIA labelling attributes change. */\n private ariaObserver?: MutationObserver\n\n /** Index + value to focus once the async value update has applied. */\n private pendingFocus: { index: number, value: string } | null = null\n\n /** Value to fire `complete` for once the async value update has applied. */\n private pendingComplete: string | null = null\n\n /** Whether any cell currently holds focus (drives roving tabindex + data-focused). */\n private focused = false\n\n /** The cell index that currently has (or last had) focus. */\n private focusedIndex = 0\n\n /**\n * The number of OTP cells. Must be a positive integer.\n */\n @property({ reflect: true, type: Number }) length = 6\n\n /**\n * Controls the allowed characters, `inputmode` and `pattern`. `numeric` accepts\n * digits; `alphanumeric` accepts letters and digits.\n */\n @property({ reflect: true }) type: OtpFieldType = 'numeric'\n\n /**\n * Prevents the user from changing the value while keeping navigation and focus.\n */\n @property({ reflect: true, type: Boolean }) readonly = false\n\n /**\n * Obscures each cell (renders `type=\"password\"`) for use on shared screens.\n */\n @property({ reflect: true, type: Boolean }) mask = false\n\n /**\n * Placeholder character or string shown in every empty cell.\n */\n @property({ reflect: true }) placeholder?: string\n\n /**\n * Marks the field invalid, applying error styling and `aria-invalid` to every\n * cell and the hidden input. Pair with a `nord-field-error` in the Field.\n */\n @property({ reflect: true, type: Boolean }) invalid = false\n\n // The control's own invalid state for the field context: its `invalid` prop or\n // a built-in `error` (when used standalone).\n protected override get ownInvalid() {\n return this.invalid || super.ownInvalid\n }\n\n /**\n * The autocomplete token applied to the first cell and the hidden input (all\n * other cells get `autocomplete=\"off\"`). Defaults to `one-time-code` to enable\n * SMS / keychain OTP autofill.\n */\n @property() autocomplete = 'one-time-code'\n\n /**\n * Renders a decorative separator after every N cells (for example, `3` shows\n * `123-456`). `0` disables grouping. The separator is `aria-hidden` and does\n * not affect the value or navigation.\n */\n @property({ reflect: true, type: Number, attribute: 'group-size' }) groupSize = 0\n\n /**\n * Whether every cell is filled (`value.length === length`). Read-only and\n * derived from `value`; reflected as the `complete` attribute so consumers can\n * style the completed state.\n */\n get complete(): boolean {\n return this.length > 0 && this._value.length === this.length\n }\n\n /** Backing store for the normalized value. */\n private _value = ''\n\n /**\n * The OTP value, for example `'123456'`. Whitespace is stripped, characters are\n * filtered by `type`, and the result is clamped to `length`. Set programmatically\n * to prefill.\n */\n @property()\n // @ts-expect-error - intentionally re-declares the inherited `value` property as a normalizing accessor\n get value(): string {\n return this._value\n }\n\n set value(next: string) {\n const old = this._value\n const normalized = normalize(next, this.length, this.config)\n\n if (normalized === old) {\n return\n }\n\n this._value = normalized\n this.requestUpdate('value', old)\n }\n\n /** The validation config for the current `type`. */\n private get config(): OtpValidationConfig {\n return OTP_VALIDATION_CONFIG[this.type] ?? OTP_VALIDATION_CONFIG.numeric\n }\n\n /** Whether `length` is a usable positive integer. */\n private get hasValidLength(): boolean {\n return Number.isInteger(this.length) && this.length > 0\n }\n\n /** The index of the cell that is currently tabbable (roving tabindex). */\n private get activeIndex(): number {\n const last = Math.max(this.length - 1, 0)\n\n return this.focused\n ? Math.min(Math.max(this.focusedIndex, 0), last)\n : Math.min(this.value.length, last)\n }\n\n connectedCallback() {\n super.connectedCallback()\n injectLightDomStyles(this, style)\n\n // The built-in `<label for>` (from FieldControlMixin) focuses the first cell.\n this.inputId = this.cellId(0)\n\n // An external label (e.g. nord-field-label) names the control by setting\n // `aria-labelledby`/`aria-label` on the host; forward it to the first cell.\n this.ariaObserver ??= new MutationObserver(() => this.requestUpdate())\n this.ariaObserver.observe(this, {\n attributes: true,\n attributeFilter: ['aria-label', 'aria-labelledby', 'aria-describedby'],\n })\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n this.ariaObserver?.disconnect()\n this.ariaObserver = undefined\n }\n\n // Render in the light DOM so the control participates in the document tree\n // (form labelling, Tailwind), like the other new Nord components.\n protected createRenderRoot() {\n return this\n }\n\n /** Re-normalize the value when `length` or `type` changes (e.g. clamps it). */\n @observe('length')\n @observe('type')\n protected renormalize() {\n const normalized = normalize(this._value, this.length, this.config)\n\n if (normalized !== this._value) {\n this._value = normalized\n this.requestUpdate()\n }\n }\n\n /**\n * Flush queued focus/complete once the value update has actually applied.\n * Runs from `updated()` (after every render) rather than a value observer so\n * it also fires for a re-paste that completes an already-complete value (the\n * value text is unchanged, so a value observer would not run).\n */\n private flushPending() {\n if (this.pendingComplete != null) {\n const value = this.pendingComplete\n this.pendingComplete = null\n\n if (value === this.value) {\n this.dispatchEvent(new OtpFieldCompleteEvent(value))\n }\n }\n\n if (this.pendingFocus != null) {\n const pending = this.pendingFocus\n this.pendingFocus = null\n\n if (pending.value === this.value) {\n this.focusInput(pending.index)\n }\n }\n }\n\n /** Live list of the rendered cell inputs, in DOM order. */\n private get cells(): HTMLInputElement[] {\n return Array.from(this.querySelectorAll<HTMLInputElement>('input.n-cell'))\n }\n\n /** Focus a cell by index (clamped), then select its content. */\n private focusInput(index: number) {\n const cells = this.cells\n const target = cells[Math.min(Math.max(index, 0), Math.max(cells.length - 1, 0))]\n target?.focus()\n target?.select()\n }\n\n /** Queue a focus to run once the value update applies (Lit renders async). */\n private queueFocusInput(index: number, value: string) {\n this.pendingFocus = { index, value }\n }\n\n /** Focus the field by moving focus into its active cell. */\n focus(options?: FocusOptions) {\n this.cells[this.activeIndex]?.focus(options)\n }\n\n /**\n * Commit a new value, firing `input` + `change` (and queuing `complete` when\n * the field becomes filled). Returns the committed value, or `null` if nothing\n * changed.\n */\n private setValue(next: string): string | null {\n const normalized = normalize(next, this.length, this.config)\n const wasComplete = this.value.length === this.length\n\n // A completing change, OR a complete value (re-)committed via paste, signals\n // completion — even when the value text is unchanged.\n const completes = normalized.length === this.length && (!wasComplete || this.lastReason === 'input-paste')\n\n if (normalized === this.value) {\n if (completes) {\n this.pendingComplete = normalized\n // Value is unchanged so the value observer won't fire — flush manually.\n this.requestUpdate()\n }\n return null\n }\n\n this.value = normalized\n\n // Recommended order on a completing edit: 'input', 'change', then 'complete'\n // (queued and flushed after render, so the value is already committed).\n this.dispatchEvent(new NordEvent('input'))\n this.dispatchEvent(new NordEvent('change'))\n\n this.pendingComplete = completes ? normalized : null\n\n return normalized\n }\n\n /** The reason for the in-flight `setValue`, used to detect re-paste completion. */\n private lastReason: 'input-change' | 'input-clear' | 'input-paste' | 'keyboard' = 'input-change'\n\n /** Report rejected characters to consumers via `value-invalid`. */\n private reportInvalid(raw: string) {\n this.dispatchEvent(new OtpFieldInvalidEvent(raw))\n }\n\n /**\n * Re-select a cell on mousedown so clicking an already-focused filled cell\n * re-selects its character (typing then replaces it) instead of dropping a\n * caret. Mirrors Base UI's OTPFieldInput onMouseDown.\n */\n private handleMousedown(e: MouseEvent, index: number) {\n if (e.defaultPrevented || this.disabled) {\n return\n }\n\n e.preventDefault()\n this.focusInput(index)\n }\n\n private handleInput(e: Event, index: number) {\n // Stop the native input event at the boundary so consumers only ever see the\n // canonical NordEvent('input') dispatched from `setValue` (no double event).\n e.stopPropagation()\n\n if (this.disabled || this.readonly) {\n return\n }\n\n const cell = e.target as HTMLInputElement\n const raw = cell.value\n const [digits, didReject] = normalizeWithDetails(raw, this.length, this.config)\n\n if (didReject) {\n this.lastReason = 'input-change'\n this.reportInvalid(raw)\n }\n\n if (digits === '') {\n const slotValue = this.value[index] ?? ''\n if (raw === '') {\n // The user deleted the cell's character.\n this.lastReason = 'input-clear'\n this.setValue(removeCharacter(this.value, index))\n }\n else {\n // An invalid character was typed (e.g. a letter in a numeric field) —\n // revert the cell to its committed value (empty for an empty cell, the\n // existing digit for a filled one) so the rejected character never\n // lingers visibly in the field.\n cell.value = slotValue\n cell.select()\n }\n return\n }\n\n this.lastReason = 'input-change'\n const next = replaceValue(this.value, index, digits, this.length, this.config)\n const committed = this.setValue(next)\n\n if (committed != null) {\n this.queueFocusInput(Math.min(index + digits.length, this.length - 1), committed)\n }\n }\n\n private handleKeydown(e: KeyboardEvent, index: number) {\n // In disabled mode bail WITHOUT preventing default so vertical arrow keys\n // bubble (matches Base UI 'leaves vertical arrow navigation unhandled').\n if (this.disabled) {\n return\n }\n\n const firstIndex = 0\n const lastIndex = Math.max(this.length - 1, firstIndex)\n const endTargetIndex = Math.min(this.value.length, lastIndex)\n const hasBoundaryModifier = (e.ctrlKey || e.metaKey) && !e.altKey\n const isRtl = this.resolveDirection() === 'rtl'\n const previousKey = isRtl ? 'ArrowRight' : 'ArrowLeft'\n const nextKey = isRtl ? 'ArrowLeft' : 'ArrowRight'\n\n // --- Navigation (works in readonly too) ---\n if (e.key === previousKey) {\n this.stopEvent(e)\n this.focusInput(hasBoundaryModifier ? firstIndex : Math.max(firstIndex, index - 1))\n return\n }\n\n if (e.key === nextKey) {\n this.stopEvent(e)\n this.focusInput(hasBoundaryModifier ? endTargetIndex : Math.min(lastIndex, index + 1))\n return\n }\n\n if (e.key === 'Home' || e.key === 'ArrowUp') {\n this.stopEvent(e)\n this.focusInput(firstIndex)\n return\n }\n\n if (e.key === 'End' || e.key === 'ArrowDown') {\n this.stopEvent(e)\n this.focusInput(endTargetIndex)\n return\n }\n\n // --- Value-changing keys (blocked in readonly) ---\n if (this.readonly) {\n return\n }\n\n if (e.key === 'Backspace' && hasBoundaryModifier) {\n this.stopEvent(e)\n this.lastReason = 'keyboard'\n if (this.setValue('') != null) {\n this.queueFocusInput(firstIndex, '')\n }\n return\n }\n\n if (e.key === 'Delete') {\n this.stopEvent(e)\n this.lastReason = 'keyboard'\n const next = removeCharacter(this.value, index)\n const committed = this.setValue(next)\n if (committed != null) {\n this.queueFocusInput(index, committed)\n }\n return\n }\n\n const slotValue = this.value[index] ?? ''\n const cell = e.currentTarget as HTMLInputElement\n const fullSelection = cell.selectionStart === 0 && cell.selectionEnd === cell.value.length\n\n // Typing the same character into a fully-selected filled cell would be a\n // no-op change; advance instead so the user isn't stuck.\n if (e.key.length === 1 && fullSelection && slotValue === e.key) {\n this.stopEvent(e)\n if (index < this.length - 1) {\n this.focusInput(index + 1)\n }\n return\n }\n\n if (e.key === 'Backspace') {\n this.stopEvent(e)\n this.lastReason = 'keyboard'\n const targetIndex = Math.max(firstIndex, index - 1)\n const deleteIndex = slotValue === '' ? targetIndex : index\n const committed = this.setValue(removeCharacter(this.value, deleteIndex))\n if (committed != null) {\n this.queueFocusInput(targetIndex, committed)\n }\n }\n }\n\n private handlePaste(e: ClipboardEvent, index: number) {\n if (this.disabled || this.readonly) {\n return\n }\n\n let raw = ''\n try {\n raw = e.clipboardData?.getData('text/plain') ?? ''\n }\n catch {\n if (process.env.NODE_ENV === 'development') {\n console.warn('NORD: nord-otp-field could not read clipboard text during paste.')\n }\n return\n }\n\n e.preventDefault()\n\n const [digits, didReject] = normalizeWithDetails(raw, this.length, this.config)\n\n this.lastReason = 'input-paste'\n if (didReject) {\n this.reportInvalid(raw)\n }\n\n if (digits === '') {\n return\n }\n\n const next = replaceValue(this.value, index, digits, this.length, this.config)\n const committed = this.setValue(next)\n\n if (committed != null) {\n this.queueFocusInput(Math.min(index + digits.length, this.length - 1), committed)\n }\n }\n\n private handleFocus(e: FocusEvent, index: number) {\n if (this.disabled) {\n return\n }\n\n // Focusing a cell beyond the first empty slot redirects to the first empty one.\n if (index > this.value.length) {\n this.focusInput(Math.min(this.value.length, this.length - 1))\n return\n }\n\n this.focusedIndex = index\n this.focused = true\n this.requestUpdate()\n\n const cell = e.currentTarget as HTMLInputElement\n cell.select()\n }\n\n private handleBlur(e: FocusEvent) {\n // Ignore focus moving between cells within this field.\n if (e.relatedTarget instanceof Node && this.contains(e.relatedTarget)) {\n return\n }\n\n this.focused = false\n this.requestUpdate()\n }\n\n /** The browser focuses the hidden input during autofill — redirect to cell 0. */\n private handleHiddenFocus() {\n this.focusInput(0)\n }\n\n /** SMS autofill writes the whole code into the hidden input. */\n private handleHiddenInput(e: Event) {\n e.stopPropagation()\n\n if (this.disabled || this.readonly) {\n return\n }\n\n const input = e.target as HTMLInputElement\n const [digits, didReject] = normalizeWithDetails(input.value, this.length, this.config)\n\n this.lastReason = 'input-change'\n if (didReject) {\n this.reportInvalid(input.value)\n }\n\n const committed = this.setValue(digits)\n\n if (committed != null && committed !== '') {\n this.queueFocusInput(committed.length - 1, committed)\n }\n }\n\n /** Resolve the effective text direction from the host or document. */\n private resolveDirection(): 'ltr' | 'rtl' {\n const dir = this.closest('[dir]')?.getAttribute('dir')\n ?? (typeof document !== 'undefined' ? document.documentElement.getAttribute('dir') : null)\n return dir === 'rtl' ? 'rtl' : 'ltr'\n }\n\n /** preventDefault + stopPropagation, like Base UI's `stopEvent`. */\n private stopEvent(e: Event) {\n e.preventDefault()\n e.stopPropagation()\n }\n\n /** The id for a given cell — derived so cell ids stay unique and never collide with the host id. */\n private cellId(index: number): string {\n const base = this.getAttribute('id') ?? this.otpId\n return `${base}-${index + 1}`\n }\n\n render() {\n if (!this.hasValidLength) {\n return nothing\n }\n\n const config = this.config\n const value = this.value\n const activeIndex = this.activeIndex\n const groupId = `${this.otpId}-group`\n\n // Naming/description resolved by the FieldControlMixin getters (field context\n // in a field, built-in label/hint/error standalone, or host aria-* fallback).\n // Cell 0 inherits the shared label and the group is named by it.\n const ariaLabel = this.controlAriaLabel\n const ariaLabelledby = this.controlAriaLabelledby\n const ariaDescribedby = this.controlAriaDescribedby\n\n const cells = []\n for (let i = 0; i < this.length; i++) {\n cells.push(this.renderCell(i, value, config, activeIndex, ariaLabel, ariaLabelledby))\n\n // Decorative separators chunk the code, e.g. 123-456.\n if (this.groupSize > 0 && (i + 1) % this.groupSize === 0 && i < this.length - 1) {\n cells.push(html`<span class=\"n-separator\" aria-hidden=\"true\"></span>`)\n }\n }\n\n return html`\n ${this.renderLabel()}\n <div\n class=\"n-otp-field\"\n id=${groupId}\n role=\"group\"\n aria-label=${ifDefined(ariaLabel)}\n aria-labelledby=${ifDefined(ariaLabelledby)}\n aria-describedby=${ifDefined(ariaDescribedby)}\n >\n ${cells}\n </div>\n <input\n class=\"n-hidden-input\"\n type=\"text\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n .value=${value}\n autocomplete=${this.autocomplete}\n inputmode=${config.inputMode}\n minlength=${this.length}\n maxlength=${this.length}\n pattern=${config.rootPattern(this.length)}\n ?disabled=${this.effectiveDisabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n aria-invalid=${ifDefined(!this.effectiveDisabled && this.effectiveInvalid ? 'true' : undefined)}\n @focus=${this.handleHiddenFocus}\n @input=${this.handleHiddenInput}\n />\n ${this.renderError()}\n ${this.isHintBelow ? this.renderHint() : nothing}\n `\n }\n\n private renderCell(\n index: number,\n value: string,\n config: OtpValidationConfig,\n activeIndex: number,\n ariaLabel: string | undefined,\n ariaLabelledby: string | undefined,\n ) {\n const slotValue = value[index] ?? ''\n const filled = slotValue !== ''\n\n // Cell 0 inherits the shared field label; later cells get a per-cell label so\n // AT announces which slot is focused.\n const cellAriaLabel = index === 0 ? undefined : this.localize.term('characterLabel', index + 1, this.length)\n const cellAriaLabelledby = index === 0 ? ariaLabelledby : undefined\n const cellAriaLabelInherited = index === 0 ? ariaLabel : undefined\n\n return html`\n <input\n class=\"n-cell\"\n id=${this.cellId(index)}\n .value=${slotValue}\n type=${this.mask ? 'password' : 'text'}\n inputmode=${config.inputMode}\n autocomplete=${index === 0 ? this.autocomplete : 'off'}\n autocorrect=\"off\"\n spellcheck=\"false\"\n enterkeyhint=${index === this.length - 1 ? 'done' : 'next'}\n maxlength=${ifDefined(index === 0 ? this.length : undefined)}\n pattern=${config.slotPattern}\n placeholder=${ifDefined(this.placeholder)}\n tabindex=${activeIndex === index ? 0 : -1}\n ?disabled=${this.effectiveDisabled}\n ?readonly=${this.readonly}\n aria-label=${ifDefined(cellAriaLabel ?? cellAriaLabelInherited)}\n aria-labelledby=${ifDefined(cellAriaLabel == null ? cellAriaLabelledby : undefined)}\n aria-invalid=${ifDefined(!this.effectiveDisabled && this.effectiveInvalid ? 'true' : undefined)}\n data-filled=${ifDefined(filled ? '' : undefined)}\n @mousedown=${(e: MouseEvent) => this.handleMousedown(e, index)}\n @input=${(e: Event) => this.handleInput(e, index)}\n @keydown=${(e: KeyboardEvent) => this.handleKeydown(e, index)}\n @paste=${(e: ClipboardEvent) => this.handlePaste(e, index)}\n @focus=${(e: FocusEvent) => this.handleFocus(e, index)}\n @blur=${(e: FocusEvent) => this.handleBlur(e)}\n />\n `\n }\n\n /** Mirror state to host data-* attributes and flush queued focus/complete. */\n protected updated(changed: PropertyValues) {\n super.updated(changed)\n this.toggleAttribute('complete', this.complete)\n this.toggleAttribute('data-complete', this.complete)\n this.toggleAttribute('data-filled', this.value.length > 0)\n this.toggleAttribute('data-disabled', this.disabled)\n this.toggleAttribute('data-readonly', this.readonly)\n this.toggleAttribute('data-required', this.required)\n // `data-invalid` and `data-focused` are managed by `stateAttributes`.\n\n this.flushPending()\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nord-otp-field': OtpField\n }\n}\n"],"names":["OTP_VALIDATION_CONFIG","numeric","slotPattern","rootPattern","length","regexp","inputMode","alphanumeric","normalizeWithDetails","value","config","stripped","replace","stripWhitespace","normalized","applyValidation","didReject","maxLength","characters","Array","from","slice","join","normalize","replaceValue","current","index","next","removeCharacter","otpFieldCount","OtpField","DraftComponentMixin","SizeMixin","FieldControlMixin","InputMixin","LitElement","constructor","this","otpId","localize","LocalizeController","formData","FormDataController","undefined","stateAttributes","StateAttributesController","invalid","trackFocus","pendingFocus","pendingComplete","focused","focusedIndex","type","readonly","mask","autocomplete","groupSize","_value","lastReason","ownInvalid","super","complete","old","requestUpdate","_a","hasValidLength","Number","isInteger","activeIndex","last","Math","max","min","connectedCallback","injectLightDomStyles","style","inputId","cellId","ariaObserver","MutationObserver","observe","attributes","attributeFilter","disconnectedCallback","disconnect","createRenderRoot","renormalize","flushPending","dispatchEvent","OtpFieldCompleteEvent","pending","focusInput","cells","querySelectorAll","target","focus","select","queueFocusInput","options","setValue","wasComplete","completes","NordEvent","reportInvalid","raw","OtpFieldInvalidEvent","handleMousedown","e","defaultPrevented","disabled","preventDefault","handleInput","stopPropagation","cell","digits","slotValue","committed","handleKeydown","lastIndex","endTargetIndex","hasBoundaryModifier","ctrlKey","metaKey","altKey","isRtl","resolveDirection","previousKey","nextKey","key","stopEvent","currentTarget","fullSelection","selectionStart","selectionEnd","targetIndex","deleteIndex","handlePaste","_b","clipboardData","getData","_c","handleFocus","handleBlur","relatedTarget","Node","contains","handleHiddenFocus","handleHiddenInput","input","closest","getAttribute","document","documentElement","render","nothing","groupId","ariaLabel","controlAriaLabel","ariaLabelledby","controlAriaLabelledby","ariaDescribedby","controlAriaDescribedby","i","push","renderCell","html","renderLabel","ifDefined","effectiveDisabled","required","effectiveInvalid","renderError","isHintBelow","renderHint","filled","cellAriaLabel","term","cellAriaLabelledby","cellAriaLabelInherited","placeholder","updated","changed","toggleAttribute","__decorate","property","reflect","prototype","Boolean","attribute","customElement"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{N as e}from"./events-Bv6wNHwJ.js";class t extends e{constructor(e){super(t.eventName),this.value=e}get detail(){return this.value}}t.eventName="complete";class s extends e{constructor(e){super(s.eventName),this.value=e}get detail(){return this.value}}s.eventName="value-invalid";export{t as OtpFieldCompleteEvent,s as OtpFieldInvalidEvent};
2
+ //# sourceMappingURL=OtpFieldEvents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtpFieldEvents.js","sources":["../src/otp-field/OtpFieldEvents.ts"],"sourcesContent":["import { NordEvent } from '../common/events.js'\n\n/**\n * Dispatched after the value update applies when every OTP cell becomes filled\n * (`value.length === length`), or when a complete value is pasted while the\n * field is already complete. Carries the completed value so consumers can react\n * to completion (for example, submitting the owning form).\n *\n * Fired after `input`/`change` so the committed value is already readable on the\n * host, mirroring Base UI's `onValueComplete`-after-`onValueChange` ordering.\n */\nexport class OtpFieldCompleteEvent extends NordEvent {\n static eventName = 'complete'\n\n constructor(\n /** The completed OTP value, e.g. `'123456'`. */\n public readonly value: string,\n ) {\n super(OtpFieldCompleteEvent.eventName)\n }\n\n /** Convenience accessor mirroring `CustomEvent.detail`. */\n get detail() {\n return this.value\n }\n}\n\n/**\n * Dispatched when typed or pasted text contained characters rejected by the\n * field's `type` normalization (for example, letters typed into a `numeric`\n * field). Carries the raw attempted string before normalization.\n *\n * Named `value-invalid` rather than `invalid` so it does not collide with the\n * native `HTMLInputElement` `invalid` event.\n */\nexport class OtpFieldInvalidEvent extends NordEvent {\n static eventName = 'value-invalid'\n\n constructor(\n /** The raw text the user attempted to enter, before normalization. */\n public readonly value: string,\n ) {\n super(OtpFieldInvalidEvent.eventName)\n }\n\n /** Convenience accessor mirroring `CustomEvent.detail`. */\n get detail() {\n return this.value\n }\n}\n"],"names":["OtpFieldCompleteEvent","NordEvent","constructor","value","super","eventName","this","detail","OtpFieldInvalidEvent"],"mappings":"yCAWM,MAAOA,UAA8BC,EAGzC,WAAAC,CAEkBC,GAEhBC,MAAMJ,EAAsBK,WAFZC,KAAKH,MAALA,CAGjB,CAGD,UAAII,GACF,OAAOD,KAAKH,KACb,EAZMH,EAASK,UAAG,WAuBf,MAAOG,UAA6BP,EAGxC,WAAAC,CAEkBC,GAEhBC,MAAMI,EAAqBH,WAFXC,KAAKH,MAALA,CAGjB,CAGD,UAAII,GACF,OAAOD,KAAKH,KACb,EAZMK,EAASH,UAAG"}
@@ -0,0 +1,2 @@
1
+ import{_ as i}from"./tslib.es6-CmLYFWVC.js";import{css as t,LitElement as o}from"lit";import{property as a,customElement as l}from"lit/decorators.js";import{i as r}from"./light-dom-styles-DXsbiKU9.js";import{D as s}from"./DraftComponentMixin-4qug5Rky.js";import{LocalizeController as n}from"./LocalizeController.js";import"./translation.js";import"./en-us.js";import"./localization.js";import"./localization2.js";import"./localization3.js";import"./localization4.js";import"./localization5.js";import"./localization6.js";import"./localization7.js";import"./localization8.js";import"./localization9.js";import"./localization10.js";import"./localization11.js";import"./localization12.js";import"./localization13.js";import"./localization14.js";import"./localization15.js";import"./localization16.js";import"./localization17.js";import"./localization18.js";import"./localization19.js";import"./localization20.js";import"./localization21.js";import"./localization22.js";const e=t`nord-pagination{display:flex;inline-size:100%;justify-content:center;margin-inline:auto}nord-pagination[loading]{opacity:.5;pointer-events:none}`;let p=class extends(s(o)){constructor(){super(...arguments),this.localize=new n(this),this.loading=!1}connectedCallback(){super.connectedCallback(),r(this,e),this.hasAttribute("role")||this.setAttribute("role","navigation"),this.hasAttribute("aria-label")||this.hasAttribute("aria-labelledby")||this.setAttribute("aria-label",this.localize.term("label"))}updated(){this.loading?this.setAttribute("aria-busy","true"):this.removeAttribute("aria-busy")}createRenderRoot(){return this}};i([a({reflect:!0,type:Boolean})],p.prototype,"loading",void 0),p=i([l("nord-pagination")],p);var c=p;export{c as default};
2
+ //# sourceMappingURL=Pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.js","sources":["../src/pagination/Pagination.ts"],"sourcesContent":["import { LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { injectLightDomStyles } from '../common/light-dom-styles.js'\nimport { DraftComponentMixin } from '../common/mixins/DraftComponentMixin.js'\nimport { LocalizeController } from '../localization/LocalizeController.js'\nimport style from './Pagination.css'\n\n/**\n * Pagination is the navigation root for a paginated collection. It is\n * composition-first: it owns no page state, renders no controls, and emits no\n * events. Your app owns the page state, URL/query syncing, cursors and any data\n * fetching; Nord supplies the semantic/layout primitives, the styling and the\n * `paginate()` math utility for building the page window.\n *\n * As a root it is a `navigation` landmark — it sets `role=\"navigation\"` and a\n * default accessible label so screen-reader users can jump to it. Compose the\n * lower-level primitives inside it:\n *\n * - [Pagination Content](/components/pagination-content/) — the list row.\n * - [Pagination Item](/components/pagination-item/) — a slot in the row.\n * - [Pagination Link](/components/pagination-link/) — a page link (set `current`).\n * - [Pagination Previous](/components/pagination-previous/) — the previous control.\n * - [Pagination Next](/components/pagination-next/) — the next control.\n * - [Pagination Ellipsis](/components/pagination-ellipsis/) — the collapsed-pages marker.\n *\n * Bring your own interactive element — an `<a>` (e.g. a framework `<Link>` /\n * `<NuxtLink>`) or a `nord-button` — and own its `href`, navigation and\n * `disabled` state. See the framework adapters in the docs.\n *\n * @status draft\n * @category navigation\n * @lightDom true\n *\n * @localization label - Accessible label for the pagination navigation landmark.\n *\n * @cssprop [--n-pagination-gap=var(--n-space-xs)] - Controls the spacing between pagination controls.\n *\n * @slot - Default slot for the composed pagination primitives.\n */\n@customElement('nord-pagination')\nexport default class Pagination extends DraftComponentMixin(LitElement) {\n protected localize = new LocalizeController<'nord-pagination'>(this)\n\n /**\n * Dims the pagination and disables interaction while results are loading.\n */\n @property({ reflect: true, type: Boolean }) loading = false\n\n connectedCallback() {\n super.connectedCallback()\n injectLightDomStyles(this, style)\n\n // As the navigation root, expose a landmark with an accessible name. Only\n // set defaults when the consumer hasn't provided their own semantics.\n if (!this.hasAttribute('role')) {\n this.setAttribute('role', 'navigation')\n }\n if (!this.hasAttribute('aria-label') && !this.hasAttribute('aria-labelledby')) {\n this.setAttribute('aria-label', this.localize.term('label'))\n }\n }\n\n protected updated() {\n // Light DOM with no render(): reflect the loading state onto the host for\n // assistive tech, mirroring the visual dim/disable applied via CSS.\n if (this.loading) {\n this.setAttribute('aria-busy', 'true')\n }\n else {\n this.removeAttribute('aria-busy')\n }\n }\n\n // No render() — the composed primitives are the element's own light-DOM\n // content; we only style them and set the landmark semantics.\n protected createRenderRoot() {\n return this\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nord-pagination': Pagination\n }\n}\n"],"names":["Pagination","DraftComponentMixin","LitElement","constructor","this","localize","LocalizeController","loading","connectedCallback","super","injectLightDomStyles","style","hasAttribute","setAttribute","term","updated","removeAttribute","createRenderRoot","__decorate","property","reflect","type","Boolean","prototype","customElement"],"mappings":"kmCAyCe,IAAMA,EAAN,cAAyBC,EAAoBC,IAA7C,WAAAC,uBACHC,KAAAC,SAAW,IAAIC,EAAsCF,MAKnBA,KAAOG,SAAG,CAgCvD,CA9BC,iBAAAC,GACEC,MAAMD,oBACNE,EAAqBN,KAAMO,GAItBP,KAAKQ,aAAa,SACrBR,KAAKS,aAAa,OAAQ,cAEvBT,KAAKQ,aAAa,eAAkBR,KAAKQ,aAAa,oBACzDR,KAAKS,aAAa,aAAcT,KAAKC,SAASS,KAAK,SAEtD,CAES,OAAAC,GAGJX,KAAKG,QACPH,KAAKS,aAAa,YAAa,QAG/BT,KAAKY,gBAAgB,YAExB,CAIS,gBAAAC,GACR,OAAOb,IACR,GA/B2Cc,EAAA,CAA3CC,EAAS,CAAEC,SAAS,EAAMC,KAAMC,WAA0BtB,EAAAuB,UAAA,eAAA,GANxCvB,EAAUkB,EAAA,CAD9BM,EAAc,oBACMxB,SAAAA"}
@@ -0,0 +1,2 @@
1
+ import{_ as t}from"./tslib.es6-CmLYFWVC.js";import{LitElement as o}from"lit";import{customElement as r}from"lit/decorators.js";import{i as s}from"./light-dom-styles-DXsbiKU9.js";import{D as e}from"./DraftComponentMixin-4qug5Rky.js";import{s as i}from"./primitives-Dj0vyf1-.js";let a=class extends(e(o)){connectedCallback(){super.connectedCallback(),s(this,i)}createRenderRoot(){return this}};a=t([r("nord-pagination-content")],a);var m=a;export{m as default};
2
+ //# sourceMappingURL=PaginationContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PaginationContent.js","sources":["../src/pagination/PaginationContent.ts"],"sourcesContent":["import { LitElement } from 'lit'\nimport { customElement } from 'lit/decorators.js'\n\nimport { injectLightDomStyles } from '../common/light-dom-styles.js'\nimport { DraftComponentMixin } from '../common/mixins/DraftComponentMixin.js'\nimport style from './primitives.css'\n\n/**\n * The list container for composed [Pagination](/components/pagination/) controls.\n * Lays its [Pagination Item](/components/pagination-item/) children out in a row.\n *\n * Place it inside [Pagination](/components/pagination/), which is already the\n * `navigation` landmark (it sets `role=\"navigation\"` and an accessible label).\n * Do not add your own `<nav>` wrapper — a second landmark around the same\n * controls would be a duplicate that screen-reader users have to wade through.\n *\n * @status draft\n * @category navigation\n * @lightDom true\n *\n * @slot - Default slot for Pagination Item children.\n */\n@customElement('nord-pagination-content')\nexport default class PaginationContent extends DraftComponentMixin(LitElement) {\n connectedCallback() {\n super.connectedCallback()\n injectLightDomStyles(this, style)\n }\n\n protected createRenderRoot() {\n return this\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nord-pagination-content': PaginationContent\n }\n}\n"],"names":["PaginationContent","DraftComponentMixin","LitElement","connectedCallback","super","injectLightDomStyles","this","style","createRenderRoot","__decorate","customElement"],"mappings":"qRAuBe,IAAMA,EAAN,cAAgCC,EAAoBC,IACjE,iBAAAC,GACEC,MAAMD,oBACNE,EAAqBC,KAAMC,EAC5B,CAES,gBAAAC,GACR,OAAOF,IACR,GARkBN,EAAiBS,EAAA,CADrCC,EAAc,4BACMV,SAAAA"}
@@ -0,0 +1,2 @@
1
+ import{_ as r}from"./tslib.es6-CmLYFWVC.js";import{html as e,LitElement as s}from"lit";import{property as t,customElement as i}from"lit/decorators.js";import{i as o}from"./light-dom-styles-DXsbiKU9.js";import{D as a}from"./DraftComponentMixin-4qug5Rky.js";import{s as l}from"./primitives-Dj0vyf1-.js";import"./VisuallyHidden.js";let n=class extends(a(s)){constructor(){super(...arguments),this.label="More pages"}connectedCallback(){super.connectedCallback(),o(this,l)}createRenderRoot(){return this}render(){return e`<span aria-hidden="true">…</span><nord-visually-hidden>${this.label}</nord-visually-hidden>`}};r([t()],n.prototype,"label",void 0),n=r([i("nord-pagination-ellipsis")],n);var d=n;export{d as default};
2
+ //# sourceMappingURL=PaginationEllipsis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PaginationEllipsis.js","sources":["../src/pagination/PaginationEllipsis.ts"],"sourcesContent":["import { html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { injectLightDomStyles } from '../common/light-dom-styles.js'\nimport { DraftComponentMixin } from '../common/mixins/DraftComponentMixin.js'\nimport style from './primitives.css'\nimport '../visually-hidden/VisuallyHidden.js'\n\n/**\n * The collapsed-pages marker (…) in a composed [Pagination](/components/pagination/).\n * The glyph is decorative; a visually-hidden label gives it meaning for\n * assistive tech. Set `label` to localise it.\n *\n * @status draft\n * @category navigation\n * @lightDom true\n *\n * @cssprop [--n-pagination-gap=var(--n-space-xs)] - Inherited spacing token used by the pagination row.\n */\n@customElement('nord-pagination-ellipsis')\nexport default class PaginationEllipsis extends DraftComponentMixin(LitElement) {\n /** The visually-hidden label announced for the collapsed pages. */\n @property() label = 'More pages'\n\n connectedCallback() {\n super.connectedCallback()\n injectLightDomStyles(this, style)\n }\n\n protected createRenderRoot() {\n return this\n }\n\n render() {\n return html`\n <span aria-hidden=\"true\">…</span>\n <nord-visually-hidden>${this.label}</nord-visually-hidden>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nord-pagination-ellipsis': PaginationEllipsis\n }\n}\n"],"names":["PaginationEllipsis","DraftComponentMixin","LitElement","constructor","this","label","connectedCallback","super","injectLightDomStyles","style","createRenderRoot","render","html","__decorate","property","prototype","customElement"],"mappings":"yUAoBe,IAAMA,EAAN,cAAiCC,EAAoBC,IAArD,WAAAC,uBAEDC,KAAKC,MAAG,YAiBrB,CAfC,iBAAAC,GACEC,MAAMD,oBACNE,EAAqBJ,KAAMK,EAC5B,CAES,gBAAAC,GACR,OAAON,IACR,CAED,MAAAO,GACE,OAAOC,CAAI,0DAEeR,KAAKC,8BAEhC,GAhBWQ,EAAA,CAAXC,KAA+Bd,EAAAe,UAAA,aAAA,GAFbf,EAAkBa,EAAA,CADtCG,EAAc,6BACMhB,SAAAA"}
@@ -0,0 +1,2 @@
1
+ import{_ as t}from"./tslib.es6-CmLYFWVC.js";import{LitElement as o}from"lit";import{customElement as r}from"lit/decorators.js";import{i as s}from"./light-dom-styles-DXsbiKU9.js";import{D as e}from"./DraftComponentMixin-4qug5Rky.js";import{s as i}from"./primitives-Dj0vyf1-.js";let a=class extends(e(o)){connectedCallback(){super.connectedCallback(),s(this,i)}createRenderRoot(){return this}};a=t([r("nord-pagination-item")],a);var m=a;export{m as default};
2
+ //# sourceMappingURL=PaginationItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PaginationItem.js","sources":["../src/pagination/PaginationItem.ts"],"sourcesContent":["import { LitElement } from 'lit'\nimport { customElement } from 'lit/decorators.js'\n\nimport { injectLightDomStyles } from '../common/light-dom-styles.js'\nimport { DraftComponentMixin } from '../common/mixins/DraftComponentMixin.js'\nimport style from './primitives.css'\n\n/**\n * A single slot in a composed [Pagination Content](/components/pagination-content/)\n * row. Wrap each control — a [Pagination Link](/components/pagination-link/),\n * [Pagination Previous](/components/pagination-previous/), [Pagination Next](/components/pagination-next/)\n * or [Pagination Ellipsis](/components/pagination-ellipsis/) — in its own item.\n *\n * @status draft\n * @category navigation\n * @lightDom true\n *\n * @slot - Default slot for a single pagination control.\n */\n@customElement('nord-pagination-item')\nexport default class PaginationItem extends DraftComponentMixin(LitElement) {\n connectedCallback() {\n super.connectedCallback()\n injectLightDomStyles(this, style)\n }\n\n protected createRenderRoot() {\n return this\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nord-pagination-item': PaginationItem\n }\n}\n"],"names":["PaginationItem","DraftComponentMixin","LitElement","connectedCallback","super","injectLightDomStyles","this","style","createRenderRoot","__decorate","customElement"],"mappings":"qRAoBe,IAAMA,EAAN,cAA6BC,EAAoBC,IAC9D,iBAAAC,GACEC,MAAMD,oBACNE,EAAqBC,KAAMC,EAC5B,CAES,gBAAAC,GACR,OAAOF,IACR,GARkBN,EAAcS,EAAA,CADlCC,EAAc,yBACMV,SAAAA"}
@@ -0,0 +1,2 @@
1
+ import{_ as t}from"./tslib.es6-CmLYFWVC.js";import{LitElement as r}from"lit";import{property as e,customElement as s}from"lit/decorators.js";import{i as o}from"./light-dom-styles-DXsbiKU9.js";import{D as i}from"./DraftComponentMixin-4qug5Rky.js";import{s as n}from"./primitives-Dj0vyf1-.js";let a=class extends(i(r)){constructor(){super(...arguments),this.current=!1,this.ownsAriaCurrent=!1}connectedCallback(){super.connectedCallback(),o(this,n),this.syncCurrent()}createRenderRoot(){return this}updated(){this.syncCurrent()}syncCurrent(){const t=this.querySelector("a, button, nord-button");t&&(this.current?(t.setAttribute("aria-current","page"),this.ownsAriaCurrent=!0):this.ownsAriaCurrent&&(t.removeAttribute("aria-current"),this.ownsAriaCurrent=!1))}};t([e({reflect:!0,type:Boolean})],a.prototype,"current",void 0),a=t([s("nord-pagination-link")],a);var u=a;export{u as default};
2
+ //# sourceMappingURL=PaginationLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PaginationLink.js","sources":["../src/pagination/PaginationLink.ts"],"sourcesContent":["import { LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { injectLightDomStyles } from '../common/light-dom-styles.js'\nimport { DraftComponentMixin } from '../common/mixins/DraftComponentMixin.js'\nimport style from './primitives.css'\n\n/**\n * A page link in a composed [Pagination](/components/pagination/). A layout\n * wrapper around your own interactive element — provide an `<a>` (e.g. a\n * framework `<Link>` for crawlable, SSR-friendly links) or a `nord-button`. Set\n * `current` on the link for the active page; it mirrors `aria-current=\"page\"`\n * onto the interactive child so assistive tech announces it.\n *\n * @status draft\n * @category navigation\n * @lightDom true\n *\n * @slot - Default slot for the page link or button.\n */\n@customElement('nord-pagination-link')\nexport default class PaginationLink extends DraftComponentMixin(LitElement) {\n /** Marks this as the current page, mirroring `aria-current=\"page\"` onto the child. */\n @property({ reflect: true, type: Boolean }) current = false\n\n connectedCallback() {\n super.connectedCallback()\n injectLightDomStyles(this, style)\n this.syncCurrent()\n }\n\n protected createRenderRoot() {\n return this\n }\n\n // No render() — the consumer's link/button is preserved as the element's own\n // content; we only reflect `current` onto it.\n protected updated() {\n this.syncCurrent()\n }\n\n // Whether we set `aria-current` on the child, so we only ever clear our own —\n // a consumer who sets `aria-current` themselves (without `current`) keeps it.\n private ownsAriaCurrent = false\n\n private syncCurrent() {\n const link = this.querySelector('a, button, nord-button')\n if (!link) {\n return\n }\n if (this.current) {\n link.setAttribute('aria-current', 'page')\n this.ownsAriaCurrent = true\n }\n else if (this.ownsAriaCurrent) {\n link.removeAttribute('aria-current')\n this.ownsAriaCurrent = false\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nord-pagination-link': PaginationLink\n }\n}\n"],"names":["PaginationLink","DraftComponentMixin","LitElement","constructor","this","current","ownsAriaCurrent","connectedCallback","super","injectLightDomStyles","style","syncCurrent","createRenderRoot","updated","link","querySelector","setAttribute","removeAttribute","__decorate","property","reflect","type","Boolean","prototype","customElement"],"mappings":"mSAqBe,IAAMA,EAAN,cAA6BC,EAAoBC,IAAjD,WAAAC,uBAE+BC,KAAOC,SAAG,EAoB9CD,KAAeE,iBAAG,CAgB3B,CAlCC,iBAAAC,GACEC,MAAMD,oBACNE,EAAqBL,KAAMM,GAC3BN,KAAKO,aACN,CAES,gBAAAC,GACR,OAAOR,IACR,CAIS,OAAAS,GACRT,KAAKO,aACN,CAMO,WAAAA,GACN,MAAMG,EAAOV,KAAKW,cAAc,0BAC3BD,IAGDV,KAAKC,SACPS,EAAKE,aAAa,eAAgB,QAClCZ,KAAKE,iBAAkB,GAEhBF,KAAKE,kBACZQ,EAAKG,gBAAgB,gBACrBb,KAAKE,iBAAkB,GAE1B,GAnC2CY,EAAA,CAA3CC,EAAS,CAAEC,SAAS,EAAMC,KAAMC,WAA0BtB,EAAAuB,UAAA,eAAA,GAFxCvB,EAAckB,EAAA,CADlCM,EAAc,yBACMxB,SAAAA"}
@@ -0,0 +1,2 @@
1
+ import{_ as t}from"./tslib.es6-CmLYFWVC.js";import{LitElement as o}from"lit";import{customElement as r}from"lit/decorators.js";import{i as s}from"./light-dom-styles-DXsbiKU9.js";import{D as e}from"./DraftComponentMixin-4qug5Rky.js";import{s as i}from"./primitives-Dj0vyf1-.js";let a=class extends(e(o)){connectedCallback(){super.connectedCallback(),s(this,i)}createRenderRoot(){return this}};a=t([r("nord-pagination-next")],a);var m=a;export{m as default};
2
+ //# sourceMappingURL=PaginationNext.js.map