@accelint/design-toolkit 7.0.1 → 8.0.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 (678) hide show
  1. package/README.md +1 -1
  2. package/catalog-info.yaml +12 -6
  3. package/dist/components/accordion/context.d.ts +0 -2
  4. package/dist/components/accordion/group.d.ts +0 -2
  5. package/dist/components/accordion/group.js +1 -1
  6. package/dist/components/accordion/group.js.map +1 -1
  7. package/dist/components/accordion/header.d.ts +0 -2
  8. package/dist/components/accordion/header.js +1 -1
  9. package/dist/components/accordion/header.js.map +1 -1
  10. package/dist/components/accordion/index.d.ts +0 -2
  11. package/dist/components/accordion/index.js +1 -1
  12. package/dist/components/accordion/index.js.map +1 -1
  13. package/dist/components/accordion/panel.d.ts +0 -2
  14. package/dist/components/accordion/panel.js +1 -1
  15. package/dist/components/accordion/panel.js.map +1 -1
  16. package/dist/components/accordion/styles.module.css +65 -0
  17. package/dist/components/accordion/trigger.d.ts +0 -2
  18. package/dist/components/accordion/trigger.js +1 -1
  19. package/dist/components/accordion/trigger.js.map +1 -1
  20. package/dist/components/accordion/types.d.ts +5 -5
  21. package/dist/components/action-bar/index.d.ts +1 -1
  22. package/dist/components/action-bar/index.js +1 -1
  23. package/dist/components/action-bar/index.js.map +1 -1
  24. package/dist/components/action-bar/styles.module.css +27 -0
  25. package/dist/components/action-bar/types.d.ts +3 -1
  26. package/dist/components/avatar/context.d.ts +0 -3
  27. package/dist/components/avatar/index.d.ts +0 -3
  28. package/dist/components/avatar/index.js +1 -1
  29. package/dist/components/avatar/index.js.map +1 -1
  30. package/dist/components/avatar/styles.module.css +45 -0
  31. package/dist/components/avatar/types.d.ts +1 -4
  32. package/dist/components/badge/context.d.ts +0 -2
  33. package/dist/components/badge/index.d.ts +0 -2
  34. package/dist/components/badge/index.js +1 -1
  35. package/dist/components/badge/index.js.map +1 -1
  36. package/dist/components/badge/styles.module.css +67 -0
  37. package/dist/components/badge/types.d.ts +3 -4
  38. package/dist/components/breadcrumbs/index.js +1 -1
  39. package/dist/components/breadcrumbs/index.js.map +1 -1
  40. package/dist/components/breadcrumbs/item.js +1 -1
  41. package/dist/components/breadcrumbs/item.js.map +1 -1
  42. package/dist/components/breadcrumbs/styles.module.css +41 -0
  43. package/dist/components/button/context.d.ts +0 -3
  44. package/dist/components/button/index.d.ts +0 -3
  45. package/dist/components/button/index.js +1 -1
  46. package/dist/components/button/index.js.map +1 -1
  47. package/dist/components/button/link.d.ts +0 -3
  48. package/dist/components/button/link.js +1 -1
  49. package/dist/components/button/link.js.map +1 -1
  50. package/dist/components/button/styles.module.css +917 -0
  51. package/dist/components/button/toggle.d.ts +0 -3
  52. package/dist/components/button/toggle.js +1 -1
  53. package/dist/components/button/toggle.js.map +1 -1
  54. package/dist/components/button/types.d.ts +6 -6
  55. package/dist/components/checkbox/group.js +1 -1
  56. package/dist/components/checkbox/group.js.map +1 -1
  57. package/dist/components/checkbox/index.js +1 -1
  58. package/dist/components/checkbox/index.js.map +1 -1
  59. package/dist/components/checkbox/styles.module.css +111 -0
  60. package/dist/components/chip/context.d.ts +3 -6
  61. package/dist/components/chip/context.js +1 -1
  62. package/dist/components/chip/context.js.map +1 -1
  63. package/dist/components/chip/deletable.d.ts +0 -3
  64. package/dist/components/chip/deletable.js +1 -1
  65. package/dist/components/chip/deletable.js.map +1 -1
  66. package/dist/components/chip/index.d.ts +0 -3
  67. package/dist/components/chip/index.js +1 -1
  68. package/dist/components/chip/index.js.map +1 -1
  69. package/dist/components/chip/list.d.ts +0 -3
  70. package/dist/components/chip/list.js +1 -1
  71. package/dist/components/chip/list.js.map +1 -1
  72. package/dist/components/chip/selectable.d.ts +0 -3
  73. package/dist/components/chip/selectable.js +1 -1
  74. package/dist/components/chip/selectable.js.map +1 -1
  75. package/dist/components/chip/styles.module.css +129 -0
  76. package/dist/components/chip/types.d.ts +7 -8
  77. package/dist/components/classification-badge/context.d.ts +1 -2
  78. package/dist/components/classification-badge/index.d.ts +1 -2
  79. package/dist/components/classification-badge/index.js +1 -1
  80. package/dist/components/classification-badge/index.js.map +1 -1
  81. package/dist/components/classification-badge/styles.module.css +63 -0
  82. package/dist/components/classification-badge/types.d.ts +3 -5
  83. package/dist/components/classification-banner/context.d.ts +0 -2
  84. package/dist/components/classification-banner/index.d.ts +0 -2
  85. package/dist/components/classification-banner/index.js +1 -1
  86. package/dist/components/classification-banner/index.js.map +1 -1
  87. package/dist/components/classification-banner/styles.module.css +55 -0
  88. package/dist/components/classification-banner/types.d.ts +4 -5
  89. package/dist/components/color-picker/index.js +1 -1
  90. package/dist/components/color-picker/index.js.map +1 -1
  91. package/dist/components/color-picker/styles.module.css +43 -0
  92. package/dist/components/combobox-field/context.d.ts +0 -3
  93. package/dist/components/combobox-field/index.d.ts +0 -3
  94. package/dist/components/combobox-field/index.js +1 -1
  95. package/dist/components/combobox-field/index.js.map +1 -1
  96. package/dist/components/combobox-field/styles.module.css +101 -0
  97. package/dist/components/combobox-field/types.d.ts +0 -3
  98. package/dist/components/coordinate-field/context.d.ts +77 -0
  99. package/dist/components/coordinate-field/context.js +2 -0
  100. package/dist/components/coordinate-field/context.js.map +1 -0
  101. package/dist/components/coordinate-field/coordinate-utils.d.ts +282 -0
  102. package/dist/components/coordinate-field/coordinate-utils.js +2 -0
  103. package/dist/components/coordinate-field/coordinate-utils.js.map +1 -0
  104. package/dist/components/coordinate-field/index.d.ts +66 -0
  105. package/dist/components/coordinate-field/index.js +4 -0
  106. package/dist/components/coordinate-field/index.js.map +1 -0
  107. package/dist/components/coordinate-field/segment-configs.d.ts +163 -0
  108. package/dist/components/coordinate-field/segment-configs.js +2 -0
  109. package/dist/components/coordinate-field/segment-configs.js.map +1 -0
  110. package/dist/components/coordinate-field/segment.d.ts +39 -0
  111. package/dist/components/coordinate-field/segment.js +4 -0
  112. package/dist/components/coordinate-field/segment.js.map +1 -0
  113. package/dist/components/coordinate-field/styles.module.css +129 -0
  114. package/dist/components/coordinate-field/types.d.ts +194 -0
  115. package/dist/components/coordinate-field/types.js +2 -0
  116. package/dist/components/coordinate-field/types.js.map +1 -0
  117. package/dist/components/coordinate-field/width-utils.d.ts +29 -0
  118. package/dist/components/coordinate-field/width-utils.js +2 -0
  119. package/dist/components/coordinate-field/width-utils.js.map +1 -0
  120. package/dist/components/date-field/index.d.ts +0 -2
  121. package/dist/components/date-field/index.js +1 -1
  122. package/dist/components/date-field/index.js.map +1 -1
  123. package/dist/components/date-field/styles.module.css +103 -0
  124. package/dist/components/date-field/types.d.ts +1 -3
  125. package/dist/components/details-list/context.d.ts +0 -2
  126. package/dist/components/details-list/index.d.ts +0 -2
  127. package/dist/components/details-list/index.js +1 -1
  128. package/dist/components/details-list/index.js.map +1 -1
  129. package/dist/components/details-list/label.d.ts +0 -2
  130. package/dist/components/details-list/styles.module.css +52 -0
  131. package/dist/components/details-list/types.d.ts +2 -3
  132. package/dist/components/details-list/value.d.ts +0 -2
  133. package/dist/components/dialog/content.js +1 -1
  134. package/dist/components/dialog/content.js.map +1 -1
  135. package/dist/components/dialog/footer.js +1 -1
  136. package/dist/components/dialog/footer.js.map +1 -1
  137. package/dist/components/dialog/index.js +1 -1
  138. package/dist/components/dialog/index.js.map +1 -1
  139. package/dist/components/dialog/styles.module.css +86 -0
  140. package/dist/components/dialog/title.js +1 -1
  141. package/dist/components/dialog/title.js.map +1 -1
  142. package/dist/components/dialog/trigger.d.ts +5 -1
  143. package/dist/components/dialog/trigger.js +1 -1
  144. package/dist/components/dialog/trigger.js.map +1 -1
  145. package/dist/components/divider/index.js +1 -1
  146. package/dist/components/divider/index.js.map +1 -1
  147. package/dist/components/divider/styles.module.css +44 -0
  148. package/dist/components/drawer/back.js +1 -1
  149. package/dist/components/drawer/back.js.map +1 -1
  150. package/dist/components/drawer/close.js +1 -1
  151. package/dist/components/drawer/close.js.map +1 -1
  152. package/dist/components/drawer/content.js +1 -3
  153. package/dist/components/drawer/content.js.map +1 -1
  154. package/dist/components/drawer/context.d.ts +0 -4
  155. package/dist/components/drawer/footer.js +1 -3
  156. package/dist/components/drawer/footer.js.map +1 -1
  157. package/dist/components/drawer/header-title.d.ts +0 -4
  158. package/dist/components/drawer/header-title.js +1 -3
  159. package/dist/components/drawer/header-title.js.map +1 -1
  160. package/dist/components/drawer/header.js +1 -1
  161. package/dist/components/drawer/header.js.map +1 -1
  162. package/dist/components/drawer/index.d.ts +0 -4
  163. package/dist/components/drawer/index.js +1 -1
  164. package/dist/components/drawer/index.js.map +1 -1
  165. package/dist/components/drawer/layout-main.js +1 -3
  166. package/dist/components/drawer/layout-main.js.map +1 -1
  167. package/dist/components/drawer/layout.d.ts +0 -4
  168. package/dist/components/drawer/layout.js +1 -3
  169. package/dist/components/drawer/layout.js.map +1 -1
  170. package/dist/components/drawer/menu-item.d.ts +0 -4
  171. package/dist/components/drawer/menu-item.js +1 -1
  172. package/dist/components/drawer/menu-item.js.map +1 -1
  173. package/dist/components/drawer/menu.d.ts +0 -4
  174. package/dist/components/drawer/menu.js +1 -3
  175. package/dist/components/drawer/menu.js.map +1 -1
  176. package/dist/components/drawer/panel.js +1 -3
  177. package/dist/components/drawer/panel.js.map +1 -1
  178. package/dist/components/drawer/styles.module.css +304 -0
  179. package/dist/components/drawer/trigger.d.ts +0 -4
  180. package/dist/components/drawer/trigger.js +1 -1
  181. package/dist/components/drawer/trigger.js.map +1 -1
  182. package/dist/components/drawer/types.d.ts +3 -5
  183. package/dist/components/drawer/view.js +1 -1
  184. package/dist/components/drawer/view.js.map +1 -1
  185. package/dist/components/hero/index.js +1 -1
  186. package/dist/components/hero/index.js.map +1 -1
  187. package/dist/components/hero/styles.module.css +51 -0
  188. package/dist/components/hotkey/context.d.ts +0 -2
  189. package/dist/components/hotkey/index.d.ts +0 -2
  190. package/dist/components/hotkey/index.js +1 -1
  191. package/dist/components/hotkey/index.js.map +1 -1
  192. package/dist/components/hotkey/set.d.ts +6 -0
  193. package/dist/components/hotkey/set.js +4 -0
  194. package/dist/components/hotkey/set.js.map +1 -0
  195. package/dist/components/hotkey/styles.module.css +36 -0
  196. package/dist/components/hotkey/types.d.ts +5 -6
  197. package/dist/components/icon/index.js +1 -1
  198. package/dist/components/icon/index.js.map +1 -1
  199. package/dist/components/icon/styles.module.css +38 -0
  200. package/dist/components/input/context.d.ts +0 -4
  201. package/dist/components/input/index.d.ts +0 -4
  202. package/dist/components/input/index.js +1 -1
  203. package/dist/components/input/index.js.map +1 -1
  204. package/dist/components/input/styles.module.css +175 -0
  205. package/dist/components/input/types.d.ts +7 -6
  206. package/dist/components/kanban/card-body.d.ts +12 -0
  207. package/dist/components/kanban/card-body.js +4 -0
  208. package/dist/components/kanban/card-body.js.map +1 -0
  209. package/dist/components/kanban/card-header-actions.d.ts +12 -0
  210. package/dist/components/kanban/card-header-actions.js +4 -0
  211. package/dist/components/kanban/card-header-actions.js.map +1 -0
  212. package/dist/components/kanban/card-header-title.d.ts +12 -0
  213. package/dist/components/kanban/card-header-title.js +4 -0
  214. package/dist/components/kanban/card-header-title.js.map +1 -0
  215. package/dist/components/kanban/card-header.d.ts +12 -0
  216. package/dist/components/kanban/card-header.js +4 -0
  217. package/dist/components/kanban/card-header.js.map +1 -0
  218. package/dist/components/kanban/card.d.ts +12 -0
  219. package/dist/components/kanban/card.js +4 -0
  220. package/dist/components/kanban/card.js.map +1 -0
  221. package/dist/components/kanban/column-actions.d.ts +12 -0
  222. package/dist/components/kanban/column-actions.js +4 -0
  223. package/dist/components/kanban/column-actions.js.map +1 -0
  224. package/dist/components/kanban/column-container.d.ts +12 -0
  225. package/dist/components/kanban/column-container.js +4 -0
  226. package/dist/components/kanban/column-container.js.map +1 -0
  227. package/dist/components/kanban/column-content.d.ts +12 -0
  228. package/dist/components/kanban/column-content.js +4 -0
  229. package/dist/components/kanban/column-content.js.map +1 -0
  230. package/dist/components/kanban/column-header-actions.d.ts +12 -0
  231. package/dist/components/kanban/column-header-actions.js +4 -0
  232. package/dist/components/kanban/column-header-actions.js.map +1 -0
  233. package/dist/components/kanban/column-header-drag-handle.d.ts +5 -0
  234. package/dist/components/kanban/column-header-drag-handle.js +4 -0
  235. package/dist/components/kanban/column-header-drag-handle.js.map +1 -0
  236. package/dist/components/kanban/column-header-title.d.ts +12 -0
  237. package/dist/components/kanban/column-header-title.js +4 -0
  238. package/dist/components/kanban/column-header-title.js.map +1 -0
  239. package/dist/components/kanban/column-header.d.ts +12 -0
  240. package/dist/components/kanban/column-header.js +4 -0
  241. package/dist/components/kanban/column-header.js.map +1 -0
  242. package/dist/components/kanban/column.d.ts +12 -0
  243. package/dist/components/kanban/column.js +4 -0
  244. package/dist/components/kanban/column.js.map +1 -0
  245. package/dist/components/kanban/context.d.ts +101 -0
  246. package/dist/components/kanban/context.js +2 -0
  247. package/dist/components/kanban/context.js.map +1 -0
  248. package/dist/components/kanban/header-actions.d.ts +12 -0
  249. package/dist/components/kanban/header-actions.js +4 -0
  250. package/dist/components/kanban/header-actions.js.map +1 -0
  251. package/dist/components/kanban/header-search.d.ts +12 -0
  252. package/dist/components/kanban/header-search.js +4 -0
  253. package/dist/components/kanban/header-search.js.map +1 -0
  254. package/dist/components/kanban/header-title.d.ts +12 -0
  255. package/dist/components/kanban/header-title.js +4 -0
  256. package/dist/components/kanban/header-title.js.map +1 -0
  257. package/dist/components/kanban/header.d.ts +12 -0
  258. package/dist/components/kanban/header.js +4 -0
  259. package/dist/components/kanban/header.js.map +1 -0
  260. package/dist/components/kanban/index.d.ts +9 -0
  261. package/dist/components/kanban/index.js +2 -0
  262. package/dist/components/kanban/index.js.map +1 -0
  263. package/dist/components/kanban/kanban.d.ts +18 -0
  264. package/dist/components/kanban/kanban.js +4 -0
  265. package/dist/components/kanban/kanban.js.map +1 -0
  266. package/dist/components/kanban/mock-data.d.ts +14 -0
  267. package/dist/components/kanban/mock-data.js +2 -0
  268. package/dist/components/kanban/mock-data.js.map +1 -0
  269. package/dist/components/kanban/styles.module.css +117 -0
  270. package/dist/components/kanban/types.d.ts +50 -0
  271. package/dist/components/label/index.js +1 -1
  272. package/dist/components/label/index.js.map +1 -1
  273. package/dist/components/label/styles.module.css +23 -0
  274. package/dist/components/lines/index.d.ts +0 -2
  275. package/dist/components/lines/index.js +1 -1
  276. package/dist/components/lines/index.js.map +1 -1
  277. package/dist/components/lines/styles.module.css +95 -0
  278. package/dist/components/lines/types.d.ts +4 -5
  279. package/dist/components/link/index.js +1 -1
  280. package/dist/components/link/index.js.map +1 -1
  281. package/dist/components/link/styles.module.css +37 -0
  282. package/dist/components/menu/context.d.ts +0 -2
  283. package/dist/components/menu/index.d.ts +0 -2
  284. package/dist/components/menu/index.js +1 -1
  285. package/dist/components/menu/index.js.map +1 -1
  286. package/dist/components/menu/item-description.js +1 -1
  287. package/dist/components/menu/item-description.js.map +1 -1
  288. package/dist/components/menu/item-label.js +1 -1
  289. package/dist/components/menu/item-label.js.map +1 -1
  290. package/dist/components/menu/item.d.ts +0 -2
  291. package/dist/components/menu/item.js +1 -1
  292. package/dist/components/menu/item.js.map +1 -1
  293. package/dist/components/menu/section.d.ts +0 -2
  294. package/dist/components/menu/section.js +1 -1
  295. package/dist/components/menu/section.js.map +1 -1
  296. package/dist/components/menu/separator.js +1 -1
  297. package/dist/components/menu/separator.js.map +1 -1
  298. package/dist/components/menu/styles.module.css +415 -0
  299. package/dist/components/menu/trigger.d.ts +5 -1
  300. package/dist/components/menu/trigger.js +1 -1
  301. package/dist/components/menu/trigger.js.map +1 -1
  302. package/dist/components/menu/types.d.ts +2 -3
  303. package/dist/components/notice/index.d.ts +0 -3
  304. package/dist/components/notice/index.js +1 -1
  305. package/dist/components/notice/index.js.map +1 -1
  306. package/dist/components/notice/list.d.ts +0 -3
  307. package/dist/components/notice/list.js +1 -1
  308. package/dist/components/notice/list.js.map +1 -1
  309. package/dist/components/notice/notice-icon.d.ts +0 -3
  310. package/dist/components/notice/styles.module.css +133 -0
  311. package/dist/components/notice/types.d.ts +3 -6
  312. package/dist/components/options/index.js +1 -1
  313. package/dist/components/options/index.js.map +1 -1
  314. package/dist/components/options/item-content.d.ts +2 -5
  315. package/dist/components/options/item-content.js +1 -3
  316. package/dist/components/options/item-content.js.map +1 -1
  317. package/dist/components/options/item-description.d.ts +2 -5
  318. package/dist/components/options/item-description.js +1 -3
  319. package/dist/components/options/item-description.js.map +1 -1
  320. package/dist/components/options/item-label.d.ts +2 -5
  321. package/dist/components/options/item-label.js +1 -3
  322. package/dist/components/options/item-label.js.map +1 -1
  323. package/dist/components/options/item.js +1 -1
  324. package/dist/components/options/item.js.map +1 -1
  325. package/dist/components/options/section.js +1 -3
  326. package/dist/components/options/section.js.map +1 -1
  327. package/dist/components/options/styles.module.css +397 -0
  328. package/dist/components/options/types.d.ts +2 -3
  329. package/dist/components/pagination/context.d.ts +9 -0
  330. package/dist/components/pagination/context.js +4 -0
  331. package/dist/components/pagination/context.js.map +1 -0
  332. package/dist/components/pagination/index.d.ts +25 -0
  333. package/dist/components/pagination/index.js +4 -0
  334. package/dist/components/pagination/index.js.map +1 -0
  335. package/dist/components/pagination/next.d.ts +10 -0
  336. package/dist/components/pagination/next.js +4 -0
  337. package/dist/components/pagination/next.js.map +1 -0
  338. package/dist/components/pagination/pages.d.ts +10 -0
  339. package/dist/components/pagination/pages.js +4 -0
  340. package/dist/components/pagination/pages.js.map +1 -0
  341. package/dist/components/pagination/prev.d.ts +10 -0
  342. package/dist/components/pagination/prev.js +4 -0
  343. package/dist/components/pagination/prev.js.map +1 -0
  344. package/dist/components/pagination/styles.module.css +25 -0
  345. package/dist/components/pagination/types.d.ts +35 -0
  346. package/dist/components/pagination/types.js +2 -0
  347. package/dist/components/pagination/types.js.map +1 -0
  348. package/dist/components/pagination/utils.d.ts +16 -0
  349. package/dist/components/pagination/utils.js +2 -0
  350. package/dist/components/pagination/utils.js.map +1 -0
  351. package/dist/components/popover/content.d.ts +2 -4
  352. package/dist/components/popover/content.js +1 -1
  353. package/dist/components/popover/content.js.map +1 -1
  354. package/dist/components/popover/footer.d.ts +2 -5
  355. package/dist/components/popover/footer.js +1 -1
  356. package/dist/components/popover/footer.js.map +1 -1
  357. package/dist/components/popover/index.d.ts +15 -19
  358. package/dist/components/popover/index.js +1 -1
  359. package/dist/components/popover/index.js.map +1 -1
  360. package/dist/components/popover/styles.module.css +32 -0
  361. package/dist/components/popover/title.d.ts +2 -4
  362. package/dist/components/popover/title.js +1 -1
  363. package/dist/components/popover/title.js.map +1 -1
  364. package/dist/components/popover/trigger.d.ts +1 -1
  365. package/dist/components/popover/trigger.js +1 -1
  366. package/dist/components/popover/trigger.js.map +1 -1
  367. package/dist/components/popover/types.d.ts +11 -22
  368. package/dist/components/query-builder/index.js +1 -1
  369. package/dist/components/query-builder/index.js.map +1 -1
  370. package/dist/components/query-builder/rule-group.js +1 -1
  371. package/dist/components/query-builder/rule-group.js.map +1 -1
  372. package/dist/components/query-builder/rule.js +1 -1
  373. package/dist/components/query-builder/rule.js.map +1 -1
  374. package/dist/components/query-builder/styles.module.css +87 -0
  375. package/dist/components/query-builder/value-editor.js +1 -1
  376. package/dist/components/query-builder/value-editor.js.map +1 -1
  377. package/dist/components/radio/group.js +1 -1
  378. package/dist/components/radio/group.js.map +1 -1
  379. package/dist/components/radio/index.js +1 -1
  380. package/dist/components/radio/index.js.map +1 -1
  381. package/dist/components/radio/styles.module.css +118 -0
  382. package/dist/components/search-field/context.d.ts +0 -4
  383. package/dist/components/search-field/index.d.ts +0 -4
  384. package/dist/components/search-field/index.js +1 -1
  385. package/dist/components/search-field/index.js.map +1 -1
  386. package/dist/components/search-field/styles.module.css +104 -0
  387. package/dist/components/search-field/types.d.ts +2 -7
  388. package/dist/components/select-field/context.d.ts +0 -3
  389. package/dist/components/select-field/index.d.ts +0 -3
  390. package/dist/components/select-field/index.js +1 -1
  391. package/dist/components/select-field/index.js.map +1 -1
  392. package/dist/components/select-field/styles.module.css +78 -0
  393. package/dist/components/select-field/types.d.ts +0 -3
  394. package/dist/components/sidenav/avatar.js +1 -1
  395. package/dist/components/sidenav/avatar.js.map +1 -1
  396. package/dist/components/sidenav/content.js +1 -1
  397. package/dist/components/sidenav/content.js.map +1 -1
  398. package/dist/components/sidenav/footer.js +1 -3
  399. package/dist/components/sidenav/footer.js.map +1 -1
  400. package/dist/components/sidenav/header.js +1 -1
  401. package/dist/components/sidenav/header.js.map +1 -1
  402. package/dist/components/sidenav/index.js +1 -1
  403. package/dist/components/sidenav/index.js.map +1 -1
  404. package/dist/components/sidenav/item.js +1 -1
  405. package/dist/components/sidenav/item.js.map +1 -1
  406. package/dist/components/sidenav/link.js +1 -1
  407. package/dist/components/sidenav/link.js.map +1 -1
  408. package/dist/components/sidenav/menu-item.js +1 -3
  409. package/dist/components/sidenav/menu-item.js.map +1 -1
  410. package/dist/components/sidenav/menu.js +1 -1
  411. package/dist/components/sidenav/menu.js.map +1 -1
  412. package/dist/components/sidenav/styles.module.css +311 -0
  413. package/dist/components/sidenav/types.d.ts +1 -2
  414. package/dist/components/skeleton/index.d.ts +2 -4
  415. package/dist/components/skeleton/index.js +1 -1
  416. package/dist/components/skeleton/index.js.map +1 -1
  417. package/dist/components/skeleton/styles.module.css +33 -0
  418. package/dist/components/skeleton/types.d.ts +4 -5
  419. package/dist/components/slider/index.js +1 -1
  420. package/dist/components/slider/index.js.map +1 -1
  421. package/dist/components/slider/styles.module.css +220 -0
  422. package/dist/components/switch/index.js +1 -1
  423. package/dist/components/switch/index.js.map +1 -1
  424. package/dist/components/switch/styles.module.css +116 -0
  425. package/dist/components/table/body.d.ts +0 -3
  426. package/dist/components/table/body.js +1 -1
  427. package/dist/components/table/body.js.map +1 -1
  428. package/dist/components/table/cell.d.ts +0 -3
  429. package/dist/components/table/cell.js +1 -1
  430. package/dist/components/table/cell.js.map +1 -1
  431. package/dist/components/table/context.d.ts +0 -3
  432. package/dist/components/table/header-cell.d.ts +0 -3
  433. package/dist/components/table/header-cell.js +1 -1
  434. package/dist/components/table/header-cell.js.map +1 -1
  435. package/dist/components/table/header.d.ts +0 -3
  436. package/dist/components/table/header.js +1 -1
  437. package/dist/components/table/header.js.map +1 -1
  438. package/dist/components/table/index.d.ts +0 -3
  439. package/dist/components/table/index.js +1 -1
  440. package/dist/components/table/index.js.map +1 -1
  441. package/dist/components/table/row.d.ts +0 -3
  442. package/dist/components/table/row.js +1 -1
  443. package/dist/components/table/row.js.map +1 -1
  444. package/dist/components/table/styles.module.css +95 -0
  445. package/dist/components/table/types.d.ts +5 -15
  446. package/dist/components/tabs/index.js +1 -1
  447. package/dist/components/tabs/index.js.map +1 -1
  448. package/dist/components/tabs/list.js +1 -1
  449. package/dist/components/tabs/list.js.map +1 -1
  450. package/dist/components/tabs/panel.js +1 -1
  451. package/dist/components/tabs/panel.js.map +1 -1
  452. package/dist/components/tabs/styles.module.css +140 -0
  453. package/dist/components/tabs/tab.js +1 -1
  454. package/dist/components/tabs/tab.js.map +1 -1
  455. package/dist/components/text-area-field/index.js +1 -1
  456. package/dist/components/text-area-field/index.js.map +1 -1
  457. package/dist/components/text-area-field/styles.module.css +67 -0
  458. package/dist/components/text-field/context.d.ts +0 -4
  459. package/dist/components/text-field/index.d.ts +24 -4
  460. package/dist/components/text-field/index.js +1 -1
  461. package/dist/components/text-field/index.js.map +1 -1
  462. package/dist/components/text-field/styles.module.css +37 -0
  463. package/dist/components/text-field/types.d.ts +0 -4
  464. package/dist/components/time-field/index.d.ts +0 -3
  465. package/dist/components/time-field/index.js +1 -1
  466. package/dist/components/time-field/index.js.map +1 -1
  467. package/dist/components/time-field/styles.module.css +75 -0
  468. package/dist/components/time-field/types.d.ts +2 -5
  469. package/dist/components/tooltip/index.js +1 -1
  470. package/dist/components/tooltip/index.js.map +1 -1
  471. package/dist/components/tooltip/styles.module.css +20 -0
  472. package/dist/components/tree/context.d.ts +0 -2
  473. package/dist/components/tree/context.js +1 -1
  474. package/dist/components/tree/context.js.map +1 -1
  475. package/dist/components/tree/index.d.ts +0 -2
  476. package/dist/components/tree/index.js +1 -1
  477. package/dist/components/tree/index.js.map +1 -1
  478. package/dist/components/tree/item-actions.js +1 -1
  479. package/dist/components/tree/item-actions.js.map +1 -1
  480. package/dist/components/tree/item-content.d.ts +0 -2
  481. package/dist/components/tree/item-content.js +1 -1
  482. package/dist/components/tree/item-content.js.map +1 -1
  483. package/dist/components/tree/item-description.js +1 -1
  484. package/dist/components/tree/item-description.js.map +1 -1
  485. package/dist/components/tree/item-label.js +1 -1
  486. package/dist/components/tree/item-label.js.map +1 -1
  487. package/dist/components/tree/item-prefix-icon.js +1 -1
  488. package/dist/components/tree/item-prefix-icon.js.map +1 -1
  489. package/dist/components/tree/item.d.ts +0 -2
  490. package/dist/components/tree/item.js +1 -1
  491. package/dist/components/tree/item.js.map +1 -1
  492. package/dist/components/tree/lines.js +1 -1
  493. package/dist/components/tree/lines.js.map +1 -1
  494. package/dist/components/tree/styles.module.css +183 -0
  495. package/dist/components/tree/types.d.ts +6 -5
  496. package/dist/hooks/coordinate-field/index.d.ts +9 -0
  497. package/dist/hooks/coordinate-field/index.js +2 -0
  498. package/dist/hooks/coordinate-field/index.js.map +1 -0
  499. package/dist/hooks/coordinate-field/use-coordinate-copy.d.ts +19 -0
  500. package/dist/hooks/coordinate-field/use-coordinate-copy.js +2 -0
  501. package/dist/hooks/coordinate-field/use-coordinate-copy.js.map +1 -0
  502. package/dist/hooks/coordinate-field/use-coordinate-field-state.d.ts +28 -0
  503. package/dist/hooks/coordinate-field/use-coordinate-field-state.js +2 -0
  504. package/dist/hooks/coordinate-field/use-coordinate-field-state.js.map +1 -0
  505. package/dist/hooks/coordinate-field/use-coordinate-field.d.ts +49 -0
  506. package/dist/hooks/coordinate-field/use-coordinate-field.js +2 -0
  507. package/dist/hooks/coordinate-field/use-coordinate-field.js.map +1 -0
  508. package/dist/hooks/coordinate-field/use-coordinate-focus.d.ts +21 -0
  509. package/dist/hooks/coordinate-field/use-coordinate-focus.js +2 -0
  510. package/dist/hooks/coordinate-field/use-coordinate-focus.js.map +1 -0
  511. package/dist/hooks/coordinate-field/use-coordinate-paste.d.ts +21 -0
  512. package/dist/hooks/coordinate-field/use-coordinate-paste.js +2 -0
  513. package/dist/hooks/coordinate-field/use-coordinate-paste.js.map +1 -0
  514. package/dist/hooks/coordinate-field/use-timeout-cleanup.d.ts +6 -0
  515. package/dist/hooks/coordinate-field/use-timeout-cleanup.js +2 -0
  516. package/dist/hooks/coordinate-field/use-timeout-cleanup.js.map +1 -0
  517. package/dist/hooks/kanban/index.d.ts +93 -0
  518. package/dist/hooks/kanban/index.js +2 -0
  519. package/dist/hooks/kanban/index.js.map +1 -0
  520. package/dist/index.d.ts +58 -61
  521. package/dist/index.js +1 -1
  522. package/dist/index.module.css +19 -0
  523. package/dist/lib/utils.d.ts +1 -17
  524. package/dist/lib/utils.js +1 -1
  525. package/dist/lib/utils.js.map +1 -1
  526. package/dist/metafile-esm.json +1 -1
  527. package/dist/providers/theme-provider.d.ts +1 -1
  528. package/dist/providers/theme-provider.js +1 -1
  529. package/dist/providers/theme-provider.js.map +1 -1
  530. package/package.json +36 -49
  531. package/dist/components/accordion/styles.d.ts +0 -56
  532. package/dist/components/accordion/styles.js +0 -2
  533. package/dist/components/accordion/styles.js.map +0 -1
  534. package/dist/components/action-bar/styles.d.ts +0 -5
  535. package/dist/components/action-bar/styles.js +0 -2
  536. package/dist/components/action-bar/styles.js.map +0 -1
  537. package/dist/components/avatar/styles.d.ts +0 -48
  538. package/dist/components/avatar/styles.js +0 -2
  539. package/dist/components/avatar/styles.js.map +0 -1
  540. package/dist/components/badge/styles.d.ts +0 -32
  541. package/dist/components/badge/styles.js +0 -2
  542. package/dist/components/badge/styles.js.map +0 -1
  543. package/dist/components/breadcrumbs/styles.d.ts +0 -48
  544. package/dist/components/breadcrumbs/styles.js +0 -2
  545. package/dist/components/breadcrumbs/styles.js.map +0 -1
  546. package/dist/components/button/styles.d.ts +0 -129
  547. package/dist/components/button/styles.js +0 -2
  548. package/dist/components/button/styles.js.map +0 -1
  549. package/dist/components/checkbox/styles.d.ts +0 -54
  550. package/dist/components/checkbox/styles.js +0 -2
  551. package/dist/components/checkbox/styles.js.map +0 -1
  552. package/dist/components/chip/styles.d.ts +0 -247
  553. package/dist/components/chip/styles.js +0 -2
  554. package/dist/components/chip/styles.js.map +0 -1
  555. package/dist/components/classification-badge/styles.d.ts +0 -38
  556. package/dist/components/classification-badge/styles.js +0 -2
  557. package/dist/components/classification-badge/styles.js.map +0 -1
  558. package/dist/components/classification-banner/styles.d.ts +0 -38
  559. package/dist/components/classification-banner/styles.js +0 -2
  560. package/dist/components/classification-banner/styles.js.map +0 -1
  561. package/dist/components/color-picker/styles.d.ts +0 -42
  562. package/dist/components/color-picker/styles.js +0 -2
  563. package/dist/components/color-picker/styles.js.map +0 -1
  564. package/dist/components/combobox-field/styles.d.ts +0 -72
  565. package/dist/components/combobox-field/styles.js +0 -2
  566. package/dist/components/combobox-field/styles.js.map +0 -1
  567. package/dist/components/date-field/styles.d.ts +0 -59
  568. package/dist/components/date-field/styles.js +0 -2
  569. package/dist/components/date-field/styles.js.map +0 -1
  570. package/dist/components/details-list/styles.d.ts +0 -65
  571. package/dist/components/details-list/styles.js +0 -2
  572. package/dist/components/details-list/styles.js.map +0 -1
  573. package/dist/components/dialog/styles.d.ts +0 -60
  574. package/dist/components/dialog/styles.js +0 -2
  575. package/dist/components/dialog/styles.js.map +0 -1
  576. package/dist/components/divider/styles.d.ts +0 -5
  577. package/dist/components/divider/styles.js +0 -2
  578. package/dist/components/divider/styles.js.map +0 -1
  579. package/dist/components/drawer/styles.d.ts +0 -152
  580. package/dist/components/drawer/styles.js +0 -2
  581. package/dist/components/drawer/styles.js.map +0 -1
  582. package/dist/components/hero/styles.d.ts +0 -48
  583. package/dist/components/hero/styles.js +0 -2
  584. package/dist/components/hero/styles.js.map +0 -1
  585. package/dist/components/hotkey/hotkey-set.d.ts +0 -9
  586. package/dist/components/hotkey/hotkey-set.js +0 -4
  587. package/dist/components/hotkey/hotkey-set.js.map +0 -1
  588. package/dist/components/hotkey/styles.d.ts +0 -53
  589. package/dist/components/hotkey/styles.js +0 -2
  590. package/dist/components/hotkey/styles.js.map +0 -1
  591. package/dist/components/icon/styles.d.ts +0 -5
  592. package/dist/components/icon/styles.js +0 -2
  593. package/dist/components/icon/styles.js.map +0 -1
  594. package/dist/components/input/styles.d.ts +0 -142
  595. package/dist/components/input/styles.js +0 -2
  596. package/dist/components/input/styles.js.map +0 -1
  597. package/dist/components/label/styles.d.ts +0 -5
  598. package/dist/components/label/styles.js +0 -2
  599. package/dist/components/label/styles.js.map +0 -1
  600. package/dist/components/lines/styles.d.ts +0 -32
  601. package/dist/components/lines/styles.js +0 -2
  602. package/dist/components/lines/styles.js.map +0 -1
  603. package/dist/components/link/styles.d.ts +0 -5
  604. package/dist/components/link/styles.js +0 -2
  605. package/dist/components/link/styles.js.map +0 -1
  606. package/dist/components/menu/styles.d.ts +0 -71
  607. package/dist/components/menu/styles.js +0 -2
  608. package/dist/components/menu/styles.js.map +0 -1
  609. package/dist/components/notice/styles.d.ts +0 -60
  610. package/dist/components/notice/styles.js +0 -2
  611. package/dist/components/notice/styles.js.map +0 -1
  612. package/dist/components/options/styles.d.ts +0 -72
  613. package/dist/components/options/styles.js +0 -2
  614. package/dist/components/options/styles.js.map +0 -1
  615. package/dist/components/popover/body.d.ts +0 -8
  616. package/dist/components/popover/body.js +0 -4
  617. package/dist/components/popover/body.js.map +0 -1
  618. package/dist/components/popover/styles.d.ts +0 -48
  619. package/dist/components/popover/styles.js +0 -2
  620. package/dist/components/popover/styles.js.map +0 -1
  621. package/dist/components/query-builder/styles.d.ts +0 -152
  622. package/dist/components/query-builder/styles.js +0 -2
  623. package/dist/components/query-builder/styles.js.map +0 -1
  624. package/dist/components/radio/styles.d.ts +0 -54
  625. package/dist/components/radio/styles.js +0 -2
  626. package/dist/components/radio/styles.js.map +0 -1
  627. package/dist/components/search-field/styles.d.ts +0 -53
  628. package/dist/components/search-field/styles.js +0 -2
  629. package/dist/components/search-field/styles.js.map +0 -1
  630. package/dist/components/select-field/styles.d.ts +0 -66
  631. package/dist/components/select-field/styles.js +0 -2
  632. package/dist/components/select-field/styles.js.map +0 -1
  633. package/dist/components/sidenav/styles.d.ts +0 -156
  634. package/dist/components/sidenav/styles.js +0 -2
  635. package/dist/components/sidenav/styles.js.map +0 -1
  636. package/dist/components/skeleton/styles.d.ts +0 -23
  637. package/dist/components/skeleton/styles.js +0 -2
  638. package/dist/components/skeleton/styles.js.map +0 -1
  639. package/dist/components/slider/styles.d.ts +0 -84
  640. package/dist/components/slider/styles.js +0 -2
  641. package/dist/components/slider/styles.js.map +0 -1
  642. package/dist/components/switch/styles.d.ts +0 -44
  643. package/dist/components/switch/styles.js +0 -2
  644. package/dist/components/switch/styles.js.map +0 -1
  645. package/dist/components/table/styles.d.ts +0 -134
  646. package/dist/components/table/styles.js +0 -2
  647. package/dist/components/table/styles.js.map +0 -1
  648. package/dist/components/tabs/styles.d.ts +0 -48
  649. package/dist/components/tabs/styles.js +0 -2
  650. package/dist/components/tabs/styles.js.map +0 -1
  651. package/dist/components/text-area-field/styles.d.ts +0 -54
  652. package/dist/components/text-area-field/styles.js +0 -2
  653. package/dist/components/text-area-field/styles.js.map +0 -1
  654. package/dist/components/text-field/styles.d.ts +0 -54
  655. package/dist/components/text-field/styles.js +0 -2
  656. package/dist/components/text-field/styles.js.map +0 -1
  657. package/dist/components/time-field/styles.d.ts +0 -69
  658. package/dist/components/time-field/styles.js +0 -2
  659. package/dist/components/time-field/styles.js.map +0 -1
  660. package/dist/components/tooltip/styles.d.ts +0 -5
  661. package/dist/components/tooltip/styles.js +0 -2
  662. package/dist/components/tooltip/styles.js.map +0 -1
  663. package/dist/components/tree/styles.d.ts +0 -128
  664. package/dist/components/tree/styles.js +0 -2
  665. package/dist/components/tree/styles.js.map +0 -1
  666. package/dist/index.css +0 -196
  667. package/dist/styles.css +0 -9484
  668. package/dist/tokens/themes.css +0 -882
  669. package/dist/tokens/themes.d.ts +0 -1
  670. package/dist/tokens/tokens.css +0 -202
  671. package/dist/tokens/tokens.d.ts +0 -468
  672. package/dist/tokens/tokens.js +0 -2
  673. package/dist/tokens/tokens.js.map +0 -1
  674. package/dist/tokens/types.d.ts +0 -308
  675. package/dist/variants/variants.css +0 -86
  676. package/dist/variants/variants.d.ts +0 -2
  677. /package/dist/{tokens → components/kanban}/types.js +0 -0
  678. /package/dist/{tokens → components/kanban}/types.js.map +0 -0
