@threadlabs/looma 0.28.5 → 0.28.7

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 (453) hide show
  1. package/components/ui-editor-block-actions/ui-editor-block-actions.html +20 -0
  2. package/components/ui-editor-block-actions/ui-editor-block-actions.js +14 -0
  3. package/components/ui-editor-image-toolbar/ui-editor-image-toolbar.html +7 -6
  4. package/components/ui-editor-image-toolbar/ui-editor-image-toolbar.js +2 -1
  5. package/components/ui-editor-link-card/ui-editor-link-card.html +57 -0
  6. package/components/ui-editor-link-card/ui-editor-link-card.js +27 -0
  7. package/components/ui-editor-mention-menu-item/ui-editor-mention-menu-item.html +3 -2
  8. package/dist/index.js +36 -34
  9. package/package.json +3 -2
  10. package/styles/ui-action-bar.css +13 -6
  11. package/styles/ui-affordance-scope.css +12 -5
  12. package/styles/ui-avatar-group.css +17 -10
  13. package/styles/ui-avatar.css +23 -16
  14. package/styles/ui-badge.css +78 -71
  15. package/styles/ui-breadcrumb-item.css +12 -5
  16. package/styles/ui-breadcrumbs.css +10 -3
  17. package/styles/ui-button.css +79 -72
  18. package/styles/ui-callout.css +29 -22
  19. package/styles/ui-card.css +25 -18
  20. package/styles/ui-checkbox.css +45 -37
  21. package/styles/ui-cluster.css +34 -27
  22. package/styles/ui-combobox.css +46 -39
  23. package/styles/ui-container.css +20 -13
  24. package/styles/ui-context-menu.css +17 -10
  25. package/styles/ui-cover.css +12 -5
  26. package/styles/ui-description-item.css +10 -3
  27. package/styles/ui-description-list.css +20 -13
  28. package/styles/ui-dialog.css +44 -35
  29. package/styles/ui-disclosure.css +32 -25
  30. package/styles/ui-editable.css +15 -8
  31. package/styles/ui-editor-block-actions.css +1 -0
  32. package/styles/ui-editor-image-toolbar.css +1 -1
  33. package/styles/ui-editor-insert-table-grid.css +11 -4
  34. package/styles/ui-editor-link-card.css +1 -0
  35. package/styles/ui-editor-mention-menu-item.css +17 -8
  36. package/styles/ui-editor-mention-menu.css +14 -7
  37. package/styles/ui-editor-slash-menu-group.css +10 -3
  38. package/styles/ui-editor-slash-menu-item.css +15 -8
  39. package/styles/ui-editor-slash-menu.css +15 -8
  40. package/styles/ui-editor-surface.css +10 -3
  41. package/styles/ui-editor-table-context-menu.css +17 -10
  42. package/styles/ui-editor-table-overlay.css +17 -10
  43. package/styles/ui-editor-table-toolbar.css +22 -15
  44. package/styles/ui-editor-toolbar.css +18 -11
  45. package/styles/ui-floating-action-button.css +21 -14
  46. package/styles/ui-form-field.css +20 -13
  47. package/styles/ui-grid.css +21 -14
  48. package/styles/ui-icon-button.css +80 -73
  49. package/styles/ui-icon.css +14 -7
  50. package/styles/ui-image.css +25 -18
  51. package/styles/ui-input-group.css +34 -27
  52. package/styles/ui-input.css +42 -35
  53. package/styles/ui-list-item.css +33 -26
  54. package/styles/ui-list.css +22 -15
  55. package/styles/ui-listbox.css +22 -14
  56. package/styles/ui-menu-group.css +10 -3
  57. package/styles/ui-menu-item.css +29 -22
  58. package/styles/ui-menu.css +25 -18
  59. package/styles/ui-meter.css +36 -29
  60. package/styles/ui-nav-item.css +26 -19
  61. package/styles/ui-page-header.css +12 -5
  62. package/styles/ui-popover.css +27 -20
  63. package/styles/ui-radio-group.css +14 -6
  64. package/styles/ui-radio.css +24 -17
  65. package/styles/ui-reel.css +28 -21
  66. package/styles/ui-scroll-area.css +22 -15
  67. package/styles/ui-search-result-row.css +28 -21
  68. package/styles/ui-search-shell.css +24 -17
  69. package/styles/ui-section.css +14 -7
  70. package/styles/ui-select.css +33 -26
  71. package/styles/ui-separator.css +17 -10
  72. package/styles/ui-sidebar.css +35 -28
  73. package/styles/ui-spinner.css +32 -23
  74. package/styles/ui-stack.css +29 -21
  75. package/styles/ui-status-message.css +14 -7
  76. package/styles/ui-switch.css +29 -22
  77. package/styles/ui-switcher.css +27 -20
  78. package/styles/ui-table.css +14 -7
  79. package/styles/ui-tabs.css +24 -17
  80. package/styles/ui-text.css +35 -28
  81. package/styles/ui-textarea.css +37 -30
  82. package/styles/ui-toast-region.css +74 -63
  83. package/styles/ui-toast.css +21 -14
  84. package/styles/ui-tooltip.css +38 -31
  85. package/styles/ui-top-bar.css +19 -12
  86. package/styles/ui-tree-item.css +79 -71
  87. package/styles/ui-tree.css +18 -11
  88. package/vanilla/UiActionBar.d.ts +1 -1
  89. package/vanilla/UiActionBar.js +1 -1
  90. package/vanilla/UiAffordanceScope.d.ts +1 -1
  91. package/vanilla/UiAffordanceScope.js +1 -1
  92. package/vanilla/UiAvatar.d.ts +1 -1
  93. package/vanilla/UiAvatar.js +1 -1
  94. package/vanilla/UiAvatarGroup.d.ts +1 -1
  95. package/vanilla/UiAvatarGroup.js +1 -1
  96. package/vanilla/UiBadge.d.ts +1 -1
  97. package/vanilla/UiBadge.js +1 -1
  98. package/vanilla/UiBreadcrumbItem.d.ts +1 -1
  99. package/vanilla/UiBreadcrumbItem.js +1 -1
  100. package/vanilla/UiBreadcrumbs.d.ts +1 -1
  101. package/vanilla/UiBreadcrumbs.js +1 -1
  102. package/vanilla/UiButton.d.ts +1 -1
  103. package/vanilla/UiButton.js +19 -57
  104. package/vanilla/UiCallout.d.ts +1 -1
  105. package/vanilla/UiCallout.js +25 -73
  106. package/vanilla/UiCard.d.ts +1 -1
  107. package/vanilla/UiCard.js +1 -1
  108. package/vanilla/UiCheckbox.d.ts +1 -1
  109. package/vanilla/UiCheckbox.js +1 -1
  110. package/vanilla/UiCluster.d.ts +1 -1
  111. package/vanilla/UiCluster.js +1 -1
  112. package/vanilla/UiCombobox.d.ts +1 -1
  113. package/vanilla/UiCombobox.js +60 -166
  114. package/vanilla/UiContainer.d.ts +1 -1
  115. package/vanilla/UiContainer.js +1 -1
  116. package/vanilla/UiContextMenu.d.ts +1 -1
  117. package/vanilla/UiContextMenu.js +1 -1
  118. package/vanilla/UiCover.d.ts +1 -1
  119. package/vanilla/UiCover.js +1 -1
  120. package/vanilla/UiDescriptionItem.d.ts +1 -1
  121. package/vanilla/UiDescriptionItem.js +1 -1
  122. package/vanilla/UiDescriptionList.d.ts +1 -1
  123. package/vanilla/UiDescriptionList.js +1 -1
  124. package/vanilla/UiDialog.d.ts +1 -1
  125. package/vanilla/UiDialog.js +4 -10
  126. package/vanilla/UiDisclosure.d.ts +1 -1
  127. package/vanilla/UiDisclosure.js +1 -1
  128. package/vanilla/UiEditable.d.ts +1 -1
  129. package/vanilla/UiEditable.js +7 -19
  130. package/vanilla/UiEditorBlockActions.d.ts +16 -0
  131. package/vanilla/UiEditorBlockActions.js +41 -0
  132. package/vanilla/UiEditorImageToolbar.d.ts +1 -1
  133. package/vanilla/UiEditorImageToolbar.js +2 -2
  134. package/vanilla/UiEditorInsertTableGrid.d.ts +1 -1
  135. package/vanilla/UiEditorInsertTableGrid.js +1 -1
  136. package/vanilla/UiEditorLinkCard.d.ts +20 -0
  137. package/vanilla/UiEditorLinkCard.js +153 -0
  138. package/vanilla/UiEditorMentionMenu.d.ts +1 -1
  139. package/vanilla/UiEditorMentionMenu.js +17 -37
  140. package/vanilla/UiEditorMentionMenuItem.d.ts +1 -1
  141. package/vanilla/UiEditorMentionMenuItem.js +4 -10
  142. package/vanilla/UiEditorSlashMenu.d.ts +1 -1
  143. package/vanilla/UiEditorSlashMenu.js +5 -4
  144. package/vanilla/UiEditorSlashMenuGroup.d.ts +1 -1
  145. package/vanilla/UiEditorSlashMenuGroup.js +1 -1
  146. package/vanilla/UiEditorSlashMenuItem.d.ts +1 -1
  147. package/vanilla/UiEditorSlashMenuItem.js +7 -19
  148. package/vanilla/UiEditorSurface.d.ts +1 -1
  149. package/vanilla/UiEditorSurface.js +1 -1
  150. package/vanilla/UiEditorTableContextMenu.d.ts +1 -1
  151. package/vanilla/UiEditorTableContextMenu.js +6 -14
  152. package/vanilla/UiEditorTableOverlay.d.ts +1 -1
  153. package/vanilla/UiEditorTableOverlay.js +9 -25
  154. package/vanilla/UiEditorTableToolbar.d.ts +1 -1
  155. package/vanilla/UiEditorTableToolbar.js +25 -77
  156. package/vanilla/UiEditorToolbar.d.ts +1 -1
  157. package/vanilla/UiEditorToolbar.js +1 -1
  158. package/vanilla/UiFloatingActionButton.d.ts +1 -1
  159. package/vanilla/UiFloatingActionButton.js +1 -1
  160. package/vanilla/UiFormField.d.ts +1 -1
  161. package/vanilla/UiFormField.js +1 -1
  162. package/vanilla/UiGrid.d.ts +1 -1
  163. package/vanilla/UiGrid.js +1 -1
  164. package/vanilla/UiIcon.d.ts +1 -1
  165. package/vanilla/UiIcon.js +15 -47
  166. package/vanilla/UiIconButton.d.ts +1 -1
  167. package/vanilla/UiIconButton.js +4 -10
  168. package/vanilla/UiImage.d.ts +1 -1
  169. package/vanilla/UiImage.js +1 -1
  170. package/vanilla/UiInput.d.ts +1 -1
  171. package/vanilla/UiInput.js +1 -1
  172. package/vanilla/UiInputGroup.d.ts +1 -1
  173. package/vanilla/UiInputGroup.js +1 -1
  174. package/vanilla/UiList.d.ts +1 -1
  175. package/vanilla/UiList.js +1 -1
  176. package/vanilla/UiListItem.d.ts +1 -1
  177. package/vanilla/UiListItem.js +1 -1
  178. package/vanilla/UiListbox.d.ts +1 -1
  179. package/vanilla/UiListbox.js +4 -10
  180. package/vanilla/UiMenu.d.ts +1 -1
  181. package/vanilla/UiMenu.js +1 -1
  182. package/vanilla/UiMenuGroup.d.ts +1 -1
  183. package/vanilla/UiMenuGroup.js +4 -10
  184. package/vanilla/UiMenuItem.d.ts +1 -1
  185. package/vanilla/UiMenuItem.js +4 -10
  186. package/vanilla/UiMeter.d.ts +1 -1
  187. package/vanilla/UiMeter.js +13 -33
  188. package/vanilla/UiNavItem.d.ts +1 -1
  189. package/vanilla/UiNavItem.js +1 -1
  190. package/vanilla/UiPageHeader.d.ts +1 -1
  191. package/vanilla/UiPageHeader.js +1 -1
  192. package/vanilla/UiPopover.d.ts +1 -1
  193. package/vanilla/UiPopover.js +1 -1
  194. package/vanilla/UiRadio.d.ts +1 -1
  195. package/vanilla/UiRadio.js +1 -1
  196. package/vanilla/UiRadioGroup.d.ts +1 -1
  197. package/vanilla/UiRadioGroup.js +1 -1
  198. package/vanilla/UiReel.d.ts +1 -1
  199. package/vanilla/UiReel.js +1 -1
  200. package/vanilla/UiScrollArea.d.ts +1 -1
  201. package/vanilla/UiScrollArea.js +1 -1
  202. package/vanilla/UiSearchResultRow.d.ts +1 -1
  203. package/vanilla/UiSearchResultRow.js +1 -1
  204. package/vanilla/UiSearchShell.d.ts +1 -1
  205. package/vanilla/UiSearchShell.js +1 -1
  206. package/vanilla/UiSection.d.ts +1 -1
  207. package/vanilla/UiSection.js +1 -1
  208. package/vanilla/UiSelect.d.ts +1 -1
  209. package/vanilla/UiSelect.js +1 -1
  210. package/vanilla/UiSeparator.d.ts +1 -1
  211. package/vanilla/UiSeparator.js +1 -1
  212. package/vanilla/UiSidebar.d.ts +1 -1
  213. package/vanilla/UiSidebar.js +1 -1
  214. package/vanilla/UiSpinner.d.ts +1 -1
  215. package/vanilla/UiSpinner.js +1 -1
  216. package/vanilla/UiStack.d.ts +1 -1
  217. package/vanilla/UiStack.js +1 -1
  218. package/vanilla/UiStatusMessage.d.ts +1 -1
  219. package/vanilla/UiStatusMessage.js +1 -1
  220. package/vanilla/UiSwitch.d.ts +1 -1
  221. package/vanilla/UiSwitch.js +1 -1
  222. package/vanilla/UiSwitcher.d.ts +1 -1
  223. package/vanilla/UiSwitcher.js +1 -1
  224. package/vanilla/UiTable.d.ts +1 -1
  225. package/vanilla/UiTable.js +1 -1
  226. package/vanilla/UiTabs.d.ts +1 -1
  227. package/vanilla/UiTabs.js +1 -1
  228. package/vanilla/UiText.d.ts +1 -1
  229. package/vanilla/UiText.js +1 -1
  230. package/vanilla/UiTextarea.d.ts +1 -1
  231. package/vanilla/UiTextarea.js +1 -1
  232. package/vanilla/UiToast.d.ts +1 -1
  233. package/vanilla/UiToast.js +1 -1
  234. package/vanilla/UiToastRegion.d.ts +1 -1
  235. package/vanilla/UiToastRegion.js +1 -1
  236. package/vanilla/UiTooltip.d.ts +1 -1
  237. package/vanilla/UiTooltip.js +1 -1
  238. package/vanilla/UiTopBar.d.ts +1 -1
  239. package/vanilla/UiTopBar.js +1 -1
  240. package/vanilla/UiTree.d.ts +1 -1
  241. package/vanilla/UiTree.js +1 -1
  242. package/vanilla/UiTreeItem.d.ts +1 -1
  243. package/vanilla/UiTreeItem.js +7 -19
  244. package/vanilla/index.js +2 -0
  245. package/vue/UiActionBar.vue +46 -78
  246. package/vue/UiAffordanceScope.vue +27 -66
  247. package/vue/UiAvatar.d.ts +10 -7
  248. package/vue/UiAvatar.vue +100 -218
  249. package/vue/UiAvatarGroup.d.ts +10 -7
  250. package/vue/UiAvatarGroup.vue +78 -160
  251. package/vue/UiBadge.d.ts +1 -1
  252. package/vue/UiBadge.vue +483 -520
  253. package/vue/UiBreadcrumbItem.vue +52 -123
  254. package/vue/UiBreadcrumbs.vue +27 -70
  255. package/vue/UiButton.d.ts +2 -2
  256. package/vue/UiButton.vue +420 -471
  257. package/vue/UiCallout.vue +131 -175
  258. package/vue/UiCard.d.ts +1 -1
  259. package/vue/UiCard.vue +112 -151
  260. package/vue/UiCheckbox.d.ts +13 -10
  261. package/vue/UiCheckbox.vue +160 -221
  262. package/vue/UiCluster.d.ts +1 -1
  263. package/vue/UiCluster.vue +84 -128
  264. package/vue/UiCombobox.d.ts +71 -68
  265. package/vue/UiCombobox.vue +417 -743
  266. package/vue/UiContainer.vue +43 -87
  267. package/vue/UiContextMenu.d.ts +6 -6
  268. package/vue/UiContextMenu.vue +78 -117
  269. package/vue/UiCover.vue +29 -69
  270. package/vue/UiDescriptionItem.vue +39 -82
  271. package/vue/UiDescriptionList.vue +64 -107
  272. package/vue/UiDialog.d.ts +22 -19
  273. package/vue/UiDialog.vue +193 -246
  274. package/vue/UiDisclosure.d.ts +22 -19
  275. package/vue/UiDisclosure.vue +192 -283
  276. package/vue/UiEditable.d.ts +5 -5
  277. package/vue/UiEditable.vue +124 -207
  278. package/vue/UiEditorBlockActions.d.ts +33 -0
  279. package/vue/UiEditorBlockActions.js +2 -0
  280. package/vue/UiEditorBlockActions.vue +125 -0
  281. package/vue/UiEditorImageToolbar.d.ts +2 -2
  282. package/vue/UiEditorImageToolbar.vue +45 -256
  283. package/vue/UiEditorInsertTableGrid.d.ts +2 -2
  284. package/vue/UiEditorInsertTableGrid.vue +98 -266
  285. package/vue/UiEditorLinkCard.d.ts +58 -0
  286. package/vue/UiEditorLinkCard.js +2 -0
  287. package/vue/UiEditorLinkCard.vue +319 -0
  288. package/vue/UiEditorMentionMenu.d.ts +15 -12
  289. package/vue/UiEditorMentionMenu.vue +150 -239
  290. package/vue/UiEditorMentionMenuItem.vue +66 -110
  291. package/vue/UiEditorSlashMenu.d.ts +16 -13
  292. package/vue/UiEditorSlashMenu.vue +172 -253
  293. package/vue/UiEditorSlashMenuGroup.vue +25 -69
  294. package/vue/UiEditorSlashMenuItem.vue +67 -115
  295. package/vue/UiEditorSurface.vue +19 -63
  296. package/vue/UiEditorTableContextMenu.vue +135 -269
  297. package/vue/UiEditorTableOverlay.d.ts +2 -2
  298. package/vue/UiEditorTableOverlay.vue +310 -479
  299. package/vue/UiEditorTableToolbar.d.ts +2 -2
  300. package/vue/UiEditorTableToolbar.vue +182 -357
  301. package/vue/UiEditorToolbar.vue +143 -183
  302. package/vue/UiFloatingActionButton.vue +70 -114
  303. package/vue/UiFormField.d.ts +1 -1
  304. package/vue/UiFormField.vue +76 -117
  305. package/vue/UiGrid.d.ts +1 -1
  306. package/vue/UiGrid.vue +65 -103
  307. package/vue/UiIcon.vue +32 -106
  308. package/vue/UiIconButton.d.ts +2 -2
  309. package/vue/UiIconButton.vue +359 -411
  310. package/vue/UiImage.vue +145 -180
  311. package/vue/UiInput.vue +158 -190
  312. package/vue/UiInputGroup.vue +199 -239
  313. package/vue/UiList.vue +67 -109
  314. package/vue/UiListItem.vue +154 -201
  315. package/vue/UiListbox.d.ts +10 -7
  316. package/vue/UiListbox.vue +86 -260
  317. package/vue/UiMenu.d.ts +11 -11
  318. package/vue/UiMenu.vue +118 -152
  319. package/vue/UiMenuGroup.vue +21 -67
  320. package/vue/UiMenuItem.d.ts +19 -16
  321. package/vue/UiMenuItem.vue +169 -262
  322. package/vue/UiMeter.d.ts +4 -4
  323. package/vue/UiMeter.vue +166 -680
  324. package/vue/UiNavItem.vue +140 -213
  325. package/vue/UiPageHeader.vue +81 -127
  326. package/vue/UiPopover.d.ts +7 -7
  327. package/vue/UiPopover.vue +90 -129
  328. package/vue/UiRadio.d.ts +12 -9
  329. package/vue/UiRadio.vue +91 -149
  330. package/vue/UiRadioGroup.d.ts +2 -2
  331. package/vue/UiRadioGroup.vue +47 -85
  332. package/vue/UiReel.vue +89 -130
  333. package/vue/UiScrollArea.d.ts +1 -1
  334. package/vue/UiScrollArea.vue +78 -119
  335. package/vue/UiSearchResultRow.vue +96 -149
  336. package/vue/UiSearchShell.d.ts +2 -2
  337. package/vue/UiSearchShell.vue +159 -196
  338. package/vue/UiSection.vue +105 -149
  339. package/vue/UiSelect.d.ts +1 -1
  340. package/vue/UiSelect.vue +114 -146
  341. package/vue/UiSeparator.vue +42 -85
  342. package/vue/UiSidebar.d.ts +10 -7
  343. package/vue/UiSidebar.vue +193 -260
  344. package/vue/UiSpinner.vue +54 -130
  345. package/vue/UiStack.vue +66 -107
  346. package/vue/UiStatusMessage.d.ts +1 -1
  347. package/vue/UiStatusMessage.vue +61 -135
  348. package/vue/UiSwitch.d.ts +12 -9
  349. package/vue/UiSwitch.vue +136 -194
  350. package/vue/UiSwitcher.vue +69 -107
  351. package/vue/UiTable.vue +121 -156
  352. package/vue/UiTabs.d.ts +1 -1
  353. package/vue/UiTabs.vue +139 -267
  354. package/vue/UiText.d.ts +4 -4
  355. package/vue/UiText.vue +145 -184
  356. package/vue/UiTextarea.d.ts +2 -2
  357. package/vue/UiTextarea.vue +162 -194
  358. package/vue/UiToast.vue +70 -118
  359. package/vue/UiToastRegion.vue +157 -276
  360. package/vue/UiTooltip.d.ts +21 -18
  361. package/vue/UiTooltip.vue +174 -234
  362. package/vue/UiTopBar.vue +48 -76
  363. package/vue/UiTree.vue +46 -79
  364. package/vue/UiTreeItem.d.ts +18 -15
  365. package/vue/UiTreeItem.vue +526 -668
  366. package/vue/chunks/UiActionBar.js +5 -17
  367. package/vue/chunks/UiAffordanceScope.js +7 -26
  368. package/vue/chunks/UiAvatar.js +20 -74
  369. package/vue/chunks/UiAvatarGroup.js +14 -56
  370. package/vue/chunks/UiBadge.js +10 -28
  371. package/vue/chunks/UiBreadcrumbItem.js +11 -41
  372. package/vue/chunks/UiBreadcrumbs.js +7 -25
  373. package/vue/chunks/UiButton.js +80 -103
  374. package/vue/chunks/UiCallout.js +9 -27
  375. package/vue/chunks/UiCard.js +33 -53
  376. package/vue/chunks/UiCheckbox.js +14 -46
  377. package/vue/chunks/UiCluster.js +13 -31
  378. package/vue/chunks/UiCombobox.js +99 -237
  379. package/vue/chunks/UiContainer.js +9 -27
  380. package/vue/chunks/UiContextMenu.js +7 -26
  381. package/vue/chunks/UiCover.js +7 -25
  382. package/vue/chunks/UiDescriptionItem.js +6 -24
  383. package/vue/chunks/UiDescriptionList.js +9 -27
  384. package/vue/chunks/UiDialog.js +18 -47
  385. package/vue/chunks/UiDisclosure.js +19 -66
  386. package/vue/chunks/UiEditable.js +18 -60
  387. package/vue/chunks/UiEditorBlockActions.js +127 -0
  388. package/vue/chunks/UiEditorImageToolbar.js +40 -127
  389. package/vue/chunks/UiEditorInsertTableGrid.js +14 -112
  390. package/vue/chunks/UiEditorLinkCard.js +356 -0
  391. package/vue/chunks/UiEditorMentionMenu.js +16 -54
  392. package/vue/chunks/UiEditorMentionMenuItem.js +10 -28
  393. package/vue/chunks/UiEditorSlashMenu.js +17 -46
  394. package/vue/chunks/UiEditorSlashMenuGroup.js +7 -25
  395. package/vue/chunks/UiEditorSlashMenuItem.js +16 -31
  396. package/vue/chunks/UiEditorSurface.js +7 -25
  397. package/vue/chunks/UiEditorTableContextMenu.js +25 -102
  398. package/vue/chunks/UiEditorTableOverlay.js +41 -104
  399. package/vue/chunks/UiEditorTableToolbar.js +44 -122
  400. package/vue/chunks/UiEditorToolbar.js +7 -26
  401. package/vue/chunks/UiFloatingActionButton.js +10 -28
  402. package/vue/chunks/UiFormField.js +8 -27
  403. package/vue/chunks/UiGrid.js +10 -28
  404. package/vue/chunks/UiIcon.js +21 -74
  405. package/vue/chunks/UiIconButton.js +18 -50
  406. package/vue/chunks/UiImage.js +14 -33
  407. package/vue/chunks/UiInput.js +12 -31
  408. package/vue/chunks/UiInputGroup.js +10 -29
  409. package/vue/chunks/UiList.js +17 -37
  410. package/vue/chunks/UiListItem.js +12 -30
  411. package/vue/chunks/UiListbox.js +22 -124
  412. package/vue/chunks/UiMenu.js +13 -32
  413. package/vue/chunks/UiMenuGroup.js +8 -26
  414. package/vue/chunks/UiMenuItem.js +35 -80
  415. package/vue/chunks/UiMeter.js +17 -351
  416. package/vue/chunks/UiNavItem.js +23 -57
  417. package/vue/chunks/UiPageHeader.js +7 -25
  418. package/vue/chunks/UiPopover.js +9 -28
  419. package/vue/chunks/UiRadio.js +11 -43
  420. package/vue/chunks/UiRadioGroup.js +13 -32
  421. package/vue/chunks/UiReel.js +10 -28
  422. package/vue/chunks/UiScrollArea.js +10 -29
  423. package/vue/chunks/UiSearchResultRow.js +10 -28
  424. package/vue/chunks/UiSearchShell.js +9 -28
  425. package/vue/chunks/UiSection.js +9 -27
  426. package/vue/chunks/UiSelect.js +10 -29
  427. package/vue/chunks/UiSeparator.js +10 -28
  428. package/vue/chunks/UiSidebar.js +15 -47
  429. package/vue/chunks/UiSpinner.js +8 -44
  430. package/vue/chunks/UiStack.js +12 -30
  431. package/vue/chunks/UiStatusMessage.js +10 -42
  432. package/vue/chunks/UiSwitch.js +11 -43
  433. package/vue/chunks/UiSwitcher.js +9 -28
  434. package/vue/chunks/UiTable.js +7 -26
  435. package/vue/chunks/UiTabs.js +15 -91
  436. package/vue/chunks/UiText.js +148 -168
  437. package/vue/chunks/UiTextarea.js +16 -35
  438. package/vue/chunks/UiToast.js +13 -37
  439. package/vue/chunks/UiToastRegion.js +16 -88
  440. package/vue/chunks/UiTooltip.js +14 -46
  441. package/vue/chunks/UiTopBar.js +5 -17
  442. package/vue/chunks/UiTree.js +13 -32
  443. package/vue/chunks/UiTreeItem.js +34 -90
  444. package/vue/chunks/_plugin-vue_export-helper.js +904 -1
  445. package/vue/chunks/control.js +3 -0
  446. package/vue/chunks/props.js +1 -1
  447. package/vue/components.css +7689 -7617
  448. package/vue/editor/index.js +30 -95
  449. package/vue/editor/primitives.d.ts +8 -2
  450. package/vue/host.ts +999 -14
  451. package/vue/index.d.ts +2 -0
  452. package/vue/index.js +5 -3
  453. package/vue/chunks/host.js +0 -443