@@ -0,0 +1,101 @@
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ @reference '../../index.module.css';
14
+
15
+ @layer components.l1 {
16
+ .field {
17
+ @apply gap-xs flex flex-col;
18
+ }
19
+
20
+ .control {
21
+ @apply rounded-medium px-s py-xs fg-primary-bold outline-interactive flex items-center outline;
22
+
23
+ @variant placeholder {
24
+ @apply fg-primary-muted;
25
+ }
26
+
27
+ @variant hover {
28
+ @apply outline-interactive-hover;
29
+ }
30
+
31
+ @variant focus-visible {
32
+ @apply outline-interactive-hover;
33
+ }
34
+
35
+ @variant focus-within {
36
+ @apply outline-accent-primary-bold;
37
+ }
38
+
39
+ @variant pressed {
40
+ @apply outline-interactive-pressed;
41
+ }
42
+
43
+ @variant group-size-medium/combobox-field {
44
+ @apply max-w-[400px] min-w-[160px];
45
+ }
46
+
47
+ @variant group-size-small/combobox-field {
48
+ @apply max-w-[200px] min-w-[80px];
49
+ }
50
+
51
+ @variant group-invalid/combobox-field {
52
+ @apply outline-serious-bold;
53
+ }
54
+
55
+ @variant group-disabled/combobox-field {
56
+ @apply fg-disabled outline-interactive-disabled;
57
+ }
58
+ }
59
+
60
+ .input {
61
+ @apply font-display grow outline-none;
62
+
63
+ @variant group-size-medium/combobox-field {
64
+ @apply text-body-s;
65
+ }
66
+
67
+ @variant group-size-small/combobox-field {
68
+ @apply text-body-xs;
69
+ }
70
+ }
71
+
72
+ .trigger {
73
+ @apply fg-primary-bold;
74
+
75
+ @variant group-open/combobox-field {
76
+ @apply rotate-180 transform;
77
+ }
78
+
79
+ @variant group-disabled/combobox-field {
80
+ @apply fg-disabled;
81
+ }
82
+ }
83
+
84
+ .description {
85
+ @apply fg-primary-muted text-body-xs;
86
+
87
+ @variant group-disabled/combobox-field {
88
+ @apply fg-disabled;
89
+ }
90
+ }
91
+
92
+ .error {
93
+ @apply fg-serious-bold text-body-xs;
94
+ }
95
+
96
+ .popover {
97
+ --trigger-width: initial; /* is inlined by react aria components on render */
98
+ @apply -ml-s;
99
+ min-width: calc(var(--trigger-width) + (var(--spacing-s) * 2));
100
+ }
101
+ }
@@ -2,10 +2,7 @@ import { RefAttributes } from 'react';
2
2
  import { ComboBoxProps, VirtualizerProps, ListLayoutOptions, LabelProps, InputProps, FieldErrorProps, PopoverProps } from 'react-aria-components';