package/vue/host.ts CHANGED
@@ -1,8 +1,12 @@
1
- // Generated by HTML Next 1.0.0-alpha.35 for Vue 3.5. Do not edit.
1
+ // Generated by HTML Next 1.0.0-alpha.51 for Vue 3.5. Do not edit.
2
2
  import {
3
3
  computed,
4
+ createTextVNode,
5
+ defineComponent,
4
6
  Fragment,
5
7
  getCurrentInstance,
8
+ h,
9
+ inject,
6
10
  onBeforeUnmount,
7
11
  onBeforeUpdate,
8
12
  onMounted,
@@ -12,6 +16,7 @@ import {
12
16
  watch,
13
17
  watchEffect,
14
18
  } from 'vue'
19
+ import type { PropType, VNode } from 'vue'
15
20
 
16
21
  interface ControllerStateAccess {
17
22
  readonly get: () => unknown
@@ -22,7 +27,10 @@ interface ControllerNamespaces {
22
27
  readonly computed: Readonly<Record<string, () => unknown>>
23
28
  readonly data?: Readonly<Record<string, () => unknown>>
24
29
  readonly acceptsState?: (name: string, keys: readonly string[], value: unknown) => boolean
25
- readonly changed?: (name: string) => void
30
+ /** A read below a state root, by its path from the root. */
31
+ readonly read?: (name: string, keys: readonly string[]) => void
32
+ /** A write below a state root changed the value at this path from the root. */
33
+ readonly changed?: (name: string, keys: readonly string[]) => void
26
34
  }
27
35
 
28
36
  function controllerNamespaces(options: ControllerNamespaces, source: string): {
@@ -67,6 +75,10 @@ function controllerNamespaces(options: ControllerNamespaces, source: string): {
67
75
  } else apply()
68
76
  return true
69
77
  }
78
+ // Each proxy's own object: a value read through host.state and written back is the same value.
79
+ const plain = new WeakMap<object, unknown>()
80
+ const unwrap = (value: unknown): unknown =>
81
+ typeof value === 'object' && value !== null && plain.has(value) ? plain.get(value) : value
70
82
  const wrap = (
71
83
  value: unknown,
72
84
  name: string,
@@ -85,12 +97,24 @@ function controllerNamespaces(options: ControllerNamespaces, source: string): {
85
97
  : value
86
98
  if (readonly && Array.isArray(value)) surface.length = value.length
87
99
  const proxy = new Proxy(surface, {
88
- get: (_target, key) => wrap(Reflect.get(value, key), name, [...keys, String(key)], readonly),
89
- set: (_target, key, next) =>
90
- write(name, [...keys, String(key)], next, readonly, () => {
100
+ get: (_target, key) => {
101
+ if (!readonly) options.read?.(name, [...keys, String(key)])
102
+ return wrap(Reflect.get(value, key), name, [...keys, String(key)], readonly)
103
+ },
104
+ set: (_target, key, written) => {
105
+ const next = unwrap(written)
106
+ return write(name, [...keys, String(key)], next, readonly, () => {
91
107
  const previous = Reflect.get(value, key)
92
- if (Reflect.set(value, key, next) && !Object.is(previous, next)) options.changed?.(name)
93
- }),
108
+ const length = Array.isArray(value) ? value.length : undefined
109
+ if (Reflect.set(value, key, next) && !Object.is(previous, next)) {
110
+ options.changed?.(name, [...keys, String(key)])
111
+ }
112
+ // Setting an index past the end extends the list before any write of its length.
113
+ if (length !== undefined && length !== (value as unknown[]).length && key !== 'length') {
114
+ options.changed?.(name, [...keys, 'length'])
115
+ }
116
+ })
117
+ },
94
118
  has: (_target, key) => Reflect.has(value, key),
95
119
  ownKeys: () => Reflect.ownKeys(value),
96
120
  getOwnPropertyDescriptor: (_target, key) => {
@@ -107,7 +131,9 @@ function controllerNamespaces(options: ControllerNamespaces, source: string): {
107
131
  },
108
132
  deleteProperty: (_target, key) =>
109
133
  write(name, [...keys, String(key)], undefined, readonly, () => {
110
- if (Reflect.has(value, key) && Reflect.deleteProperty(value, key)) options.changed?.(name)
134
+ if (Reflect.has(value, key) && Reflect.deleteProperty(value, key)) {
135
+ options.changed?.(name, [...keys, String(key)])
136
+ }
111
137
  }),
112
138
  defineProperty: (_target, key, descriptor) => {
113
139
  if (
@@ -118,11 +144,12 @@ function controllerNamespaces(options: ControllerNamespaces, source: string): {
118
144
  return false
119
145
  }
120
146
  const changed = Reflect.defineProperty(value, key, descriptor)
121
- if (changed) options.changed?.(name)
147
+ if (changed) options.changed?.(name, [...keys, String(key)])
122
148
  return changed
123
149
  },
124
150
  })
125
151
  paths.set(path, proxy)
152
+ plain.set(proxy, value)
126
153
  return proxy
127
154
  }
128
155
  const state = new Proxy({} as Record<string, unknown>, {
@@ -140,9 +167,9 @@ function controllerNamespaces(options: ControllerNamespaces, source: string): {
140
167
  write(
141
168
  String(name),
142
169
  [],
143
- value,
170
+ unwrap(value),
144
171
  typeof name !== 'string' || !Object.hasOwn(options.state, name),
145
- () => options.state[String(name)]!.set(value),
172
+ () => options.state[String(name)]!.set(unwrap(value)),
146
173
  ),
147
174
  deleteProperty: (_target, name) => {
148
175
  warn(String(name), true)
@@ -220,6 +247,15 @@ function dataURL(
220
247
  return url.href
221
248
  }
222
249
 
250
+ /** What the from-parameters send, as dataURL writes them: an equal key requests nothing new. */
251
+ function dataKey(values: readonly unknown[]): string {
252
+ return JSON.stringify(
253
+ values.map((value) =>
254
+ value == null ? null : Array.isArray(value) ? value.map(String) : String(value)
255
+ ),
256
+ )
257
+ }
258
+
223
259
  /** A Vue-owned declared read; no request is made during SSR. */
224
260
  export function useDataRead(state: { value: any }, options: DataReadOptions): void {
225
261
  let value: unknown = null
@@ -281,8 +317,13 @@ export function useDataRead(state: { value: any }, options: DataReadOptions): vo
281
317
  }
282
318
  }
283
319
  }
320
+ let requested: string | undefined
284
321
  const update = (sources: readonly unknown[]): void => {
285
322
  if (sources.includes(Symbol.for('html-next.invalid-result'))) return
323
+ // A deep watch fires on any write it reaches; only changed parameters request again.
324
+ const key = dataKey(sources)
325
+ if (connected && key === requested) return
326
+ requested = key
286
327
  connected = true
287
328
  cancel()
288
329
  const current = ++generation
@@ -344,6 +385,36 @@ function observeConnection(element: Element, check: () => void): () => void {
344
385
  }
345
386
  }
346
387
 
388
+ /**
389
+ * Runs the root's on:connect and on:disconnect handlers each time it joins and leaves a document.
390
+ * Vue hooks cover mount and unmount; the shared native observer sees the root detached and
391
+ * reinserted outside Vue.
392
+ */
393
+ export function useLifecycle(
394
+ root: Readable<Element | null>,
395
+ connect?: () => void,
396
+ disconnect?: () => void,
397
+ ): void {
398
+ let connected = false
399
+ let stop: (() => void) | undefined
400
+ const synchronize = (): void => {
401
+ if ((root.value?.isConnected === true) === connected) return
402
+ connected = !connected
403
+ ;(connected ? connect : disconnect)?.()
404
+ }
405
+ onMounted(() => {
406
+ if (root.value !== null) stop = observeConnection(root.value, synchronize)
407
+ synchronize()
408
+ })
409
+ onBeforeUnmount(() => {
410
+ stop?.()
411
+ if (connected) {
412
+ connected = false
413
+ disconnect?.()
414
+ }
415
+ })
416
+ }
417
+
347
418
  /** Keep native focus on the corresponding control when a root-level $match replaces its element. */
348
419
  export function preserveRootFocus(root: Readable<Element | null>): void {
349
420
  const focusable =
@@ -485,7 +556,7 @@ export function useComponentHost(
485
556
  {
486
557
  type: string
487
558
  callback: (event: Event) => void | (() => void)
488
- target?: Element
559
+ target?: Element | undefined
489
560
  cleanup?: void | (() => void)
490
561
  }
491
562
  >()
@@ -508,9 +579,11 @@ export function useComponentHost(
508
579
  const propHandles = Object.create(null) as Record<string, unknown>
509
580
  for (const name of propNames) {
510
581
  const validity = () => options.propValidity?.(name)
582
+ // One computed per prop: a reader of this prop does not run again when another prop changes.
583
+ const value = computed(() => props?.value[name])
511
584
  propHandles[name] = Object.freeze({
512
585
  get value() {
513
- return props?.value[name]
586
+ return value.value
514
587
  },
515
588
  get inputValue() {
516
589
  return propInputs(name)
@@ -545,7 +618,7 @@ export function useComponentHost(
545
618
  data: Object.fromEntries(
546
619
  Object.entries(data).map(([name, value]) => [name, () => value.value]),
547
620
  ),
548
- acceptsState: options.acceptsState,
621
+ ...(options.acceptsState === undefined ? {} : { acceptsState: options.acceptsState }),
549
622
  }, options.controllerSource?.definition ?? '<component>'),
550
623
  on(type: string, callback: (event: Event) => void | (() => void)): () => void {
551
624
  const entry: Subscription = { type, callback }
@@ -794,3 +867,915 @@ export function createDispatch(
794
867
  return root.value?.dispatchEvent(event) ?? true
795
868
  }
796
869
  }
870
+
871
+ /**
872
+ * A consumer's attributes for the root. Vue sets a name that is also an object property, such as
873
+ * `constructor`, as a DOM property; capitalized, it stays an attribute, which HTML lowercases.
874
+ */
875
+ export function nativeAttrs(attrs: Record<string, unknown>): Record<string, unknown> {
876
+ const names = Object.keys(attrs)
877
+ if (!names.some((name) => Object.hasOwn(Object.prototype, name))) return attrs
878
+ return Object.fromEntries(names.map((name) => [
879
+ Object.hasOwn(Object.prototype, name)
880
+ ? name === '__proto__' ? '__Proto__' : name[0]!.toUpperCase() + name.slice(1)
881
+ : name,
882
+ attrs[name],
883
+ ]))
884
+ }
885
+
886
+ /** Hydrating server markup needs its root to be the element this component renders. */
887
+ export function checkHydratedRoot(expected: string | undefined, tag: string): void {
888
+ const node = getCurrentInstance()?.vnode.el
889
+ if (
890
+ typeof window === 'undefined' || node == null
891
+ || node instanceof Element && node.localName === expected
892
+ ) return
893
+ const message = `Server markup for <${tag}> has an incompatible root.`
894
+ throw Object.assign(new Error(`HR005: ${message}`), {
895
+ name: 'HtmlDiagnosticError',
896
+ diagnostic: Object.freeze({ code: 'HR005', message }),
897
+ })
898
+ }
899
+
900
+ function diagnostic(code: string, message: string): Error {
901
+ return Object.assign(new Error(`${code}: ${message}`), {
902
+ name: 'HtmlDiagnosticError',
903
+ diagnostic: Object.freeze({ code, message }),
904
+ })
905
+ }
906
+
907
+ /** A component's context value from the ancestor that provides it; a missing provider is an error. */
908
+ export function injectContext(tag: string, from: string, name: string): any {
909
+ const value = inject<any>(`html-next:${from}:${name}`)
910
+ if (value === undefined) {
911
+ throw diagnostic('HR009', `<${tag}> requires context \`${name}\` from <${from}>.`)
912
+ }
913
+ return value
914
+ }
915
+
916
+ /** Vue may return an in-progress computed value on a cyclic read; guard the public value access instead. */
917
+ export function cycleCheckedComputed<T>(evaluate: () => T) {
918
+ const value = computed(evaluate)
919
+ let reading = false
920
+ return new Proxy(value, {
921
+ get(target, property) {
922
+ if (property !== 'value') return Reflect.get(target, property)
923
+ if (reading) throw diagnostic('HR006', 'A reactive computed value depends on itself.')
924
+ reading = true
925
+ try {
926
+ return target.value
927
+ } finally {
928
+ reading = false
929
+ }
930
+ },
931
+ })
932
+ }
933
+
934
+ /**
935
+ * A declared prop's reflected root attribute: the authored literal until the consumer passes the
936
+ * prop, then its value as text, absent for null.
937
+ */
938
+ export function useReflectedProp() {
939
+ const instance = getCurrentInstance()
940
+ return (
941
+ name: string,
942
+ kebab: string,
943
+ value: unknown,
944
+ fallback: string | undefined,
945
+ bound: boolean,
946
+ separator?: string,
947
+ ): string | undefined => {
948
+ const incoming = instance?.vnode.props
949
+ if (
950
+ !bound
951
+ && (incoming === null || incoming === undefined
952
+ || (!Object.hasOwn(incoming, name) && !Object.hasOwn(incoming, kebab)))
953
+ ) return fallback
954
+ if (value === null || value === undefined) return undefined
955
+ return Array.isArray(value) && separator !== undefined
956
+ ? value.join(separator)
957
+ : typeof value === 'object'
958
+ ? JSON.stringify(value)
959
+ : String(value)
960
+ }
961
+ }
962
+
963
+ /** A scoped slot's name, which the consumer must fill with a `<template slot>` rather than plain children. */
964
+ export function useScopedSlotName() {
965
+ const slots = useSlots()
966
+ return (value: unknown): string => {
967
+ const name = value == null ? '' : String(value)
968
+ if (slots[name] === undefined && slots.default?.().some((node) => node.props?.slot === name)) {
969
+ throw diagnostic(
970
+ 'HR007',
971
+ 'Scoped slot `' + name + '` requires a consumer <template slot="' + name + '">.',
972
+ )
973
+ }
974
+ return name
975
+ }
976
+ }
977
+
978
+ /** An inline text part that keeps its last accepted text while its value is invalid. */
979
+ export type InlineTextSegment = {
980
+ readonly value: unknown
981
+ readonly text: string
982
+ readonly accepted: boolean
983
+ }
984
+
985
+ export function inlineTextSegment(
986
+ value: unknown,
987
+ accepted: boolean,
988
+ text: (value: any) => string,
989
+ ): InlineTextSegment {
990
+ return {
991
+ value,
992
+ accepted,
993
+ text: accepted && value !== Symbol.for('html-next.invalid-result') ? text(value) ?? '' : '',
994
+ }
995
+ }
996
+
997
+ export const RetainedInlineText = /* @__PURE__ */ defineComponent({
998
+ props: { segments: { type: Array as PropType<InlineTextSegment[]>, required: true } },
999
+ setup(props) {
1000
+ const previous: string[] = []
1001
+ return () =>
1002
+ createTextVNode(
1003
+ props.segments.map((segment, index) => {
1004
+ if (
1005
+ segment.accepted && segment.value !== Symbol.for('html-next.invalid-result')
1006
+ ) previous[index] = segment.text
1007
+ return previous[index] ?? ''
1008
+ }).join(''),
1009
+ )
1010
+ },
1011
+ })
1012
+
1013
+ const KeyedFailure = /* @__PURE__ */ defineComponent({
1014
+ props: { error: { type: null, required: true } },
1015
+ setup(props) {
1016
+ return () => {
1017
+ throw props.error
1018
+ }
1019
+ },
1020
+ })
1021
+
1022
+ /** A keyed list that produces a duplicate key keeps its last rows and reports the error in the browser. */
1023
+ export const KeyedBoundary = /* @__PURE__ */ defineComponent({
1024
+ setup(_props, { slots }) {
1025
+ let last: VNode[] = []
1026
+ return () => {
1027
+ try {
1028
+ last = slots.default?.() ?? []
1029
+ return last
1030
+ } catch (error) {
1031
+ if (
1032
+ !(error instanceof Error)
1033
+ || (error as Error & { diagnostic?: { code?: string } }).diagnostic?.code !== 'HR004'
1034
+ ) throw error
1035
+ if (typeof window === 'undefined') throw error
1036
+ return [...last, h(KeyedFailure, { error })]
1037
+ }
1038
+ }
1039
+ },
1040
+ })
1041
+
1042
+ const warned = new Set<string>()
1043
+ /** An authored value's check: false warns once per authored location. */
1044
+ export function warnUnless(accepted: boolean, location: string, message: string): boolean {
1045
+ if (!accepted && !warned.has(location)) {
1046
+ warned.add(location)
1047
+ console.warn(message)
1048
+ }
1049
+ return accepted
1050
+ }
1051
+
1052
+ /**
1053
+ * A handler's checked write to a ref or through a setter. An invalid result, such as a number that
1054
+ * is not finite, writes nothing. A value neither absent nor of the destination's type warns once for
1055
+ * its authored write (the state `path` in `file`'s `handler`), as the live runtime does, and
1056
+ * leaves the destination as it was.
1057
+ */
1058
+ export function write(
1059
+ to: { value: unknown } | ((value: any) => void),
1060
+ value: unknown,
1061
+ check?: (value: any) => boolean,
1062
+ file?: string,
1063
+ handler?: string,
1064
+ path?: string,
1065
+ ): void {
1066
+ if (
1067
+ value === Symbol.for('html-next.invalid-result')
1068
+ || (typeof value === 'number' && !Number.isFinite(value))
1069
+ ) return
1070
+ if (check !== undefined && value !== undefined && !check(value)) {
1071
+ warnUnless(
1072
+ false,
1073
+ `${file}#${handler}:${path}`,
1074
+ `${file}: HR007: State \`${path}\` does not satisfy its declared type.`,
1075
+ )
1076
+ } else if (typeof to === 'function') to(value)
1077
+ else to.value = value
1078
+ }
1079
+
1080
+ export const isString = (value: unknown): value is string => typeof value === 'string'
1081
+ export const isNumber = (value: unknown): value is number =>
1082
+ typeof value === 'number' && Number.isFinite(value)
1083
+ export const isInteger = (value: unknown): value is number => Number.isInteger(value)
1084
+ export const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean'
1085
+
1086
+ export function truthy(value: unknown): boolean {
1087
+ if (Array.isArray(value)) return value.length > 0
1088
+ if (value instanceof Error) return true
1089
+ if (value !== null && typeof value === 'object') {
1090
+ if (typeof Event !== 'undefined' && 'type' in value) {
1091
+ try {
1092
+ Object.getOwnPropertyDescriptor(Event.prototype, 'type')!.get!.call(value)
1093
+ return true
1094
+ } catch { /* ordinary objects use their fields */ }
1095
+ }
1096
+ return Object.keys(value).length > 0
1097
+ }
1098
+ return Boolean(value)
1099
+ }
1100
+
1101
+ export function text(value: unknown): string {
1102
+ if (Array.isArray(value)) return value.map(text).join(' ')
1103
+ return value === null || value === undefined || typeof value === 'object' ? '' : String(value)
1104
+ }
1105
+
1106
+ export function attribute(value: unknown): any {
1107
+ if (
1108
+ value === null || value === undefined || value === false
1109
+ || (typeof value === 'object' && !Array.isArray(value))
1110
+ ) return undefined
1111
+ return value === true ? '' : text(value)
1112
+ }
1113
+
1114
+ export function list(value: unknown): any[] {
1115
+ return Array.isArray(value) ? value : []
1116
+ }
1117
+
1118
+ export function number(value: unknown): number | undefined {
1119
+ return typeof value === 'number' && !Number.isNaN(value) ? value : undefined
1120
+ }
1121
+
1122
+ // A nonempty scalar call cannot produce the invalid-result sentinel.
1123
+ export type ConcatResult<T extends unknown[]> = T extends
1124
+ [
1125
+ string | number | boolean | null | undefined,
1126
+ ...(string | number | boolean | null | undefined)[],
1127
+ ] ? string | undefined
1128
+ : string | symbol | undefined
1129
+ export function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
1130
+ if (values.some(value => value === Symbol.for('html-next.invalid-result'))) {
1131
+ return Symbol.for('html-next.invalid-result') as ConcatResult<T>
1132
+ }
1133
+ if (values.some(value => value === undefined)) return undefined as ConcatResult<T>
1134
+ if (values.length === 0 || values.some(value => typeof value === 'object' && value !== null)) {
1135
+ return Symbol.for('html-next.invalid-result') as ConcatResult<T>
1136
+ }
1137
+ return values.map(value => value === null ? '' : String(value)).join('') as ConcatResult<T>
1138
+ }
1139
+
1140
+ export function join(...values: unknown[]): string | symbol | undefined {
1141
+ if (values.some(value => value === Symbol.for('html-next.invalid-result'))) {
1142
+ return Symbol.for('html-next.invalid-result')
1143
+ }
1144
+ if (values.some(value => value === undefined)) return undefined
1145
+ if (values.length !== 2) return Symbol.for('html-next.invalid-result')
1146
+ const [items, separator] = values
1147
+ if (!Array.isArray(items) || typeof separator !== 'string') {
1148
+ return Symbol.for('html-next.invalid-result')
1149
+ }
1150
+ if (items.some(value => value === Symbol.for('html-next.invalid-result'))) {
1151
+ return Symbol.for('html-next.invalid-result')
1152
+ }
1153
+ if (items.some(value => value === undefined)) return undefined
1154
+ if (items.some(value => typeof value === 'object' && value !== null)) {
1155
+ return Symbol.for('html-next.invalid-result')
1156
+ }
1157
+ if (new Set(items.filter(value => value !== null).map(value => typeof value)).size > 1) {
1158
+ return Symbol.for('html-next.invalid-result')
1159
+ }
1160
+ return items.map(value => value === null ? '' : String(value)).join(separator)
1161
+ }
1162
+
1163
+ export function math(
1164
+ fn: string,
1165
+ kinds: readonly string[],
1166
+ values: readonly unknown[],
1167
+ ): number | string | symbol | undefined {
1168
+ if (values.includes(Symbol.for('html-next.invalid-result'))) {
1169
+ return Symbol.for('html-next.invalid-result')
1170
+ }
1171
+ if (values.some(value => value === undefined || value === null)) return undefined
1172
+ if (
1173
+ (fn === 'abs' || fn === 'negate') && values.length !== 1
1174
+ || fn === 'round' && (values.length < 1 || values.length > 2)
1175
+ || (fn === 'min' || fn === 'max') && values.length === 0
1176
+ || fn === 'clamp' && values.length !== 3
1177
+ ) return Symbol.for('html-next.invalid-result')
1178
+ const kind = kinds[0]
1179
+ const dimensional = kind === 'length' || kind === 'percentage' || kind === 'duration'
1180
+ if (!dimensional && kind !== 'number') return Symbol.for('html-next.invalid-result')
1181
+ let unit: string | undefined
1182
+ const numbers: number[] = []
1183
+ for (let index = 0; index < values.length; index++) {
1184
+ if (kinds[index] !== kind) return Symbol.for('html-next.invalid-result')
1185
+ const value = values[index]
1186
+ if (!dimensional) {
1187
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
1188
+ return Symbol.for('html-next.invalid-result')
1189
+ }
1190
+ numbers.push(value)
1191
+ continue
1192
+ }
1193
+ if (typeof value !== 'string') return Symbol.for('html-next.invalid-result')
1194
+ const match =
1195
+ /^(-?(?:\d+(?:\.\d+)?|\.\d+))(vmin|vmax|rem|px|em|vw|vh|ch|ex|cm|mm|in|pt|pc|q|ms|s|%)$/.exec(
1196
+ value,
1197
+ )
1198
+ if (match === null || unit !== undefined && match[2] !== unit) {
1199
+ return Symbol.for('html-next.invalid-result')
1200
+ }
1201
+ unit = match[2]
1202
+ if (
1203
+ (unit === '%' ? 'percentage' : unit === 'ms' || unit === 's' ? 'duration' : 'length') !== kind
1204
+ ) return Symbol.for('html-next.invalid-result')
1205
+ const number = Number(match[1])
1206
+ if (!Number.isFinite(number)) return Symbol.for('html-next.invalid-result')
1207
+ numbers.push(number)
1208
+ }
1209
+ let result: number
1210
+ switch (fn) {
1211
+ case 'abs':
1212
+ result = Math.abs(numbers[0]!)
1213
+ break
1214
+ case 'negate':
1215
+ result = -numbers[0]!
1216
+ break
1217
+ case 'round': {
1218
+ const step = Math.abs(numbers[1] ?? 1)
1219
+ if (step === 0) return Symbol.for('html-next.invalid-result')
1220
+ result = Math.round(numbers[0]! / step) * step
1221
+ break
1222
+ }
1223
+ case 'min':
1224
+ result = Math.min(...numbers)
1225
+ break
1226
+ case 'max':
1227
+ result = Math.max(...numbers)
1228
+ break
1229
+ case 'clamp':
1230
+ result = Math.max(numbers[0]!, Math.min(numbers[1]!, numbers[2]!))
1231
+ break
1232
+ default:
1233
+ return Symbol.for('html-next.invalid-result')
1234
+ }
1235
+ return !Number.isFinite(result)
1236
+ ? Symbol.for('html-next.invalid-result')
1237
+ : unit === undefined
1238
+ ? result
1239
+ : String(result) + unit
1240
+ }
1241
+
1242
+ export function arithmetic(
1243
+ op: string,
1244
+ leftKind: string,
1245
+ rightKind: string,
1246
+ left: unknown,
1247
+ right: unknown,
1248
+ operate: (a: number, b: number) => number,
1249
+ ): string | symbol | undefined {
1250
+ const invalid = Symbol.for('html-next.invalid-result')
1251
+ if (left === invalid || right === invalid) return invalid
1252
+ if (left === null || left === undefined || right === null || right === undefined) return undefined
1253
+ const isDimension = (kind: string): boolean =>
1254
+ kind === 'length' || kind === 'percentage' || kind === 'duration'
1255
+ const parse = (value: unknown, kind: string): { number: number; unit: string } | undefined => {
1256
+ if (typeof value !== 'string' || !isDimension(kind)) return undefined
1257
+ const match =
1258
+ /^(-?(?:\d+(?:\.\d+)?|\.\d+))(vmin|vmax|rem|px|em|vw|vh|ch|ex|cm|mm|in|pt|pc|q|ms|s|%)$/.exec(
1259
+ value,
1260
+ )
1261
+ if (match === null) return undefined
1262
+ const unit = match[2]!
1263
+ if (
1264
+ (unit === '%' ? 'percentage' : unit === 'ms' || unit === 's' ? 'duration' : 'length') !== kind
1265
+ ) return undefined
1266
+ const number = Number(match[1])
1267
+ return Number.isFinite(number) ? { number, unit } : undefined
1268
+ }
1269
+ const x = parse(left, leftKind), y = parse(right, rightKind)
1270
+ if (isDimension(leftKind) && x === undefined || isDimension(rightKind) && y === undefined) {
1271
+ return invalid
1272
+ }
1273
+ let value: number, unit: string
1274
+ if (op === '+' || op === '-') {
1275
+ if (x === undefined || y === undefined || leftKind !== rightKind || x.unit !== y.unit) {
1276
+ return invalid
1277
+ }
1278
+ value = operate(x.number, y.number)
1279
+ unit = x.unit
1280
+ } else if (op === '*') {
1281
+ const quantity = x ?? y
1282
+ const factor = x === undefined ? left : right
1283
+ if (
1284
+ quantity === undefined || x !== undefined && y !== undefined || typeof factor !== 'number'
1285
+ || !Number.isFinite(factor)
1286
+ ) return invalid
1287
+ value = operate(quantity.number, factor)
1288
+ unit = quantity.unit
1289
+ } else {
1290
+ if (
1291
+ op !== '/' || x === undefined || y !== undefined || typeof right !== 'number'
1292
+ || !Number.isFinite(right) || right === 0
1293
+ ) return invalid
1294
+ value = operate(x.number, right)
1295
+ unit = x.unit
1296
+ }
1297
+ return Number.isFinite(value) ? String(value) + unit : invalid
1298
+ }
1299
+
1300
+ export function sortBy(items: any[], keys: readonly string[]): any[] {
1301
+ const field = (item: any, path: string): unknown =>
1302
+ path !== '' && item !== null && typeof item === 'object' && !Array.isArray(item)
1303
+ ? path.split('.').reduce((value, key) => value?.[key], item)
1304
+ : item
1305
+ return items.slice().sort((a, b) => {
1306
+ for (const key of keys) {
1307
+ const descending = key.startsWith('-')
1308
+ const path = descending ? key.slice(1) : key
1309
+ const x = field(a, path), y = field(b, path)
1310
+ const order = typeof x === 'number' && typeof y === 'number'
1311
+ ? x - y
1312
+ : text(x).localeCompare(text(y))
1313
+ if (order !== 0) return descending ? -order : order
1314
+ }
1315
+ return 0
1316
+ })
1317
+ }
1318
+
1319
+ export function eachRows<T>(
1320
+ items: readonly T[],
1321
+ ): {
1322
+ item: T
1323
+ index: number
1324
+ loop: { index: number; first: boolean; last: boolean; count: number }
1325
+ }[] {
1326
+ return items.map((item, index) => ({
1327
+ item,
1328
+ index,
1329
+ loop: { index, first: index === 0, last: index === items.length - 1, count: items.length },
1330
+ }))
1331
+ }
1332
+
1333
+ export function uniqueKeys<T>(
1334
+ items: readonly T[],
1335
+ keyOf: (
1336
+ item: T,
1337
+ index: number,
1338
+ loop: { index: number; first: boolean; last: boolean; count: number },
1339
+ ) => unknown,
1340
+ ): readonly T[] {
1341
+ const seen = new Set<unknown>()
1342
+ for (let index = 0; index < items.length; index += 1) {
1343
+ const key = keyOf(items[index]!, index, {
1344
+ index,
1345
+ first: index === 0,
1346
+ last: index === items.length - 1,
1347
+ count: items.length,
1348
+ })
1349
+ if (seen.has(key)) {
1350
+ const message = `A keyed list produced duplicate key \`${text(key)}\`.`
1351
+ throw Object.assign(new Error(`HR004: ${message}`), {
1352
+ name: 'HtmlDiagnosticError',
1353
+ diagnostic: Object.freeze({ code: 'HR004', message }),
1354
+ })
1355
+ }
1356
+ seen.add(key)
1357
+ }
1358
+ return items
1359
+ }
1360
+
1361
+ /**
1362
+ * Digits after the point in `value`'s shortest round-trip text, as `Number#toString` writes it:
1363
+ * 2 for 1.25, 7 for 1e-7, and 0 for an integer, 1e21, NaN or Infinity. Writing that text made an
1364
+ * addition about ten times slower (200 ns against 20 ns), so up to 22 places, where 10^places is
1365
+ * exact, the fewest places at which `value` survives rounding stand in for it. That count is never
1366
+ * below the text's, and differs only for a value of more than 15 significant digits, which
1367
+ * `decimalResult` leaves as a double either way.
1368
+ */
1369
+ export function decimalPlaces(value: number): number {
1370
+ if (Number.isInteger(value)) return 0
1371
+ for (let places = 1; places <= 22; places += 1) {
1372
+ if (Math.round(value * 10 ** places) / 10 ** places === value) return places
1373
+ }
1374
+ const [digits, exponent] = String(value).split('e')
1375
+ const point = digits!.indexOf('.')
1376
+ return Math.max(0, (point < 0 ? 0 : digits!.length - point - 1) - Number(exponent ?? 0))
1377
+ }
1378
+
1379
+ /**
1380
+ * The double nearest the exact decimal result: `a` and `b` become integers at `left` and `right`
1381
+ * places, `combine` joins them, and the integer is read back at `places`. Every step is exact while
1382
+ * the operands and `result` stay below 10^15 at `places`, the 15 significant digits a double always
1383
+ * holds; past that (or for a non-finite value, or with no places) the double `result` stands.
1384
+ * Dividing by 10^places is exact only up to 10^22, so past 22 places a nonzero integer is read back
1385
+ * by parsing its decimal text, which rounds exactly too. A zero divides, keeping its sign.
1386
+ */
1387
+ export function decimalResult(
1388
+ result: number,
1389
+ a: number,
1390
+ b: number,
1391
+ left: number,
1392
+ right: number,
1393
+ places: number,
1394
+ combine: (a: number, b: number) => number,
1395
+ ): number {
1396
+ if (!(places > 0 && Math.max(Math.abs(a), Math.abs(b), Math.abs(result)) * 10 ** places < 1e15)) {
1397
+ return result
1398
+ }
1399
+ const integer = combine(Math.round(a * 10 ** left), Math.round(b * 10 ** right))
1400
+ return places > 22 && integer !== 0 ? Number(`${integer}e-${places}`) : integer / 10 ** places
1401
+ }
1402
+
1403
+ /** `a + b` at the larger operand's decimal places: `decimalAdd(0.1, 0.2)` is 0.3. */
1404
+ export function decimalAdd(a: number, b: number): number {
1405
+ const places = Math.max(decimalPlaces(a), decimalPlaces(b))
1406
+ return decimalResult(a + b, a, b, places, places, places, (x, y) => x + y)
1407
+ }
1408
+
1409
+ /** `a - b` at the larger operand's decimal places: `decimalSubtract(0.3, 0.1)` is 0.2. */
1410
+ export function decimalSubtract(a: number, b: number): number {
1411
+ const places = Math.max(decimalPlaces(a), decimalPlaces(b))
1412
+ return decimalResult(a - b, a, b, places, places, places, (x, y) => x - y)
1413
+ }
1414
+
1415
+ /** `a * b` at the sum of the operands' decimal places: `decimalMultiply(0.1, 0.2)` is 0.02. */
1416
+ export function decimalMultiply(a: number, b: number): number {
1417
+ const left = decimalPlaces(a)
1418
+ const right = decimalPlaces(b)
1419
+ return decimalResult(a * b, a, b, left, right, left + right, (x, y) => x * y)
1420
+ }
1421
+
1422
+ /** `a / b` at full double precision: `decimalDivide(1, 3)` is 0.3333333333333333 and `decimalDivide(1, 0)` is Infinity. */
1423
+ export function decimalDivide(a: number, b: number): number {
1424
+ return a / b
1425
+ }
1426
+
1427
+ /**
1428
+ * `a % b` at the larger operand's decimal places, with the dividend's sign as JavaScript's `%`:
1429
+ * `decimalRemainder(0.3, 0.1)` is 0, where JavaScript gives 0.09999999999999998.
1430
+ */
1431
+ export function decimalRemainder(a: number, b: number): number {
1432
+ const places = Math.max(decimalPlaces(a), decimalPlaces(b))
1433
+ return decimalResult(a % b, a, b, places, places, places, (x, y) => x % y)
1434
+ }
1435
+
1436
+ export function createFormatValue(): any {
1437
+ // FIFO bounds native instances and retained keys; only constructor inputs, never values, are cached.
1438
+ const cache = new Map()
1439
+ function formatterFor(name: any, locale: any, options: any) {
1440
+ const constructor = Reflect.get(Intl, name)
1441
+ // There is no cheap native query for changes to the default time zone. Keep native lookup for
1442
+ // instants without an explicit zone; civil HTML values already supply their fixed UTC anchor.
1443
+ if (name === 'DateTimeFormat' && options.timeZone === undefined) {
1444
+ return new constructor(locale, options)
1445
+ }
1446
+ const entries = []
1447
+ for (const key of Object.keys(options).sort()) {
1448
+ const value = options[key]
1449
+ if (value === undefined) {
1450
+ continue
1451
+ }
1452
+ // Native option coercion can observe mutable objects. Bypass caching rather than stringify
1453
+ // them or collapse NaN/infinity into null, which would change validation and side effects.
1454
+ if (
1455
+ value !== null && typeof value !== 'string' && typeof value !== 'boolean'
1456
+ && typeof value !== 'number'
1457
+ || typeof value === 'number' && !Number.isFinite(value)
1458
+ ) {
1459
+ return new constructor(locale, options)
1460
+ }
1461
+ entries.push([key, typeof value, Object.is(value, -0) ? '-0' : value])
1462
+ }
1463
+ const language = locale === undefined && typeof navigator !== 'undefined'
1464
+ ? navigator.language
1465
+ : undefined
1466
+ const key = JSON.stringify([name, locale, language, entries])
1467
+ if (key.length > 4096) {
1468
+ return new constructor(locale, options)
1469
+ }
1470
+ const cached = cache.get(key)
1471
+ if (cached !== undefined && cached.constructor === constructor) {
1472
+ return cached.value
1473
+ }
1474
+ const value = new constructor(locale, options)
1475
+ if (cache.size >= 128 && !cache.has(key)) {
1476
+ cache.delete(cache.keys().next().value)
1477
+ }
1478
+ cache.set(key, { constructor, value })
1479
+ return value
1480
+ }
1481
+ /**
1482
+ * The native Intl adapter. Self-contained so converters emit this same implementation only when
1483
+ * authored expressions use formatting, without importing the live parser or interpreter.
1484
+ * undefined is absence; the shared invalid-result symbol tells each target to retain its output.
1485
+ */
1486
+ return function formatValue(value: any, inputType: any, operation: any, ...args: any[]) {
1487
+ const invalid = Symbol.for('html-next.invalid-result')
1488
+ if (value === invalid || args.includes(invalid)) {
1489
+ return invalid
1490
+ }
1491
+ if (value === undefined || value === null || args.some((arg: any) => arg === undefined)) {
1492
+ return undefined
1493
+ }
1494
+ const end = operation === 'formatRange' ? args.shift() : undefined
1495
+ if (operation === 'formatRange' && (end === null || end === undefined)) {
1496
+ return undefined
1497
+ }
1498
+ const explicit = typeof args[0] === 'string'
1499
+ const defaults = {
1500
+ number: 'number',
1501
+ integer: 'number',
1502
+ percentage: 'percent',
1503
+ date: 'date',
1504
+ time: 'time',
1505
+ datetime: 'dateTime',
1506
+ 'datetime-local': 'dateTime',
1507
+ duration: 'duration',
1508
+ list: 'list',
1509
+ }
1510
+ const format = explicit ? args.shift() : Reflect.get(defaults, inputType ?? '')
1511
+ const options = args.length > 0 ? args.shift() : {}
1512
+ const locale = args.shift()
1513
+ if (
1514
+ args.length > 0 || !format || options === null || typeof options !== 'object'
1515
+ || Array.isArray(options) || locale !== undefined && typeof locale !== 'string'
1516
+ ) {
1517
+ return invalid
1518
+ }
1519
+ try {
1520
+ const durationFields = [
1521
+ 'years',
1522
+ 'months',
1523
+ 'weeks',
1524
+ 'days',
1525
+ 'hours',
1526
+ 'minutes',
1527
+ 'seconds',
1528
+ 'milliseconds',
1529
+ 'microseconds',
1530
+ 'nanoseconds',
1531
+ ]
1532
+ const settings = { ...options }
1533
+ let formatter
1534
+ let input = value
1535
+ let last = end
1536
+ let zoneFree = false
1537
+ if (['number', 'currency', 'percent', 'unit'].includes(format)) {
1538
+ if (format !== 'number') {
1539
+ if (settings.style !== undefined && settings.style !== format) {
1540
+ return invalid
1541
+ }
1542
+ settings.style = format
1543
+ }
1544
+ const quantity = (candidate: any) => {
1545
+ if (
1546
+ inputType === 'percentage' && typeof candidate === 'string'
1547
+ && /^-?(?:\d+(?:\.\d+)?|\.\d+)%$/.test(candidate)
1548
+ ) {
1549
+ return Number(candidate.slice(0, -1)) / 100
1550
+ }
1551
+ return candidate
1552
+ }
1553
+ input = quantity(input)
1554
+ last = quantity(last)
1555
+ if (
1556
+ typeof input !== 'number' || !Number.isFinite(input)
1557
+ || operation === 'formatRange' && (typeof last !== 'number' || !Number.isFinite(last))
1558
+ ) {
1559
+ return invalid
1560
+ }
1561
+ formatter = formatterFor('NumberFormat', locale, settings)
1562
+ } else if (['date', 'time', 'dateTime'].includes(format)) {
1563
+ const civil = inputType === 'date' || inputType === 'time' || inputType === 'datetime-local'
1564
+ || typeof input === 'string' && !/(?:Z|[+-]\d\d:\d\d)$/.test(input)
1565
+ zoneFree = civil
1566
+ if (civil && (settings.timeZone !== undefined || settings.timeZoneName !== undefined)) {
1567
+ return invalid
1568
+ }
1569
+ if (
1570
+ format === 'date'
1571
+ && (settings.timeStyle !== undefined
1572
+ || ['hour', 'minute', 'second', 'dayPeriod', 'fractionalSecondDigits'].some((
1573
+ key: any,
1574
+ ) => settings[key] !== undefined))
1575
+ || format === 'time'
1576
+ && (settings.dateStyle !== undefined
1577
+ || ['year', 'month', 'day', 'weekday', 'era'].some((key: any) =>
1578
+ settings[key] !== undefined
1579
+ ))
1580
+ ) {
1581
+ return invalid
1582
+ }
1583
+ const fields = [
1584
+ 'year',
1585
+ 'month',
1586
+ 'day',
1587
+ 'weekday',
1588
+ 'era',
1589
+ 'hour',
1590
+ 'minute',
1591
+ 'second',
1592
+ 'dayPeriod',
1593
+ 'fractionalSecondDigits',
1594
+ ]
1595
+ if (
1596
+ settings.dateStyle === undefined && settings.timeStyle === undefined
1597
+ && !fields.some((key: any) => settings[key] !== undefined)
1598
+ ) {
1599
+ if (format !== 'time') {
1600
+ settings.dateStyle = 'medium'
1601
+ }
1602
+ if (format !== 'date') {
1603
+ settings.timeStyle = 'medium'
1604
+ }
1605
+ }
1606
+ if (civil) {
1607
+ settings.timeZone = 'UTC'
1608
+ }
1609
+ const asDate = (candidate: any) => {
1610
+ if (typeof candidate === 'number' && Number.isFinite(candidate)) {
1611
+ return new Date(candidate)
1612
+ }
1613
+ if (typeof candidate !== 'string') {
1614
+ return undefined
1615
+ }
1616
+ let written = candidate.replace(' ', 'T')
1617
+ if (/^\d\d:\d\d(?::\d\d(?:\.\d{1,3})?)?$/.test(written)) {
1618
+ if (format !== 'time') {
1619
+ return undefined
1620
+ }
1621
+ written = '1970-01-01T' + written + 'Z'
1622
+ } else if (/^\d{4,}-\d\d-\d\d$/.test(written)) {
1623
+ if (format !== 'date') {
1624
+ return undefined
1625
+ }
1626
+ written += 'T00:00:00Z'
1627
+ } else if (/^\d{4,}-\d\d-\d\dT\d\d:\d\d(?::\d\d(?:\.\d{1,3})?)?$/.test(written)) {
1628
+ written += 'Z'
1629
+ } else if (
1630
+ !/^\d{4,}-\d\d-\d\dT\d\d:\d\d(?::\d\d(?:\.\d{1,3})?)?(?:Z|[+-]\d\d:\d\d)$/.test(written)
1631
+ ) {
1632
+ return undefined
1633
+ }
1634
+ const date = new Date(
1635
+ written.replace(/^(\d{5,})-/, (_match: any, year: any) =>
1636
+ '+' + year.padStart(6, '0') + '-'),
1637
+ )
1638
+ if (!Number.isFinite(date.getTime())) {
1639
+ return undefined
1640
+ }
1641
+ // Native Date normalizes invalid days; authored HTML dates must not roll into another day.
1642
+ const match = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d))?/.exec(written)
1643
+ if (!match) {
1644
+ return undefined
1645
+ }
1646
+ const probe = new Date(0)
1647
+ probe.setUTCFullYear(Number(match[1]), Number(match[2]) - 1, Number(match[3]))
1648
+ if (
1649
+ Number(match[1]) === 0 || probe.getUTCMonth() !== Number(match[2]) - 1
1650
+ || probe.getUTCDate() !== Number(match[3]) || Number(match[4]) > 23
1651
+ || Number(match[5]) > 59 || Number(match[6] ?? 0) > 59
1652
+ ) {
1653
+ return undefined
1654
+ }
1655
+ return date
1656
+ }
1657
+ input = asDate(input)
1658
+ last = operation === 'formatRange' ? asDate(last) : undefined
1659
+ if (!input || operation === 'formatRange' && !last) {
1660
+ return invalid
1661
+ }
1662
+ formatter = formatterFor('DateTimeFormat', locale, settings)
1663
+ } else {
1664
+ if (operation === 'formatRange') {
1665
+ return invalid
1666
+ }
1667
+ if (format === 'relativeTime') {
1668
+ if (
1669
+ typeof input !== 'number' || !Number.isFinite(input)
1670
+ || typeof settings.unit !== 'string'
1671
+ ) {
1672
+ return invalid
1673
+ }
1674
+ const unit = settings.unit
1675
+ delete settings.unit
1676
+ formatter = formatterFor('RelativeTimeFormat', locale, settings)
1677
+ return operation === 'formatParts'
1678
+ ? formatter.formatToParts(input, unit)
1679
+ : formatter.format(input, unit)
1680
+ }
1681
+ if (format === 'list') {
1682
+ if (!Array.isArray(input) || input.some((item: any) => typeof item !== 'string')) {
1683
+ return invalid
1684
+ }
1685
+ formatter = formatterFor('ListFormat', locale, settings)
1686
+ } else if (format === 'duration') {
1687
+ if (inputType === 'duration' && typeof input === 'string') {
1688
+ const match = /^(-?(?:\d+(?:\.\d+)?|\.\d+))(ms|s)$/.exec(input)
1689
+ if (!match) {
1690
+ return invalid
1691
+ }
1692
+ const milliseconds = Number(match[1]) * (match[2] === 's' ? 1000 : 1)
1693
+ if (!Number.isFinite(milliseconds)) {
1694
+ return invalid
1695
+ }
1696
+ const hours = Math.trunc(milliseconds / 3600000)
1697
+ const minutes = Math.trunc((milliseconds % 3600000) / 60000)
1698
+ const seconds = Math.trunc((milliseconds % 60000) / 1000)
1699
+ input = {
1700
+ hours,
1701
+ minutes,
1702
+ seconds,
1703
+ milliseconds: Math.trunc(milliseconds % 1000),
1704
+ microseconds: Math.trunc((milliseconds - Math.trunc(milliseconds)) * 1000),
1705
+ nanoseconds: Math.round(
1706
+ (milliseconds * 1000 - Math.trunc(milliseconds * 1000)) * 1000,
1707
+ ),
1708
+ }
1709
+ }
1710
+ if (
1711
+ input === null || typeof input !== 'object' || Array.isArray(input)
1712
+ || Object.keys(input).some((key: any) => !durationFields.includes(key))
1713
+ ) {
1714
+ return invalid
1715
+ }
1716
+ const DurationFormat = Reflect.get(Intl, 'DurationFormat')
1717
+ if (!DurationFormat) {
1718
+ return invalid
1719
+ }
1720
+ formatter = formatterFor('DurationFormat', locale, settings)
1721
+ } else if (format === 'displayName') {
1722
+ if (typeof input !== 'string' || operation === 'formatParts') {
1723
+ return invalid
1724
+ }
1725
+ return formatterFor('DisplayNames', locale, settings).of(input)
1726
+ } else if (format === 'plural') {
1727
+ if (typeof input !== 'number' || !Number.isFinite(input) || operation === 'formatParts') {
1728
+ return invalid
1729
+ }
1730
+ const forms = settings.forms
1731
+ if (
1732
+ !forms || typeof forms !== 'object' || Array.isArray(forms)
1733
+ || typeof forms.other !== 'string' || Object.entries(forms).some(([key, entry]: any) =>
1734
+ !['zero', 'one', 'two', 'few', 'many', 'other'].includes(key)
1735
+ || typeof entry !== 'string'
1736
+ )
1737
+ ) {
1738
+ return invalid
1739
+ }
1740
+ delete settings.forms
1741
+ const category = formatterFor('PluralRules', locale, settings).select(input)
1742
+ const message = forms[category] ?? forms.other
1743
+ const numberOptions = { ...settings }
1744
+ delete numberOptions.type
1745
+ delete numberOptions.forms
1746
+ const number = formatterFor('NumberFormat', locale, numberOptions).format(input)
1747
+ return message.replace(/#/g, () => number)
1748
+ }
1749
+ }
1750
+ if (!zoneFree && operation !== 'formatParts') {
1751
+ return operation === 'formatRange'
1752
+ ? formatter.formatRange(input, last)
1753
+ : formatter.format(input)
1754
+ }
1755
+ const parts = operation === 'formatRange'
1756
+ ? formatter.formatRangeToParts(input, last)
1757
+ : formatter.formatToParts(input)
1758
+ if (
1759
+ zoneFree && operation !== 'formatParts'
1760
+ && !parts.some((part: any) => part.type === 'timeZoneName')
1761
+ ) {
1762
+ return operation === 'formatRange'
1763
+ ? formatter.formatRange(input, last)
1764
+ : formatter.format(input)
1765
+ }
1766
+ const visible = zoneFree
1767
+ ? parts.filter((part: any, index: any) =>
1768
+ part.type !== 'timeZoneName'
1769
+ && !(part.type === 'literal' && /^[\s(),]*$/.test(part.value)
1770
+ && (parts[index - 1]?.type === 'timeZoneName'
1771
+ || parts[index + 1]?.type === 'timeZoneName'))
1772
+ )
1773
+ : parts
1774
+ return operation === 'formatParts' ? visible : visible.map((part: any) => part.value).join('')
1775
+ } catch {
1776
+ return invalid
1777
+ }
1778
+ }
1779
+ }
1780
+
1781
+ export const formatValue = /* @__PURE__ */ createFormatValue()