3
3
  import { ButtonProps } from '../button/types.js';
4
4
  import { OptionsDataItem, OptionsProps } from '../options/types.js';
5
- import 'tailwind-variants';
6
5
  import '../../lib/types.js';
7
- import '../button/styles.js';
8
- import 'tailwind-merge';
9
6
  import '../icon/types.js';
10
7
 
11
8
  type ComboBoxFieldProps<T extends OptionsDataItem> = Omit<ComboBoxProps<T>, 'children' | 'className'> & Pick<VirtualizerProps<ListLayoutOptions>, 'layoutOptions'> & Pick<OptionsProps<T>, 'children'> & RefAttributes<HTMLDivElement> & {
@@ -0,0 +1,77 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
3
+ import { ContextValue } from 'react-aria-components';
4
+ import { ProviderProps } from '../../lib/types.js';
5
+ import { CoordinateFieldProps, CoordinateFieldState } from './types.js';
6
+
7
+ /**
8
+ * CoordinateField Context Architecture
9
+ *
10
+ * This file defines two separate contexts following the React Aria component pattern:
11
+ *
12
+ * 1. CoordinateFieldContext (Props Context):
13
+ * - Contains user-provided props for the component
14
+ * - Used for React Aria's context-based prop merging
15
+ * - Part of the public composition API
16
+ *
17
+ * 2. CoordinateFieldStateContext (State Context):
18
+ * - Contains derived/computed runtime state
19
+ * - Used to share state with child components (e.g., CoordinateSegment)
20
+ * - Primarily for internal use
21
+
22
+ * Separation keeps the public API (props) distinct from internal
23
+ * implementation details (state), improving maintainability and composition.
24
+ */
25
+ /**
26
+ * Props Context for CoordinateField component.
27
+ *
28
+ * Contains user-provided props (label, format, size, value, onChange, etc.)
29
+ * and is used by React Aria's useContextProps hook for context-based prop merging.
30
+ * This enables parent components to provide default props to nested CoordinateField
31
+ * components, supporting composition patterns.
32
+ *
33
+ * Part of the public API - external consumers can use this for component composition.
34
+ *
35
+ * @see CoordinateFieldStateContext for internal runtime state
36
+ */
37
+ declare const CoordinateFieldContext: react.Context<ContextValue<CoordinateFieldProps, HTMLDivElement>>;
38
+ /**
39
+ * State Context for CoordinateField component.
40
+ *
41
+ * Contains derived/computed runtime state (segmentValues, currentValue,
42
+ * validationErrors, registerTimeout, etc.) that is shared with child components
43
+ * like CoordinateSegment. This avoids prop drilling for deeply nested children.
44
+ *
45
+ * This follows the React Aria pattern of separating props context (public API)
46
+ * from state context (internal implementation). While exported for composition
47
+ * scenarios and testing, this is primarily for internal use.
48
+ *
49
+ * @see CoordinateFieldContext for user-provided props
50
+ * @example
51
+ * // Used internally by child components
52
+ * const state = useCoordinateFieldStateContext();
53
+ * const { segmentValues, isDisabled, registerTimeout } = state;
54
+ */
55
+ declare const CoordinateFieldStateContext: react.Context<CoordinateFieldState | null>;
56
+ /**
57
+ * Provider component for CoordinateField context
58
+ * Wraps children with CoordinateFieldContext
59
+ */
60
+ declare function CoordinateFieldProvider({ children, ...props }: ProviderProps<CoordinateFieldProps>): react_jsx_runtime.JSX.Element;
61
+ /**
62
+ * Provider component for CoordinateField state context
63
+ * Wraps children with CoordinateFieldStateContext
64
+ */
65
+ declare function CoordinateFieldStateProvider({ children, value, }: {
66
+ children: React.ReactNode;
67
+ value: CoordinateFieldState;
68
+ }): react_jsx_runtime.JSX.Element;
69
+ /**
70
+ * Hook to access CoordinateField state context
71
+ * Must be used within a CoordinateField component
72
+ * @throws {Error} If used outside of CoordinateField
73
+ * @returns {CoordinateFieldState} The coordinate field state
74
+ */
75
+ declare const useCoordinateFieldStateContext: () => CoordinateFieldState;
76
+
77
+ export { CoordinateFieldContext, CoordinateFieldProvider, CoordinateFieldStateContext, CoordinateFieldStateProvider, useCoordinateFieldStateContext };
@@ -0,0 +1,2 @@
1
+ import {jsx}from'react/jsx-runtime';import {createContext,useContext}from'react';const d=createContext(null),r=createContext(null);function l({children:e,...t}){return jsx(d.Provider,{value:t,children:e})}function C({children:e,value:t}){return jsx(r.Provider,{value:t,children:e})}const p=()=>{const e=useContext(r);if(!e)throw new Error("useCoordinateFieldStateContext must be used within CoordinateField");return e};export{d as CoordinateFieldContext,l as CoordinateFieldProvider,r as CoordinateFieldStateContext,C as CoordinateFieldStateProvider,p as useCoordinateFieldStateContext};//# sourceMappingURL=context.js.map
2
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/coordinate-field/context.tsx"],"names":["CoordinateFieldContext","createContext","CoordinateFieldStateContext","CoordinateFieldProvider","children","props","jsx","CoordinateFieldStateProvider","value","useCoordinateFieldStateContext","context","useContext"],"mappings":"iFAkDO,MAAMA,EACXC,aAAAA,CAAkE,IAAI,CAAA,CAmB3DC,CAAAA,CACXD,cAA2C,IAAI,EAM1C,SAASE,CAAAA,CAAwB,CACtC,QAAA,CAAAC,CAAAA,CACA,GAAGC,CACL,EAAwC,CACtC,OACEC,GAAAA,CAACN,CAAAA,CAAuB,SAAvB,CAAgC,KAAA,CAAOK,CAAAA,CACrC,QAAA,CAAAD,EACH,CAEJ,CAMO,SAASG,CAAAA,CAA6B,CAC3C,QAAA,CAAAH,CAAAA,CACA,KAAA,CAAAI,CACF,EAGG,CACD,OACEF,GAAAA,CAACJ,CAAAA,CAA4B,SAA5B,CAAqC,KAAA,CAAOM,CAAAA,CAC1C,QAAA,CAAAJ,EACH,CAEJ,CAQO,MAAMK,CAAAA,CAAiC,IAAM,CAClD,MAAMC,CAAAA,CAAUC,UAAAA,CAAWT,CAA2B,CAAA,CACtD,GAAI,CAACQ,CAAAA,CACH,MAAM,IAAI,KAAA,CACR,oEACF,CAAA,CAEF,OAAOA,CACT","file":"context.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport { createContext, useContext } from 'react';\nimport type { ContextValue } from 'react-aria-components';\nimport type { ProviderProps } from '@/lib/types';\nimport type { CoordinateFieldProps, CoordinateFieldState } from './types';\n\n/**\n * CoordinateField Context Architecture\n *\n * This file defines two separate contexts following the React Aria component pattern:\n *\n * 1. CoordinateFieldContext (Props Context):\n * - Contains user-provided props for the component\n * - Used for React Aria's context-based prop merging\n * - Part of the public composition API\n *\n * 2. CoordinateFieldStateContext (State Context):\n * - Contains derived/computed runtime state\n * - Used to share state with child components (e.g., CoordinateSegment)\n * - Primarily for internal use\n\n * Separation keeps the public API (props) distinct from internal\n * implementation details (state), improving maintainability and composition.\n */\n\n/**\n * Props Context for CoordinateField component.\n *\n * Contains user-provided props (label, format, size, value, onChange, etc.)\n * and is used by React Aria's useContextProps hook for context-based prop merging.\n * This enables parent components to provide default props to nested CoordinateField\n * components, supporting composition patterns.\n *\n * Part of the public API - external consumers can use this for component composition.\n *\n * @see CoordinateFieldStateContext for internal runtime state\n */\nexport const CoordinateFieldContext =\n createContext<ContextValue<CoordinateFieldProps, HTMLDivElement>>(null);\n\n/**\n * State Context for CoordinateField component.\n *\n * Contains derived/computed runtime state (segmentValues, currentValue,\n * validationErrors, registerTimeout, etc.) that is shared with child components\n * like CoordinateSegment. This avoids prop drilling for deeply nested children.\n *\n * This follows the React Aria pattern of separating props context (public API)\n * from state context (internal implementation). While exported for composition\n * scenarios and testing, this is primarily for internal use.\n *\n * @see CoordinateFieldContext for user-provided props\n * @example\n * // Used internally by child components\n * const state = useCoordinateFieldStateContext();\n * const { segmentValues, isDisabled, registerTimeout } = state;\n */\nexport const CoordinateFieldStateContext =\n createContext<CoordinateFieldState | null>(null);\n\n/**\n * Provider component for CoordinateField context\n * Wraps children with CoordinateFieldContext\n */\nexport function CoordinateFieldProvider({\n children,\n ...props\n}: ProviderProps<CoordinateFieldProps>) {\n return (\n <CoordinateFieldContext.Provider value={props}>\n {children}\n </CoordinateFieldContext.Provider>\n );\n}\n\n/**\n * Provider component for CoordinateField state context\n * Wraps children with CoordinateFieldStateContext\n */\nexport function CoordinateFieldStateProvider({\n children,\n value,\n}: {\n children: React.ReactNode;\n value: CoordinateFieldState;\n}) {\n return (\n <CoordinateFieldStateContext.Provider value={value}>\n {children}\n </CoordinateFieldStateContext.Provider>\n );\n}\n\n/**\n * Hook to access CoordinateField state context\n * Must be used within a CoordinateField component\n * @throws {Error} If used outside of CoordinateField\n * @returns {CoordinateFieldState} The coordinate field state\n */\nexport const useCoordinateFieldStateContext = () => {\n const context = useContext(CoordinateFieldStateContext);\n if (!context) {\n throw new Error(\n 'useCoordinateFieldStateContext must be used within CoordinateField',\n );\n }\n return context;\n};\n"]}
@@ -0,0 +1,282 @@
1
+ import { CoordinateValue, CoordinateSystem, ParsedCoordinateMatch } from './types.js';
2
+ import 'react';
3
+ import 'react-aria-components';
4
+
5
+ /** Epsilon for coordinate equality comparison (≈11cm precision at equator) */
6
+ declare const COORDINATE_EPSILON = 0.000001;
7
+ /**
8
+ * Error message constants for coordinate format conversion
9
+ * @internal
10
+ */
11
+ declare const COORDINATE_ERROR_MESSAGES: {
12
+ readonly INVALID: "Invalid coordinate";
13
+ readonly CONVERSION_FAILED: "Conversion failed";
14
+ readonly NOT_AVAILABLE_AT_POLES: "Not available at poles";
15
+ };
16
+ /**
17
+ * Result of coordinate format conversion
18
+ */
19
+ interface CoordinateFormatResult {
20
+ /** The formatted coordinate string or error message */
21
+ value: string;
22
+ /** Whether the coordinate format is valid and can be used/copied */
23
+ isValid: boolean;
24
+ }
25
+ /**
26
+ * Format segment values into a coordinate string suitable for @accelint/geo parsing
27
+ *
28
+ * Converts an array of segment values into a string format that the geo package
29
+ * parsers can understand. Each format has different requirements:
30
+ *
31
+ * DD: [lat, lon] → "lat, lon"
32
+ * DDM: [latDeg, latMin, latDir, lonDeg, lonMin, lonDir] → "latDeg° latMin' latDir, lonDeg° lonMin' lonDir"
33
+ * DMS: [latDeg, latMin, latSec, latDir, lonDeg, lonMin, lonSec, lonDir] → "latDeg° latMin' latSec\" latDir, lonDeg° lonMin' lonSec\" lonDir"
34
+ * MGRS: [zone, band, grid, easting, northing] → "zone+band grid easting northing"
35
+ * UTM: [zone, hemisphere, easting, northing] → "zone+hemisphere easting northing"
36
+ *
37
+ * @param segments - Array of segment values from user input
38
+ * @param format - The coordinate system format
39
+ * @returns Formatted coordinate string, or null if segments are invalid
40
+ */
41
+ declare function formatSegmentsToCoordinateString(segments: string[], format: CoordinateSystem): string | null;
42
+ /**
43
+ * Parse a coordinate string into segment values
44
+ *
45
+ * Converts a formatted coordinate string (from @accelint/geo output or user input)
46
+ * back into individual segment values for display.
47
+ *
48
+ * This is the inverse of formatSegmentsToCoordinateString.
49
+ *
50
+ * **Note on Duplication**: This function and its helpers (parseDDCoordinateString,
51
+ * parseDDMCoordinateString, etc.) duplicate parsing logic that already exists in
52
+ * the @accelint/geo package parsers:
53
+ *
54
+ * - Geo parsers: parseDecimalDegrees, parseDegreesDecimalMinutes, etc.
55
+ * - These functions: parseDDCoordinateString, parseDDMCoordinateString, etc.
56
+ *
57
+ * Both use regex patterns to extract coordinate components from strings. The duplication
58
+ * exists because:
59
+ *
60
+ * 1. **Geo parsers** extract components, validate them, convert to DD, then format back to strings
61
+ * 2. **This function** extracts components from those formatted strings for the UI
62
+ *
63
+ * We're essentially undoing the formatting that geo just did. This is the second half
64
+ * of the circular conversion described in convertDDToDisplaySegments.
65
+ *
66
+ * **Why we can't use geo parsers directly**: The geo parsers return coord objects with
67
+ * only `coord.raw` (DD numbers) and formatting methods. They don't expose the parsed
68
+ * segment components we need for the UI (e.g., the degrees, minutes, and direction values).
69
+ *
70
+ * **Parsing Order**:
71
+ * - **convertDisplaySegmentsToDD**: Segments → String → **Geo parse** → DD ✓ (efficient)
72
+ * - **convertDDToDisplaySegments**: DD → String → Geo parse → Geo format → **This parse** → Segments ✗ (circular)
73
+ *
74
+ * @param coordString - Formatted coordinate string
75
+ * @param format - The coordinate system format
76
+ * @returns Array of segment values, or null if parsing fails
77
+ */
78
+ declare function parseCoordinateStringToSegments(coordString: string, format: CoordinateSystem): string[] | null;
79
+ /**
80
+ * Convert DD (internal format) to display format segment values
81
+ *
82
+ * Takes a CoordinateValue in Decimal Degrees format and converts it to the
83
+ * segment values needed for the specified display format.
84
+ *
85
+ * Uses @accelint/geo to ensure accurate conversion between coordinate systems.
86
+ *
87
+ * **Note on Circular Conversion**: This function demonstrates the circular conversion
88
+ * pattern discussed in the module documentation. The flow is:
89
+ *
90
+ * 1. Start with DD value: `{ lat: 40.7128, lon: -74.0060 }`
91
+ * 2. Convert to coordinate string: `"40.7128 / -74.006"`
92
+ * 3. Parse with geo package (creates coord object with internal parsed state)
93
+ * 4. Format to target system using geo: `coord.ddm()` → `"40 42.768 N / 74 0.36 W"`
94
+ * 5. Parse the formatted string AGAIN with regex to extract segments: `['40', '42.768', 'N', ...]`
95
+ *
96
+ * This is inefficient because:
97
+ * - The geo package already has the component values (degrees, minutes, direction) internally
98
+ * - We format them into a string, then immediately parse the string back apart
99
+ * - The regex parsing duplicates work the geo parsers already did
100
+ *
101
+ * However, this approach is necessary because:
102
+ * - The geo package only exposes `coord.raw` (DD numbers) and formatted strings
103
+ * - It doesn't expose the intermediate component values we need for the UI segments
104
+ * - We need individual segment values for separate input fields
105
+ *
106
+ * **Future Improvement**: If geo package exported component extractors like:
107
+ * ```typescript
108
+ * coord.components.ddm // { latDeg: 40, latMin: 42.768, latDir: 'N', ... }
109
+ * ```
110
+ * Then we could eliminate the format→parse cycle entirely.
111
+ *
112
+ * @param value - Coordinate value in DD format `{ lat: number, lon: number }`
113
+ * @param format - Target display format
114
+ * @returns Array of segment values for display, or null if conversion fails
115
+ *
116
+ * @example
117
+ * const segments = convertDDToDisplaySegments({ lat: 40.7128, lon: -74.0060 }, 'ddm');
118
+ * // Returns: ['40', '42.7680', 'N', '74', '0.3600', 'W']
119
+ */
120
+ declare function convertDDToDisplaySegments(value: CoordinateValue, format: CoordinateSystem): string[] | null;
121
+ /**
122
+ * Convert display format segment values to DD (internal format)
123
+ *
124
+ * Takes segment values from user input and converts them to a CoordinateValue
125
+ * in Decimal Degrees format using @accelint/geo for validation and conversion.
126
+ *
127
+ * **Note on Efficiency**: This function demonstrates the EFFICIENT conversion direction.
128
+ * The flow is:
129
+ *
130
+ * 1. Start with UI segments: `['40', '42.768', 'N', '74', '0.36', 'W']`
131
+ * 2. Build coordinate string: `"40° 42.768' N, 74° 0.36' W"`
132
+ * 3. Parse with geo package (validates and converts internally)
133
+ * 4. Extract DD from coord.raw: `{ lat: 40.7128, lon: -74.0060 }`
134
+ *
135
+ * This is efficient because:
136
+ * - We let geo do what it's designed for: parsing and validating coordinate strings
137
+ * - We extract the DD values directly from `coord.raw` (no string parsing needed)
138
+ * - Single direction: Segments → String → Geo Parse → DD (no circular conversion)
139
+ *
140
+ * Contrast with `convertDDToDisplaySegments` which has the circular pattern:
141
+ * DD → String → Geo Parse → Geo Format → String → Regex Parse → Segments
142
+ *
143
+ * @param segments - Array of segment values from user input
144
+ * @param format - The coordinate system format of the segments
145
+ * @returns CoordinateValue in DD format, or null if invalid
146
+ *
147
+ * @example
148
+ * const coord = convertDisplaySegmentsToDD(['40', '42.7680', 'N', '74', '0.3600', 'W'], 'ddm');
149
+ * // Returns: { lat: 40.7128, lon: -74.0060 }
150
+ */
151
+ declare function convertDisplaySegmentsToDD(segments: string[], format: CoordinateSystem): CoordinateValue | null;
152
+ /**
153
+ * Validate coordinate segments and return errors
154
+ *
155
+ * Uses @accelint/geo to validate the segments and returns any validation errors.
156
+ * Only validates when all required segments are filled.
157
+ *
158
+ * @param segments - Array of segment values from user input
159
+ * @param format - The coordinate system format
160
+ * @returns Array of error messages, empty if valid or incomplete
161
+ *
162
+ * @example
163
+ * const errors = validateCoordinateSegments(['91', '0', 'N', '0', '0', 'E'], 'ddm');
164
+ * // Returns: ['Invalid coordinate value']
165
+ */
166
+ declare function validateCoordinateSegments(segments: string[], format: CoordinateSystem): string[];
167
+ /**
168
+ * Check if all segments are filled
169
+ *
170
+ * Helper to determine if the user has completed entering all segment values.
171
+ * Used to determine when to trigger validation.
172
+ *
173
+ * @param segments - Array of segment values
174
+ * @returns True if all segments have values, false otherwise
175
+ */
176
+ declare function areAllSegmentsFilled(segments: string[]): boolean;
177
+ /**
178
+ * Check if any segments have values
179
+ *
180
+ * Helper to determine if the user has started entering coordinate values.
181
+ *
182
+ * @param segments - Array of segment values
183
+ * @returns True if any segment has a value, false if all empty
184
+ */
185
+ declare function hasAnySegmentValue(segments: string[]): boolean;
186
+ /**
187
+ * Get all coordinate formats for a given DD value
188
+ *
189
+ * Converts a Decimal Degrees coordinate to all 5 supported coordinate systems
190
+ * for display in the format conversion popover.
191
+ *
192
+ * Each format is tried independently - if one fails (e.g., UTM/MGRS at poles),
193
+ * the others can still succeed.
194
+ *
195
+ * @param value - Coordinate value in DD format `{ lat: number, lon: number }`
196
+ * @returns Object containing formatted strings and validity status for all coordinate systems
197
+ *
198
+ * @example
199
+ * const formats = getAllCoordinateFormats({ lat: 40.7128, lon: -74.0060 });
200
+ * // Returns: {
201
+ * // dd: { value: "40.7128 N / 74.006 W", isValid: true },
202
+ * // ddm: { value: "40 42.768 N / 74 0.36 W", isValid: true },
203
+ * // dms: { value: "40 42 46.08 N / 74 0 21.6 W", isValid: true },
204
+ * // mgrs: { value: "18T WL 80654 06346", isValid: true },
205
+ * // utm: { value: "18N 585628 4511644", isValid: true }
206
+ * // }
207
+ *
208
+ * @example
209
+ * const formats = getAllCoordinateFormats({ lat: 90, lon: 0 });
210
+ * // Returns: {
211
+ * // dd: { value: "90 N / 0 E", isValid: true },
212
+ * // ddm: { value: "90 0 N / 0 0 E", isValid: true },
213
+ * // dms: { value: "90 0 0 N / 0 0 0 E", isValid: true },
214
+ * // mgrs: { value: "Not available at poles", isValid: false },
215
+ * // utm: { value: "Not available at poles", isValid: false }
216
+ * // }
217
+ */
218
+ declare function getAllCoordinateFormats(value: CoordinateValue | null): Record<CoordinateSystem, CoordinateFormatResult>;
219
+ /**
220
+ * Check if pasted text looks like a complete coordinate string
221
+ *
222
+ * Uses heuristics to detect if the pasted text contains a full coordinate
223
+ * rather than just a single segment value. This prevents intercepting
224
+ * single-segment pastes.
225
+ *
226
+ * Indicators of a complete coordinate:
227
+ * - Contains separators: comma, slash, or multiple consecutive spaces
228
+ * - Contains coordinate symbols: °, ′, ″, ', "
229
+ * - Multiple numbers separated by whitespace
230
+ *
231
+ * @param text - The pasted text to check
232
+ * @returns True if it looks like a complete coordinate string
233
+ *
234
+ * @example
235
+ * isCompleteCoordinate("40.7128, -74.0060") // true - contains comma
236
+ * isCompleteCoordinate("40° 42' 46\" N / 74° 0' 22\" W") // true - contains symbols
237
+ * isCompleteCoordinate("18T WM 12345 67890") // true - multiple parts
238
+ * isCompleteCoordinate("42") // false - single number
239
+ * isCompleteCoordinate("N") // false - single letter
240
+ */
241
+ declare function isCompleteCoordinate(text: string): boolean;
242
+ /**
243
+ * Attempt to parse pasted text as all coordinate formats
244
+ *
245
+ * Tries to parse the pasted text using each of the 5 coordinate system parsers.
246
+ * Returns all formats that successfully parse the text.
247
+ *
248
+ * This enables automatic detection of coordinate format and disambiguation
249
+ * when multiple formats match the same input string.
250
+ *
251
+ * @param pastedText - The raw text from clipboard
252
+ * @returns Array of successfully parsed coordinate matches (may be empty)
253
+ *
254
+ * @example
255
+ * const matches = parseCoordinatePaste("40.7128, -74.0060");
256
+ * // Returns: [{ format: 'dd', value: { lat: 40.7128, lon: -74.0060 }, displayString: "..." }]
257
+ *
258
+ * @example
259
+ * const matches = parseCoordinatePaste("18T WM 12345 67890");
260
+ * // Returns: [{ format: 'mgrs', value: { lat: ..., lon: ... }, displayString: "..." }]
261
+ *
262
+ * @example
263
+ * const matches = parseCoordinatePaste("invalid text");
264
+ * // Returns: []
265
+ */
266
+ declare function parseCoordinatePaste(pastedText: string): ParsedCoordinateMatch[];
267
+ /**
268
+ * Check if two coordinates are equal within epsilon tolerance
269
+ */
270
+ declare function areCoordinatesEqual(coord1: {
271
+ lat: number;
272
+ lon: number;
273
+ }, coord2: {
274
+ lat: number;
275
+ lon: number;
276
+ }, epsilon?: number): boolean;
277
+ /**
278
+ * Deduplicate coordinate matches by location, keeping first match for each unique location
279
+ */
280
+ declare function deduplicateMatchesByLocation(matches: ParsedCoordinateMatch[]): ParsedCoordinateMatch[];
281
+
282
+ export { COORDINATE_EPSILON, COORDINATE_ERROR_MESSAGES, type CoordinateFormatResult, areAllSegmentsFilled, areCoordinatesEqual, convertDDToDisplaySegments, convertDisplaySegmentsToDD, deduplicateMatchesByLocation, formatSegmentsToCoordinateString, getAllCoordinateFormats, hasAnySegmentValue, isCompleteCoordinate, parseCoordinatePaste, parseCoordinateStringToSegments, validateCoordinateSegments };
@@ -0,0 +1,2 @@
1
+ import {getLogger}from'@accelint/logger';import {createCoordinate,coordinateSystems}from'@accelint/geo';import {COORDINATE_SYSTEMS}from'./types.js';const u=getLogger({enabled:process.env.NODE_ENV!=="production",level:"debug",prefix:"[CoordinateField]",pretty:true});const h=1e-6,l={INVALID:"Invalid coordinate",CONVERSION_FAILED:"Conversion failed",NOT_AVAILABLE_AT_POLES:"Not available at poles"};function S(t){if(t.length<2)return null;const r=Number.parseFloat(t[0]),n=Number.parseFloat(t[1]);if(Number.isNaN(r)||Number.isNaN(n))return null;const e=r>=0?"N":"S",a=n>=0?"E":"W";return `${Math.abs(r)} ${e} / ${Math.abs(n)} ${a}`}function C(t){return t.length<6?null:`${t[0]}\xB0 ${t[1]}' ${t[2]}, ${t[3]}\xB0 ${t[4]}' ${t[5]}`}function p(t){return t.length<8?null:`${t[0]}\xB0 ${t[1]}' ${t[2]}" ${t[3]}, ${t[4]}\xB0 ${t[5]}' ${t[6]}" ${t[7]}`}function N(t){return t.length<5?null:`${t[0]}${t[1]} ${t[2]} ${t[3]} ${t[4]}`}function b(t){return t.length<4?null:`${t[0]}${t[1]} ${t[2]} ${t[3]}`}function f(t,r){if(t.some(n=>n===""||n===void 0))return null;try{switch(r){case "dd":return S(t);case "ddm":return C(t);case "dms":return p(t);case "mgrs":return N(t);case "utm":return b(t);default:return null}}catch{return null}}function y(t){const r=t.match(/([-]?\d+\.?\d*)°?\s*([NS])?\s*[,/\s]+\s*([-]?\d+\.?\d*)°?\s*([EW])?/i);if(!r)return null;let n=r[1],e=r[3];return n&&e?(r[2]?.toUpperCase()==="S"&&!n.startsWith("-")&&(n=`-${n}`),r[4]?.toUpperCase()==="W"&&!e.startsWith("-")&&(e=`-${e}`),[n,e]):null}function D(t){const r=t.match(/(\d+)°?\s+([\d.]+)'?\s+([NS])\s*[,/]\s*(\d+)°?\s+([\d.]+)'?\s+([EW])/i);return r?[r[1],r[2],r[3],r[4],r[5],r[6]]:null}function $(t){const r=t.match(/(\d+)°?\s+(\d+)'?\s+([\d.]+)"?\s+([NS])\s*[,/]\s*(\d+)°?\s+(\d+)'?\s+([\d.]+)"?\s+([EW])/i);return r?[r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8]]:null}function v(t){const r=t.match(/(\d+)([A-Z])\s+([A-Z]{2})\s+(\d+)\s+(\d+)/i);return r?[r[1],r[2],r[3],r[4],r[5]]:null}function A(t){const r=t.match(/(\d+)\s*([NS])\s+(\d+)\s+(\d+)/i);return r?[r[1],r[2],r[3],r[4]]:null}function V(t,r){if(!t)return null;try{switch(r){case "dd":return y(t);case "ddm":return D(t);case "dms":return $(t);case "mgrs":return v(t);case "utm":return A(t);default:return null}}catch{return null}}function k(t,r){if(!t||typeof t.lat!="number"||typeof t.lon!="number")return null;try{const n=createCoordinate(coordinateSystems.dd,"LATLON"),e=Number(t.lat.toFixed(5)),a=Number(t.lon.toFixed(5)),s=`${e} / ${a}`,i=n(s);if(!i.valid)return null;let o;switch(r){case "dd":o=i.dd();break;case "ddm":o=i.ddm();break;case "dms":o=i.dms();break;case "mgrs":o=i.mgrs();break;case "utm":o=i.utm();break;default:return null}return V(o,r)}catch(n){return u.withContext({value:String(t),format:String(r)}).withError(n).error("Failed to convert DD to display"),null}}function x(t,r){const n=f(t,r);if(!n)return null;try{const a=createCoordinate(coordinateSystems[r],"LATLON")(n);if(!a.valid)return null;const{LAT:s,LON:i}=a.raw;return {lat:s,lon:i}}catch(e){return u.withContext({segments:JSON.stringify(t),format:String(r)}).withError(e).error("Failed to convert display to DD"),null}}function _(t,r){if(t.some(e=>e===""||e===void 0))return [];const n=f(t,r);if(!n)return ["Invalid coordinate value"];try{return createCoordinate(coordinateSystems[r],"LATLON")(n).valid?[]:["Invalid coordinate value"]}catch{return ["Invalid coordinate value"]}}function P(t){return t.every(r=>r!==""&&r!==void 0)}function U(t){return t.some(r=>r!==""&&r!==void 0)}function L(){return {dd:{value:l.INVALID,isValid:false},ddm:{value:l.INVALID,isValid:false},dms:{value:l.INVALID,isValid:false},mgrs:{value:l.INVALID,isValid:false},utm:{value:l.INVALID,isValid:false}}}function E(t){return t!==null&&typeof t.lat=="number"&&typeof t.lon=="number"}function I(t){const r=t instanceof Error?t.message:String(t);return r.includes("outside UTM limits")||r.includes("invalid UTM zone")}function M(t,r,n){try{let e;switch(r){case "dd":e=t.dd();break;case "ddm":e=t.ddm();break;case "dms":e=t.dms();break;case "mgrs":e=t.mgrs();break;case "utm":e=t.utm();break;default:return {value:l.INVALID,isValid:!1}}return {value:e,isValid:!0}}catch(e){return (r==="mgrs"||r==="utm")&&I(e)?{value:l.NOT_AVAILABLE_AT_POLES,isValid:false}:(u.withContext({value:JSON.stringify(n)}).withError(e).error(`Failed to convert to ${r}`),{value:l.CONVERSION_FAILED,isValid:false})}}function W(t){const r=L();if(!E(t))return r;const n=t;try{const a=createCoordinate(coordinateSystems.dd,"LATLON")(`${n.lat} / ${n.lon}`);if(!a.valid)return r;const s={};for(const i of COORDINATE_SYSTEMS)s[i]=M(a,i,n);return s}catch(e){return u.withContext({value:JSON.stringify(n)}).withError(e).error("Failed to get all coordinate formats"),r}}function G(t){if(!t||t.trim()==="")return false;const r=/[,/]|°|′|″|['"]|\s{2,}/.test(t),e=(t.match(/\d+/g)||[]).length>=2,a=/^\d{1,2}[A-Z]\s+[A-Z]{2}\s+\d+\s+\d+$/i.test(t.trim()),s=/^\d{1,2}[NS]\s+\d+\s+\d+$/i.test(t.trim());return r||e||a||s}function Z(t){if(!t||t.trim()==="")return [];const r=[];for(const n of COORDINATE_SYSTEMS)try{const a=createCoordinate(coordinateSystems[n],"LATLON")(t.trim());if(a.valid){const{LAT:s,LON:i}=a.raw;let o;switch(n){case "dd":o=a.dd();break;case "ddm":o=a.ddm();break;case "dms":o=a.dms();break;case "mgrs":o=a.mgrs();break;case "utm":o=a.utm();break;default:o="";}r.push({format:n,value:{lat:s,lon:i},displayString:o});}}catch(e){u.withContext({pastedText:t.trim(),format:String(n)}).withError(e).warn(`Failed to parse as ${n}`);}return r}function O(t,r,n=h){return Math.abs(t.lat-r.lat)<n&&Math.abs(t.lon-r.lon)<n}function B(t){const r=[];for(const n of t)r.some(a=>O(a.value,n.value))||r.push(n);return r}export{h as COORDINATE_EPSILON,l as COORDINATE_ERROR_MESSAGES,P as areAllSegmentsFilled,O as areCoordinatesEqual,k as convertDDToDisplaySegments,x as convertDisplaySegmentsToDD,B as deduplicateMatchesByLocation,f as formatSegmentsToCoordinateString,W as getAllCoordinateFormats,U as hasAnySegmentValue,G as isCompleteCoordinate,Z as parseCoordinatePaste,V as parseCoordinateStringToSegments,_ as validateCoordinateSegments};//# sourceMappingURL=coordinate-utils.js.map
2
+ //# sourceMappingURL=coordinate-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/coordinate-field/coordinate-utils.ts"],"names":["logger","getLogger","segments","lonNum","lonDir","latNum","latDir","format","seg","match","lat","lon","coordString","value","coordinateSystems","c","d","inputCoordString","coord","create","LAT","LON","error","formattedValue","isValidCoordinateValue","validValue","COORDINATE_SYSTEMS","convertToFormat","text","hasMultipleNumbers","isMGRS","isUTM","pastedText","displayString","matches","coord2","epsilon","COORDINATE_EPSILON","coord1","areCoordinatesEqual","existing","uniqueMatches"],"mappings":"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","file":"coordinate-utils.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { getLogger } from '@accelint/logger';\n\nconst logger = getLogger({\n enabled: process.env.NODE_ENV !== 'production',\n level: 'debug',\n prefix: '[CoordinateField]',\n pretty: true,\n});\n\n/**\n * Coordinate Conversion Utilities\n *\n * This module provides utilities for converting between:\n * 1. Segment values (user input) → Coordinate strings (for @accelint/geo parsing)\n * 2. Coordinate strings (from @accelint/geo output) → Segment values (for display)\n * 3. Decimal Degrees (internal format) ↔ Display format segment values\n *\n * All conversions use the local @accelint/geo package for accurate coordinate parsing\n * and conversion between coordinate systems.\n *\n * ## Architecture: Bridge Layer Between UI and Geo Package\n *\n * This module serves as a bridge layer to handle the impedance mismatch between:\n * - **UI Requirements**: Individual segment fields (e.g., degrees, minutes, seconds, direction)\n * - **Geo Package API**: Complete coordinate strings (e.g., \"40° 42' 46\" N / 74° 0' 22\" W\")\n *\n * ### Why This Bridge Layer Exists\n *\n * The @accelint/geo package provides excellent coordinate parsing, validation, and conversion,\n * but its API is designed around complete coordinate strings:\n *\n * ```typescript\n * // What geo provides:\n * const coord = createCoordinate(coordinateSystems.ddm, 'LATLON')('40 42.768 N / 74 0.36 W');\n * coord.dd() // Returns: \"40.7128 N / 74.006 W\" (formatted string)\n * coord.ddm() // Returns: \"40 42.768 N / 74 0.36 W\" (formatted string)\n * coord.raw // Returns: { LAT: 40.7128, LON: -74.006 } (only DD numbers)\n * ```\n *\n * The coordinate-field component needs segment-level data for individual input fields:\n * - DDM: ['40', '42.768', 'N', '74', '0.36', 'W'] ← Not provided by geo\n * - DMS: ['40', '42', '46.08', 'N', '74', '0', '21.6', 'W'] ← Not provided by geo\n *\n * ### Current Limitations and Duplication\n *\n * Because the geo package only exposes:\n * 1. **Formatters** that return complete strings (coord.ddm(), coord.dms(), etc.)\n * 2. **Raw values** in Decimal Degrees only (coord.raw)\n *\n * This module must:\n * 1. Build coordinate strings from segments → Pass to geo for parsing\n * 2. Parse geo's formatted output strings → Extract segments using regex\n *\n * This creates a circular conversion flow for DD → Display Segments:\n * ```\n * DD value → String → Geo parse → Geo format → String → Regex parse → Segments\n * ```\n *\n * **Note on Duplication**: The regex parsing in this module duplicates work that the\n * geo package parsers already do internally. However, since geo doesn't expose the\n * parsed segment components (only formatted strings and raw DD values), we must\n * re-parse its output to extract the individual segments for the UI.\n *\n * ### What Would Eliminate This Duplication\n *\n * If the geo package exported component-level converters like:\n * ```typescript\n * // Hypothetical API that would eliminate the bridge layer:\n * export function ddToDdmComponents(dd: number): {\n * degrees: number;\n * minutes: number;\n * direction: 'N' | 'S' | 'E' | 'W';\n * }\n * ```\n *\n * Then this bridge layer could be significantly simplified. The math for these conversions\n * exists in the geo package's formatters (e.g., formatDegreesDecimalMinutes), but it's\n * wrapped in string formatting logic rather than exposed as standalone utilities.\n *\n * ### Conversion Efficiency\n *\n * - **Efficient Path** (Display Segments → DD): Segments → String → Geo parse → DD\n * - Uses geo package for all parsing and validation ✓\n *\n * - **Inefficient Path** (DD → Display Segments): DD → String → Geo parse → Geo format → Regex parse → Segments\n * - Circular conversion with redundant string parsing/formatting ✗\n * - Necessary given current geo API limitations\n */\n\nimport { coordinateSystems, createCoordinate } from '@accelint/geo';\nimport {\n COORDINATE_SYSTEMS,\n type CoordinateSystem,\n type CoordinateValue,\n type ParsedCoordinateMatch,\n} from './types';\n\n/** Epsilon for coordinate equality comparison (≈11cm precision at equator) */\nexport const COORDINATE_EPSILON = 0.000001;\n\n/**\n * Error message constants for coordinate format conversion\n * @internal\n */\nexport const COORDINATE_ERROR_MESSAGES = {\n INVALID: 'Invalid coordinate',\n CONVERSION_FAILED: 'Conversion failed',\n NOT_AVAILABLE_AT_POLES: 'Not available at poles',\n} as const;\n\n/**\n * Result of coordinate format conversion\n */\nexport interface CoordinateFormatResult {\n /** The formatted coordinate string or error message */\n value: string;\n /** Whether the coordinate format is valid and can be used/copied */\n isValid: boolean;\n}\n\n/**\n * Format DD (Decimal Degrees) segments to coordinate string\n *\n * Bridge function that builds a coordinate string from UI segment values\n * for passing to the geo package parser. Part of the Segments → String → Geo Parse flow.\n *\n * @internal\n */\nfunction formatDDSegments(segments: string[]): string | null {\n if (segments.length < 2) {\n return null;\n }\n const latNum = Number.parseFloat(segments[0] as string);\n const lonNum = Number.parseFloat(segments[1] as string);\n\n if (Number.isNaN(latNum) || Number.isNaN(lonNum)) {\n return null;\n }\n\n const latDir = latNum >= 0 ? 'N' : 'S';\n const lonDir = lonNum >= 0 ? 'E' : 'W';\n\n return `${Math.abs(latNum)} ${latDir} / ${Math.abs(lonNum)} ${lonDir}`;\n}\n\n/**\n * Format DDM (Degrees Decimal Minutes) segments to coordinate string\n *\n * Bridge function that builds a coordinate string from UI segment values\n * for passing to the geo package parser. Part of the Segments → String → Geo Parse flow.\n *\n * @internal\n */\nfunction formatDDMSegments(segments: string[]): string | null {\n if (segments.length < 6) {\n return null;\n }\n return `${segments[0]}° ${segments[1]}' ${segments[2]}, ${segments[3]}° ${segments[4]}' ${segments[5]}`;\n}\n\n/**\n * Format DMS (Degrees Minutes Seconds) segments to coordinate string\n *\n * Bridge function that builds a coordinate string from UI segment values\n * for passing to the geo package parser. Part of the Segments → String → Geo Parse flow.\n *\n * @internal\n */\nfunction formatDMSSegments(segments: string[]): string | null {\n if (segments.length < 8) {\n return null;\n }\n return `${segments[0]}° ${segments[1]}' ${segments[2]}\" ${segments[3]}, ${segments[4]}° ${segments[5]}' ${segments[6]}\" ${segments[7]}`;\n}\n\n/**\n * Format MGRS (Military Grid Reference System) segments to coordinate string\n *\n * Bridge function that builds a coordinate string from UI segment values\n * for passing to the geo package parser. Part of the Segments → String → Geo Parse flow.\n *\n * @internal\n */\nfunction formatMGRSSegments(segments: string[]): string | null {\n if (segments.length < 5) {\n return null;\n }\n return `${segments[0]}${segments[1]} ${segments[2]} ${segments[3]} ${segments[4]}`;\n}\n\n/**\n * Format UTM (Universal Transverse Mercator) segments to coordinate string\n *\n * Bridge function that builds a coordinate string from UI segment values\n * for passing to the geo package parser. Part of the Segments → String → Geo Parse flow.\n *\n * @internal\n */\nfunction formatUTMSegments(segments: string[]): string | null {\n if (segments.length < 4) {\n return null;\n }\n return `${segments[0]}${segments[1]} ${segments[2]} ${segments[3]}`;\n}\n\n/**\n * Format segment values into a coordinate string suitable for @accelint/geo parsing\n *\n * Converts an array of segment values into a string format that the geo package\n * parsers can understand. Each format has different requirements:\n *\n * DD: [lat, lon] → \"lat, lon\"\n * DDM: [latDeg, latMin, latDir, lonDeg, lonMin, lonDir] → \"latDeg° latMin' latDir, lonDeg° lonMin' lonDir\"\n * DMS: [latDeg, latMin, latSec, latDir, lonDeg, lonMin, lonSec, lonDir] → \"latDeg° latMin' latSec\\\" latDir, lonDeg° lonMin' lonSec\\\" lonDir\"\n * MGRS: [zone, band, grid, easting, northing] → \"zone+band grid easting northing\"\n * UTM: [zone, hemisphere, easting, northing] → \"zone+hemisphere easting northing\"\n *\n * @param segments - Array of segment values from user input\n * @param format - The coordinate system format\n * @returns Formatted coordinate string, or null if segments are invalid\n */\nexport function formatSegmentsToCoordinateString(\n segments: string[],\n format: CoordinateSystem,\n): string | null {\n if (segments.some((seg) => seg === '' || seg === undefined)) {\n return null;\n }\n\n try {\n switch (format) {\n case 'dd':\n return formatDDSegments(segments);\n case 'ddm':\n return formatDDMSegments(segments);\n case 'dms':\n return formatDMSSegments(segments);\n case 'mgrs':\n return formatMGRSSegments(segments);\n case 'utm':\n return formatUTMSegments(segments);\n default:\n return null;\n }\n } catch (_error) {\n return null;\n }\n}\n\n/**\n * Parse DD coordinate string to segments\n *\n * Extracts segment values from a formatted DD coordinate string. This duplicates\n * parsing logic from @accelint/geo's parseDecimalDegrees, but is necessary because\n * geo doesn't expose the parsed components - only formatted strings and raw DD numbers.\n *\n * Part of the Geo Format → String → Regex Parse → Segments flow (circular conversion).\n *\n * @internal\n */\nfunction parseDDCoordinateString(coordString: string): string[] | null {\n // DD formats from @accelint/geo (no degree symbols):\n // \"40.7128 N / -74.006 W\" or \"0 N / 180 W\"\n // Also handle user input with symbols:\n // \"89.765432° N / 123.456789° W\" or \"89.765432, -123.456789\"\n\n // Match DD format with optional degree symbols and optional direction letters\n const match = coordString.match(\n /([-]?\\d+\\.?\\d*)°?\\s*([NS])?\\s*[,/\\s]+\\s*([-]?\\d+\\.?\\d*)°?\\s*([EW])?/i,\n );\n if (!match) {\n return null;\n }\n\n let lat = match[1];\n let lon = match[3];\n\n if (!(lat && lon)) {\n return null;\n }\n\n if (match[2]?.toUpperCase() === 'S' && !lat.startsWith('-')) {\n lat = `-${lat}`;\n }\n if (match[4]?.toUpperCase() === 'W' && !lon.startsWith('-')) {\n lon = `-${lon}`;\n }\n\n return [lat, lon];\n}\n\n/**\n * Parse DDM coordinate string to segments\n *\n * Extracts segment values from a formatted DDM coordinate string. This duplicates\n * parsing logic from @accelint/geo's parseDegreesDecimalMinutes, but is necessary because\n * geo doesn't expose the parsed components - only formatted strings and raw DD numbers.\n *\n * Part of the Geo Format → String → Regex Parse → Segments flow (circular conversion).\n *\n * @internal\n */\nfunction parseDDMCoordinateString(coordString: string): string[] | null {\n // DDM formats from @accelint/geo (no symbols):\n // \"40 42.768 N / 74 0.36 W\"\n // Also handle user input with symbols:\n // \"89° 45.9259' N / 123° 27.4073' W\"\n\n // Match DDM format with optional degree and minute symbols\n const match = coordString.match(\n /(\\d+)°?\\s+([\\d.]+)'?\\s+([NS])\\s*[,/]\\s*(\\d+)°?\\s+([\\d.]+)'?\\s+([EW])/i,\n );\n if (!match) {\n return null;\n }\n return [\n match[1] as string,\n match[2] as string,\n match[3] as string,\n match[4] as string,\n match[5] as string,\n match[6] as string,\n ];\n}\n\n/**\n * Parse DMS coordinate string to segments\n *\n * Extracts segment values from a formatted DMS coordinate string. This duplicates\n * parsing logic from @accelint/geo's parseDegreesMinutesSeconds, but is necessary because\n * geo doesn't expose the parsed components - only formatted strings and raw DD numbers.\n *\n * Part of the Geo Format → String → Regex Parse → Segments flow (circular conversion).\n *\n * @internal\n */\nfunction parseDMSCoordinateString(coordString: string): string[] | null {\n // DMS formats from @accelint/geo (no symbols):\n // \"40 42 46.08 N / 74 0 21.60 W\"\n // Also handle user input with symbols:\n // \"89° 45' 55.56\" N / 123° 27' 24.44\" W\"\n\n // Match DMS format with optional degree, minute, and second symbols\n const match = coordString.match(\n /(\\d+)°?\\s+(\\d+)'?\\s+([\\d.]+)\"?\\s+([NS])\\s*[,/]\\s*(\\d+)°?\\s+(\\d+)'?\\s+([\\d.]+)\"?\\s+([EW])/i,\n );\n if (!match) {\n return null;\n }\n return [\n match[1] as string,\n match[2] as string,\n match[3] as string,\n match[4] as string,\n match[5] as string,\n match[6] as string,\n match[7] as string,\n match[8] as string,\n ];\n}\n\n/**\n * Parse MGRS coordinate string to segments\n *\n * Extracts segment values from a formatted MGRS coordinate string. This duplicates\n * parsing logic from @accelint/geo's parseMGRS, but is necessary because\n * geo doesn't expose the parsed components - only formatted strings and raw DD numbers.\n *\n * Part of the Geo Format → String → Regex Parse → Segments flow (circular conversion).\n *\n * @internal\n */\nfunction parseMGRSCoordinateString(coordString: string): string[] | null {\n // MGRS: \"18T WM 12345 67890\"\n const match = coordString.match(/(\\d+)([A-Z])\\s+([A-Z]{2})\\s+(\\d+)\\s+(\\d+)/i);\n if (!match) {\n return null;\n }\n return [\n match[1] as string,\n match[2] as string,\n match[3] as string,\n match[4] as string,\n match[5] as string,\n ];\n}\n\n/**\n * Parse UTM coordinate string to segments\n *\n * Extracts segment values from a formatted UTM coordinate string. This duplicates\n * parsing logic from @accelint/geo's parseUTM, but is necessary because\n * geo doesn't expose the parsed components - only formatted strings and raw DD numbers.\n *\n * Part of the Geo Format → String → Regex Parse → Segments flow (circular conversion).\n *\n * @internal\n */\nfunction parseUTMCoordinateString(coordString: string): string[] | null {\n // UTM: \"18N 585628 4511644\" or \"18 N 585628 4511644\" (with optional space)\n const match = coordString.match(/(\\d+)\\s*([NS])\\s+(\\d+)\\s+(\\d+)/i);\n if (!match) {\n return null;\n }\n return [\n match[1] as string,\n match[2] as string,\n match[3] as string,\n match[4] as string,\n ];\n}\n\n/**\n * Parse a coordinate string into segment values\n *\n * Converts a formatted coordinate string (from @accelint/geo output or user input)\n * back into individual segment values for display.\n *\n * This is the inverse of formatSegmentsToCoordinateString.\n *\n * **Note on Duplication**: This function and its helpers (parseDDCoordinateString,\n * parseDDMCoordinateString, etc.) duplicate parsing logic that already exists in\n * the @accelint/geo package parsers:\n *\n * - Geo parsers: parseDecimalDegrees, parseDegreesDecimalMinutes, etc.\n * - These functions: parseDDCoordinateString, parseDDMCoordinateString, etc.\n *\n * Both use regex patterns to extract coordinate components from strings. The duplication\n * exists because:\n *\n * 1. **Geo parsers** extract components, validate them, convert to DD, then format back to strings\n * 2. **This function** extracts components from those formatted strings for the UI\n *\n * We're essentially undoing the formatting that geo just did. This is the second half\n * of the circular conversion described in convertDDToDisplaySegments.\n *\n * **Why we can't use geo parsers directly**: The geo parsers return coord objects with\n * only `coord.raw` (DD numbers) and formatting methods. They don't expose the parsed\n * segment components we need for the UI (e.g., the degrees, minutes, and direction values).\n *\n * **Parsing Order**:\n * - **convertDisplaySegmentsToDD**: Segments → String → **Geo parse** → DD ✓ (efficient)\n * - **convertDDToDisplaySegments**: DD → String → Geo parse → Geo format → **This parse** → Segments ✗ (circular)\n *\n * @param coordString - Formatted coordinate string\n * @param format - The coordinate system format\n * @returns Array of segment values, or null if parsing fails\n */\nexport function parseCoordinateStringToSegments(\n coordString: string,\n format: CoordinateSystem,\n): string[] | null {\n if (!coordString) {\n return null;\n }\n\n try {\n switch (format) {\n case 'dd':\n return parseDDCoordinateString(coordString);\n case 'ddm':\n return parseDDMCoordinateString(coordString);\n case 'dms':\n return parseDMSCoordinateString(coordString);\n case 'mgrs':\n return parseMGRSCoordinateString(coordString);\n case 'utm':\n return parseUTMCoordinateString(coordString);\n default:\n return null;\n }\n } catch (_error) {\n return null;\n }\n}\n\n/**\n * Convert DD (internal format) to display format segment values\n *\n * Takes a CoordinateValue in Decimal Degrees format and converts it to the\n * segment values needed for the specified display format.\n *\n * Uses @accelint/geo to ensure accurate conversion between coordinate systems.\n *\n * **Note on Circular Conversion**: This function demonstrates the circular conversion\n * pattern discussed in the module documentation. The flow is:\n *\n * 1. Start with DD value: `{ lat: 40.7128, lon: -74.0060 }`\n * 2. Convert to coordinate string: `\"40.7128 / -74.006\"`\n * 3. Parse with geo package (creates coord object with internal parsed state)\n * 4. Format to target system using geo: `coord.ddm()` → `\"40 42.768 N / 74 0.36 W\"`\n * 5. Parse the formatted string AGAIN with regex to extract segments: `['40', '42.768', 'N', ...]`\n *\n * This is inefficient because:\n * - The geo package already has the component values (degrees, minutes, direction) internally\n * - We format them into a string, then immediately parse the string back apart\n * - The regex parsing duplicates work the geo parsers already did\n *\n * However, this approach is necessary because:\n * - The geo package only exposes `coord.raw` (DD numbers) and formatted strings\n * - It doesn't expose the intermediate component values we need for the UI segments\n * - We need individual segment values for separate input fields\n *\n * **Future Improvement**: If geo package exported component extractors like:\n * ```typescript\n * coord.components.ddm // { latDeg: 40, latMin: 42.768, latDir: 'N', ... }\n * ```\n * Then we could eliminate the format→parse cycle entirely.\n *\n * @param value - Coordinate value in DD format `{ lat: number, lon: number }`\n * @param format - Target display format\n * @returns Array of segment values for display, or null if conversion fails\n *\n * @example\n * const segments = convertDDToDisplaySegments({ lat: 40.7128, lon: -74.0060 }, 'ddm');\n * // Returns: ['40', '42.7680', 'N', '74', '0.3600', 'W']\n */\nexport function convertDDToDisplaySegments(\n value: CoordinateValue,\n format: CoordinateSystem,\n): string[] | null {\n if (\n !value ||\n typeof value.lat !== 'number' ||\n typeof value.lon !== 'number'\n ) {\n return null;\n }\n\n try {\n const create = createCoordinate(coordinateSystems.dd, 'LATLON');\n\n // Round to 5 decimal places to prevent precision issues with geo package\n // Use signed numbers (not cardinal directions) for reliable conversions to all formats\n const lat = Number(value.lat.toFixed(5));\n const lon = Number(value.lon.toFixed(5));\n const inputCoordString = `${lat} / ${lon}`;\n\n const coord = create(inputCoordString);\n\n if (!coord.valid) {\n return null;\n }\n\n // Format the coordinate using geo package formatters\n // These return complete coordinate strings (e.g., \"40 42.768 N / 74 0.36 W\")\n let coordString: string;\n switch (format) {\n case 'dd':\n coordString = coord.dd();\n break;\n case 'ddm':\n coordString = coord.ddm();\n break;\n case 'dms':\n coordString = coord.dms();\n break;\n case 'mgrs':\n coordString = coord.mgrs();\n break;\n case 'utm':\n coordString = coord.utm();\n break;\n default:\n return null;\n }\n\n // Parse the formatted string to extract individual segment values\n // This is the circular part: geo formatted it, now we parse it back apart\n // Necessary because geo doesn't expose the components directly\n const segments = parseCoordinateStringToSegments(coordString, format);\n return segments;\n } catch (error) {\n logger\n .withContext({\n value: String(value),\n format: String(format),\n })\n .withError(error)\n .error('Failed to convert DD to display');\n return null;\n }\n}\n\n/**\n * Convert display format segment values to DD (internal format)\n *\n * Takes segment values from user input and converts them to a CoordinateValue\n * in Decimal Degrees format using @accelint/geo for validation and conversion.\n *\n * **Note on Efficiency**: This function demonstrates the EFFICIENT conversion direction.\n * The flow is:\n *\n * 1. Start with UI segments: `['40', '42.768', 'N', '74', '0.36', 'W']`\n * 2. Build coordinate string: `\"40° 42.768' N, 74° 0.36' W\"`\n * 3. Parse with geo package (validates and converts internally)\n * 4. Extract DD from coord.raw: `{ lat: 40.7128, lon: -74.0060 }`\n *\n * This is efficient because:\n * - We let geo do what it's designed for: parsing and validating coordinate strings\n * - We extract the DD values directly from `coord.raw` (no string parsing needed)\n * - Single direction: Segments → String → Geo Parse → DD (no circular conversion)\n *\n * Contrast with `convertDDToDisplaySegments` which has the circular pattern:\n * DD → String → Geo Parse → Geo Format → String → Regex Parse → Segments\n *\n * @param segments - Array of segment values from user input\n * @param format - The coordinate system format of the segments\n * @returns CoordinateValue in DD format, or null if invalid\n *\n * @example\n * const coord = convertDisplaySegmentsToDD(['40', '42.7680', 'N', '74', '0.3600', 'W'], 'ddm');\n * // Returns: { lat: 40.7128, lon: -74.0060 }\n */\nexport function convertDisplaySegmentsToDD(\n segments: string[],\n format: CoordinateSystem,\n): CoordinateValue | null {\n // Build coordinate string from segments for geo parsing\n const coordString = formatSegmentsToCoordinateString(segments, format);\n if (!coordString) {\n return null;\n }\n\n try {\n // Parse and validate with geo package\n const create = createCoordinate(coordinateSystems[format], 'LATLON');\n const coord = create(coordString);\n\n if (!coord.valid) {\n // Return null for invalid coordinates (errors will be handled separately)\n return null;\n }\n\n // Extract DD values directly from coord.raw (no string parsing needed)\n const { LAT, LON } = coord.raw;\n\n return {\n lat: LAT,\n lon: LON,\n };\n } catch (error) {\n logger\n .withContext({\n segments: JSON.stringify(segments),\n format: String(format),\n })\n .withError(error)\n .error('Failed to convert display to DD');\n return null;\n }\n}\n\n/**\n * Validate coordinate segments and return errors\n *\n * Uses @accelint/geo to validate the segments and returns any validation errors.\n * Only validates when all required segments are filled.\n *\n * @param segments - Array of segment values from user input\n * @param format - The coordinate system format\n * @returns Array of error messages, empty if valid or incomplete\n *\n * @example\n * const errors = validateCoordinateSegments(['91', '0', 'N', '0', '0', 'E'], 'ddm');\n * // Returns: ['Invalid coordinate value']\n */\nexport function validateCoordinateSegments(\n segments: string[],\n format: CoordinateSystem,\n): string[] {\n if (segments.some((seg) => seg === '' || seg === undefined)) {\n return [];\n }\n\n const coordString = formatSegmentsToCoordinateString(segments, format);\n if (!coordString) {\n return ['Invalid coordinate value'];\n }\n\n try {\n const create = createCoordinate(coordinateSystems[format], 'LATLON');\n const coord = create(coordString);\n\n if (!coord.valid) {\n return ['Invalid coordinate value'];\n }\n\n return [];\n } catch (_error) {\n return ['Invalid coordinate value'];\n }\n}\n\n/**\n * Check if all segments are filled\n *\n * Helper to determine if the user has completed entering all segment values.\n * Used to determine when to trigger validation.\n *\n * @param segments - Array of segment values\n * @returns True if all segments have values, false otherwise\n */\nexport function areAllSegmentsFilled(segments: string[]): boolean {\n return segments.every((seg) => seg !== '' && seg !== undefined);\n}\n\n/**\n * Check if any segments have values\n *\n * Helper to determine if the user has started entering coordinate values.\n *\n * @param segments - Array of segment values\n * @returns True if any segment has a value, false if all empty\n */\nexport function hasAnySegmentValue(segments: string[]): boolean {\n return segments.some((seg) => seg !== '' && seg !== undefined);\n}\n\n/**\n * Create an invalid result object for all coordinate systems\n * @internal\n */\nfunction createInvalidResult(): Record<\n CoordinateSystem,\n CoordinateFormatResult\n> {\n return {\n dd: { value: COORDINATE_ERROR_MESSAGES.INVALID, isValid: false },\n ddm: { value: COORDINATE_ERROR_MESSAGES.INVALID, isValid: false },\n dms: { value: COORDINATE_ERROR_MESSAGES.INVALID, isValid: false },\n mgrs: { value: COORDINATE_ERROR_MESSAGES.INVALID, isValid: false },\n utm: { value: COORDINATE_ERROR_MESSAGES.INVALID, isValid: false },\n };\n}\n\n/**\n * Validate coordinate value\n * @internal\n */\nfunction isValidCoordinateValue(value: CoordinateValue | null): boolean {\n return (\n value !== null &&\n typeof value.lat === 'number' &&\n typeof value.lon === 'number'\n );\n}\n\n/**\n * Check if error is due to geographic limitation (poles)\n * @internal\n */\nfunction isGeographicLimitationError(error: unknown): boolean {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return (\n errorMessage.includes('outside UTM limits') ||\n errorMessage.includes('invalid UTM zone')\n );\n}\n\n/**\n * Convert coordinate to a specific format with error handling\n * @internal\n */\nfunction convertToFormat(\n coord: {\n dd: () => string;\n ddm: () => string;\n dms: () => string;\n mgrs: () => string;\n utm: () => string;\n },\n format: CoordinateSystem,\n value: CoordinateValue,\n): CoordinateFormatResult {\n try {\n let formattedValue: string;\n switch (format) {\n case 'dd':\n formattedValue = coord.dd();\n break;\n case 'ddm':\n formattedValue = coord.ddm();\n break;\n case 'dms':\n formattedValue = coord.dms();\n break;\n case 'mgrs':\n formattedValue = coord.mgrs();\n break;\n case 'utm':\n formattedValue = coord.utm();\n break;\n default:\n return { value: COORDINATE_ERROR_MESSAGES.INVALID, isValid: false };\n }\n return { value: formattedValue, isValid: true };\n } catch (error) {\n // Handle geographic limitations for MGRS/UTM\n if (\n (format === 'mgrs' || format === 'utm') &&\n isGeographicLimitationError(error)\n ) {\n return {\n value: COORDINATE_ERROR_MESSAGES.NOT_AVAILABLE_AT_POLES,\n isValid: false,\n };\n }\n\n // Log other errors in development\n logger\n .withContext({\n value: JSON.stringify(value),\n })\n .withError(error)\n .error(`Failed to convert to ${format}`);\n return {\n value: COORDINATE_ERROR_MESSAGES.CONVERSION_FAILED,\n isValid: false,\n };\n }\n}\n\n/**\n * Get all coordinate formats for a given DD value\n *\n * Converts a Decimal Degrees coordinate to all 5 supported coordinate systems\n * for display in the format conversion popover.\n *\n * Each format is tried independently - if one fails (e.g., UTM/MGRS at poles),\n * the others can still succeed.\n *\n * @param value - Coordinate value in DD format `{ lat: number, lon: number }`\n * @returns Object containing formatted strings and validity status for all coordinate systems\n *\n * @example\n * const formats = getAllCoordinateFormats({ lat: 40.7128, lon: -74.0060 });\n * // Returns: {\n * // dd: { value: \"40.7128 N / 74.006 W\", isValid: true },\n * // ddm: { value: \"40 42.768 N / 74 0.36 W\", isValid: true },\n * // dms: { value: \"40 42 46.08 N / 74 0 21.6 W\", isValid: true },\n * // mgrs: { value: \"18T WL 80654 06346\", isValid: true },\n * // utm: { value: \"18N 585628 4511644\", isValid: true }\n * // }\n *\n * @example\n * const formats = getAllCoordinateFormats({ lat: 90, lon: 0 });\n * // Returns: {\n * // dd: { value: \"90 N / 0 E\", isValid: true },\n * // ddm: { value: \"90 0 N / 0 0 E\", isValid: true },\n * // dms: { value: \"90 0 0 N / 0 0 0 E\", isValid: true },\n * // mgrs: { value: \"Not available at poles\", isValid: false },\n * // utm: { value: \"Not available at poles\", isValid: false }\n * // }\n */\nexport function getAllCoordinateFormats(\n value: CoordinateValue | null,\n): Record<CoordinateSystem, CoordinateFormatResult> {\n const invalidResult = createInvalidResult();\n\n if (!isValidCoordinateValue(value)) {\n return invalidResult;\n }\n\n const validValue = value as CoordinateValue;\n\n try {\n const create = createCoordinate(coordinateSystems.dd, 'LATLON');\n const coord = create(`${validValue.lat} / ${validValue.lon}`);\n\n if (!coord.valid) {\n return invalidResult;\n }\n\n const result = {} as Record<CoordinateSystem, CoordinateFormatResult>;\n\n for (const format of COORDINATE_SYSTEMS) {\n result[format] = convertToFormat(coord, format, validValue);\n }\n\n return result;\n } catch (error) {\n logger\n .withContext({\n value: JSON.stringify(validValue),\n })\n .withError(error)\n .error('Failed to get all coordinate formats');\n return invalidResult;\n }\n}\n\n/**\n * Check if pasted text looks like a complete coordinate string\n *\n * Uses heuristics to detect if the pasted text contains a full coordinate\n * rather than just a single segment value. This prevents intercepting\n * single-segment pastes.\n *\n * Indicators of a complete coordinate:\n * - Contains separators: comma, slash, or multiple consecutive spaces\n * - Contains coordinate symbols: °, ′, ″, ', \"\n * - Multiple numbers separated by whitespace\n *\n * @param text - The pasted text to check\n * @returns True if it looks like a complete coordinate string\n *\n * @example\n * isCompleteCoordinate(\"40.7128, -74.0060\") // true - contains comma\n * isCompleteCoordinate(\"40° 42' 46\\\" N / 74° 0' 22\\\" W\") // true - contains symbols\n * isCompleteCoordinate(\"18T WM 12345 67890\") // true - multiple parts\n * isCompleteCoordinate(\"42\") // false - single number\n * isCompleteCoordinate(\"N\") // false - single letter\n */\nexport function isCompleteCoordinate(text: string): boolean {\n if (!text || text.trim() === '') {\n return false;\n }\n\n const hasSeparators = /[,/]|°|′|″|['\"]|\\s{2,}/.test(text);\n const numbers = text.match(/\\d+/g) || [];\n const hasMultipleNumbers = numbers.length >= 2;\n\n // Explicitly detect MGRS format: <zone><band> <grid> <easting> <northing>\n // Example: \"18T WL 80654 06346\"\n const isMGRS = /^\\d{1,2}[A-Z]\\s+[A-Z]{2}\\s+\\d+\\s+\\d+$/i.test(text.trim());\n\n // Explicitly detect UTM format: <zone><hemisphere> <easting> <northing>\n // Example: \"18N 585628 4511644\"\n const isUTM = /^\\d{1,2}[NS]\\s+\\d+\\s+\\d+$/i.test(text.trim());\n\n return hasSeparators || hasMultipleNumbers || isMGRS || isUTM;\n}\n\n/**\n * Attempt to parse pasted text as all coordinate formats\n *\n * Tries to parse the pasted text using each of the 5 coordinate system parsers.\n * Returns all formats that successfully parse the text.\n *\n * This enables automatic detection of coordinate format and disambiguation\n * when multiple formats match the same input string.\n *\n * @param pastedText - The raw text from clipboard\n * @returns Array of successfully parsed coordinate matches (may be empty)\n *\n * @example\n * const matches = parseCoordinatePaste(\"40.7128, -74.0060\");\n * // Returns: [{ format: 'dd', value: { lat: 40.7128, lon: -74.0060 }, displayString: \"...\" }]\n *\n * @example\n * const matches = parseCoordinatePaste(\"18T WM 12345 67890\");\n * // Returns: [{ format: 'mgrs', value: { lat: ..., lon: ... }, displayString: \"...\" }]\n *\n * @example\n * const matches = parseCoordinatePaste(\"invalid text\");\n * // Returns: []\n */\nexport function parseCoordinatePaste(\n pastedText: string,\n): ParsedCoordinateMatch[] {\n if (!pastedText || pastedText.trim() === '') {\n return [];\n }\n\n const matches: ParsedCoordinateMatch[] = [];\n\n for (const format of COORDINATE_SYSTEMS) {\n try {\n const create = createCoordinate(coordinateSystems[format], 'LATLON');\n const coord = create(pastedText.trim());\n\n if (coord.valid) {\n const { LAT, LON } = coord.raw;\n\n let displayString: string;\n switch (format) {\n case 'dd':\n displayString = coord.dd();\n break;\n case 'ddm':\n displayString = coord.ddm();\n break;\n case 'dms':\n displayString = coord.dms();\n break;\n case 'mgrs':\n displayString = coord.mgrs();\n break;\n case 'utm':\n displayString = coord.utm();\n break;\n default:\n displayString = '';\n }\n\n matches.push({\n format,\n value: { lat: LAT, lon: LON },\n displayString,\n });\n }\n } catch (error) {\n // Log parsing errors in development for debugging\n logger\n .withContext({\n pastedText: pastedText.trim(),\n format: String(format),\n })\n .withError(error)\n .warn(`Failed to parse as ${format}`);\n // Continue trying other parsers\n }\n }\n\n return matches;\n}\n\n/**\n * Check if two coordinates are equal within epsilon tolerance\n */\nexport function areCoordinatesEqual(\n coord1: { lat: number; lon: number },\n coord2: { lat: number; lon: number },\n epsilon = COORDINATE_EPSILON,\n): boolean {\n return (\n Math.abs(coord1.lat - coord2.lat) < epsilon &&\n Math.abs(coord1.lon - coord2.lon) < epsilon\n );\n}\n\n/**\n * Deduplicate coordinate matches by location, keeping first match for each unique location\n */\nexport function deduplicateMatchesByLocation(\n matches: ParsedCoordinateMatch[],\n): ParsedCoordinateMatch[] {\n const uniqueMatches: ParsedCoordinateMatch[] = [];\n\n for (const match of matches) {\n const isDuplicate = uniqueMatches.some((existing) =>\n areCoordinatesEqual(existing.value, match.value),\n );\n\n if (!isDuplicate) {\n uniqueMatches.push(match);\n }\n }\n\n return uniqueMatches;\n}\n"]}