@ixfx/components 0.13.3 → 0.13.4

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 (297) hide show
  1. package/bundle/index.d.ts +1449 -11
  2. package/bundle/index.js +1529 -45918
  3. package/bundle/rolldown-runtime-CEoa-xHZ.js +1 -0
  4. package/dist/ac-text.d.ts +2 -3
  5. package/dist/ac-text.js +0 -2
  6. package/dist/{ac-token-TCLAZeVg.d.ts → ac-token--_vCHXWw.d.ts} +2 -3
  7. package/dist/ac-token.d.ts +1 -1
  8. package/dist/ac-token.js +0 -2
  9. package/dist/button-B7mgqtxR.js +0 -2
  10. package/dist/{button-CTL45aBl.d.ts → button-BYuf72aR.d.ts} +2 -3
  11. package/dist/button.d.ts +1 -1
  12. package/dist/checkbox.d.ts +1 -2
  13. package/dist/checkbox.js +0 -2
  14. package/dist/checked-select-CglRukbP.d.ts +1 -2
  15. package/dist/checked-select-lDgAQQ7v.js +0 -2
  16. package/dist/colour-picker-BCMU7W7R.js +0 -2
  17. package/dist/colour-picker.d.ts +1 -1
  18. package/dist/crumbs.d.ts +2 -3
  19. package/dist/crumbs.js +1 -3
  20. package/dist/data-controller-DOlmqNKb.js +0 -2
  21. package/dist/data-display.d.ts +1 -2
  22. package/dist/data-display.js +0 -2
  23. package/dist/{data-grid-DHWJN66w.d.ts → data-grid-BtBZt8M1.d.ts} +5 -6
  24. package/dist/data-grid-FHr7wZ_k.js +2108 -0
  25. package/dist/data-grid.d.ts +1 -1
  26. package/dist/data-grid.js +1 -2013
  27. package/dist/data-provider-35TyWclX.js +0 -2
  28. package/dist/data-provider-BAn_-oR1.d.ts +1 -2
  29. package/dist/decorate-VRK8rslU.js +0 -2
  30. package/dist/defaults-B4ePs4LB.js +0 -2
  31. package/dist/{detail-list-C96B5Txz.js → detail-list-BfYHNh6B.js} +1 -3
  32. package/dist/{detail-list-dX7jLO6b.d.ts → detail-list-u2rWnAXQ.d.ts} +4 -5
  33. package/dist/detail-list.d.ts +2 -2
  34. package/dist/detail-list.js +1 -1
  35. package/dist/drag-ghost-DtSDvjri.js +0 -2
  36. package/dist/editable-label-rzXkjf1H.d.ts +1 -2
  37. package/dist/editable-label.js +0 -2
  38. package/dist/fallbacks-DQ_5OsmR.js +0 -2
  39. package/dist/{flat-list-Y98IqH00.d.ts → flat-list-DNnTQ65v.d.ts} +3 -4
  40. package/dist/flat-list.d.ts +1 -1
  41. package/dist/flat-list.js +0 -2
  42. package/dist/form-CsXJX15p.js +0 -2
  43. package/dist/form.d.ts +1 -2
  44. package/dist/{grid-list-CoT9e1jB.d.ts → grid-list-BLnV9oZE.d.ts} +2 -3
  45. package/dist/{grid-list-DeqAd9-h.js → grid-list-CkU8gHCh.js} +1 -3
  46. package/dist/grid-list.d.ts +1 -1
  47. package/dist/grid-list.js +1 -1
  48. package/dist/{grouped-item-lister-Bhyo-dkH.d.ts → grouped-item-lister-DETte0Dh.d.ts} +2 -3
  49. package/dist/grouped-item-lister.d.ts +1 -1
  50. package/dist/grouped-item-lister.js +0 -2
  51. package/dist/grouping-CUKgmkMm.d.ts +1 -2
  52. package/dist/grouping-RYPnHkrS.js +0 -2
  53. package/dist/handle-DAXs7kbJ.js +0 -2
  54. package/dist/hex-editor-Caq8vNQk.d.ts +1 -2
  55. package/dist/hex-editor-DiYpgIKs.js +0 -2
  56. package/dist/highlight-B-eQrhhb.js +0 -2
  57. package/dist/icon-1gpwtPx8.js +0 -2
  58. package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +2 -3
  59. package/dist/icons.d.ts +2 -2
  60. package/dist/icons.js +0 -2
  61. package/dist/incr-search-JIhwB49y.js +0 -2
  62. package/dist/incr-search.d.ts +1 -1
  63. package/dist/{index-Dq30pOnn.d.ts → index-B-hzcIP0.d.ts} +3 -4
  64. package/dist/{index-Dlah7Zfi.d.ts → index-BYIRgv49.d.ts} +2 -3
  65. package/dist/{index-CnQPCywE.d.ts → index-CCC0G1nO.d.ts} +2 -3
  66. package/dist/{index-garxxqgV.d.ts → index-CYndvTWH.d.ts} +2 -3
  67. package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +2 -3
  68. package/dist/index-DV3iaUBW.d.ts +1 -2
  69. package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +2 -3
  70. package/dist/index-o-CWDt11.d.ts +1 -2
  71. package/dist/{index-BOUaDIW-.d.ts → index-tq6f8007.d.ts} +2 -3
  72. package/dist/index.d.ts +21 -22
  73. package/dist/index.js +4 -6
  74. package/dist/item-appearance-BjcMyauw.js +0 -2
  75. package/dist/keyboard-B5xD7Fz-.js +0 -2
  76. package/dist/labelled-input-base-BFa4xlYV.js +0 -2
  77. package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +2 -3
  78. package/dist/labelled-radial-input.d.ts +3 -4
  79. package/dist/labelled-radial-input.js +0 -2
  80. package/dist/labelled-range-input.d.ts +1 -1
  81. package/dist/labelled-range-input.js +0 -2
  82. package/dist/labelled-slider-input-FdCRi6st.js +0 -2
  83. package/dist/labelled-slider-input.d.ts +1 -1
  84. package/dist/led.d.ts +1 -2
  85. package/dist/led.js +0 -2
  86. package/dist/list-group-header.d.ts +2 -3
  87. package/dist/list-group-header.js +0 -2
  88. package/dist/list-item-animation-BUoEKi5s.js +0 -2
  89. package/dist/list-native-drag-controller-B9xO0XWn.js +0 -2
  90. package/dist/list-native-drag-controller-ChIi3eK5.d.ts +1 -2
  91. package/dist/list-selection-controller-BeE70lbB.js +0 -2
  92. package/dist/list-selection-types-PjKdhF-a.d.ts +1 -2
  93. package/dist/list-viewport-types-BRZsLcvp.d.ts +1 -2
  94. package/dist/menu-CwcXXeLM.js +0 -2
  95. package/dist/menu-item-BDEekBVy.js +0 -2
  96. package/dist/{menu-item-B0zqw2xp.d.ts → menu-item-bF6narIz.d.ts} +2 -3
  97. package/dist/menu.d.ts +2 -2
  98. package/dist/miller.d.ts +2 -3
  99. package/dist/miller.js +0 -2
  100. package/dist/narrowed-text.js +0 -2
  101. package/dist/notification-pill-DyZydXoZ.d.ts +1 -2
  102. package/dist/notifier.js +0 -2
  103. package/dist/pan-text-CoYmt2qd.d.ts +1 -2
  104. package/dist/pan-text-CqtvjPyK.js +0 -2
  105. package/dist/panel.d.ts +2 -3
  106. package/dist/panel.js +0 -2
  107. package/dist/polar-pad.d.ts +1 -2
  108. package/dist/polar-pad.js +0 -2
  109. package/dist/popup-D80sj2QC.js +0 -2
  110. package/dist/prominence-DlFShic3.js +0 -2
  111. package/dist/radial-input-DU6t2hYO.d.ts +1 -2
  112. package/dist/radial-input-KMVltQfe.js +0 -2
  113. package/dist/range-input.d.ts +1 -2
  114. package/dist/range-input.js +0 -2
  115. package/dist/range.d.ts +1 -2
  116. package/dist/range.js +0 -2
  117. package/dist/registry-BEtb8_wB.js +0 -2
  118. package/dist/{scroll-fade-BrNUIYnm.js → scroll-fade-Xx28D7mH.js} +11 -7
  119. package/dist/select-horiz.d.ts +1 -2
  120. package/dist/select-horiz.js +1 -3
  121. package/dist/slider-input-BxURAAmD.d.ts +1 -2
  122. package/dist/slider-input-ByHdotzp.js +0 -2
  123. package/dist/snackbar.d.ts +1 -2
  124. package/dist/snackbar.js +0 -2
  125. package/dist/snap-container.d.ts +1 -2
  126. package/dist/snap-container.js +0 -2
  127. package/dist/split-layout-Deoxy47d.js +0 -2
  128. package/dist/{split-layout-C5SYbDrq.d.ts → split-layout-JK3xWVX2.d.ts} +2 -3
  129. package/dist/split-layout.d.ts +1 -1
  130. package/dist/swipe.d.ts +1 -2
  131. package/dist/swipe.js +0 -2
  132. package/dist/{tab-list-D_dmImJM.d.ts → tab-list-CexFFg6O.d.ts} +2 -3
  133. package/dist/tabs.d.ts +1 -1
  134. package/dist/tabs.js +1 -3
  135. package/dist/tickled-controller-D-HZymaZ.js +0 -2
  136. package/dist/tickled-controller-DodxD3eQ.d.ts +1 -2
  137. package/dist/tickled-styles-BrAHEj1q.js +0 -2
  138. package/dist/timeline-BP1Ux2EV.js +0 -2
  139. package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +2 -3
  140. package/dist/titlebar.d.ts +1 -1
  141. package/dist/titlebar.js +0 -2
  142. package/dist/tooltip-BlvBUQxx.d.ts +1 -2
  143. package/dist/tooltip-CJt3WLmN.js +0 -2
  144. package/dist/transitory-label.d.ts +1 -2
  145. package/dist/transitory-label.js +0 -2
  146. package/dist/tree-DD8OaqsK.js +0 -2
  147. package/dist/tree-component-Cj8V3uar.d.ts +1 -2
  148. package/dist/tree.d.ts +1 -1
  149. package/dist/types-DQ7KOUIj.d.ts +1 -2
  150. package/dist/{vertical-list-lj_19DCx.d.ts → vertical-list-m7GJtXwv.d.ts} +2 -3
  151. package/dist/vertical-list.d.ts +1 -1
  152. package/dist/vertical-list.js +1 -3
  153. package/dist/wheel-nudge-By5s_ioH.d.ts +1 -2
  154. package/dist/wheel-nudge-D5rmht3v.js +0 -2
  155. package/dist/xy-axis-CyMd_Bn1.js +0 -2
  156. package/dist/xy-axis-DQqd2yXJ.d.ts +1 -2
  157. package/dist/xy-pad.d.ts +1 -2
  158. package/dist/xy-pad.js +0 -2
  159. package/docs-user/index.json +2 -2
  160. package/package.json +1 -1
  161. package/bundle/index.d.ts.map +0 -1
  162. package/bundle/index.js.map +0 -1
  163. package/bundle/rolldown-runtime-D7D4PA-g.js +0 -13
  164. package/dist/ac-text.d.ts.map +0 -1
  165. package/dist/ac-text.js.map +0 -1
  166. package/dist/ac-token-TCLAZeVg.d.ts.map +0 -1
  167. package/dist/ac-token.js.map +0 -1
  168. package/dist/button-B7mgqtxR.js.map +0 -1
  169. package/dist/button-CTL45aBl.d.ts.map +0 -1
  170. package/dist/checkbox.d.ts.map +0 -1
  171. package/dist/checkbox.js.map +0 -1
  172. package/dist/checked-select-CglRukbP.d.ts.map +0 -1
  173. package/dist/checked-select-lDgAQQ7v.js.map +0 -1
  174. package/dist/colour-picker-BCMU7W7R.js.map +0 -1
  175. package/dist/crumbs.d.ts.map +0 -1
  176. package/dist/crumbs.js.map +0 -1
  177. package/dist/data-controller-DOlmqNKb.js.map +0 -1
  178. package/dist/data-display.d.ts.map +0 -1
  179. package/dist/data-display.js.map +0 -1
  180. package/dist/data-grid-DHWJN66w.d.ts.map +0 -1
  181. package/dist/data-grid.js.map +0 -1
  182. package/dist/data-provider-35TyWclX.js.map +0 -1
  183. package/dist/data-provider-BAn_-oR1.d.ts.map +0 -1
  184. package/dist/decorate-VRK8rslU.js.map +0 -1
  185. package/dist/defaults-B4ePs4LB.js.map +0 -1
  186. package/dist/detail-list-C96B5Txz.js.map +0 -1
  187. package/dist/detail-list-dX7jLO6b.d.ts.map +0 -1
  188. package/dist/drag-ghost-DtSDvjri.js.map +0 -1
  189. package/dist/editable-label-rzXkjf1H.d.ts.map +0 -1
  190. package/dist/editable-label.js.map +0 -1
  191. package/dist/fallbacks-DQ_5OsmR.js.map +0 -1
  192. package/dist/flat-list-Y98IqH00.d.ts.map +0 -1
  193. package/dist/flat-list.js.map +0 -1
  194. package/dist/form-CsXJX15p.js.map +0 -1
  195. package/dist/form.d.ts.map +0 -1
  196. package/dist/grid-list-CoT9e1jB.d.ts.map +0 -1
  197. package/dist/grid-list-DeqAd9-h.js.map +0 -1
  198. package/dist/grouped-item-lister-Bhyo-dkH.d.ts.map +0 -1
  199. package/dist/grouped-item-lister.js.map +0 -1
  200. package/dist/grouping-CUKgmkMm.d.ts.map +0 -1
  201. package/dist/grouping-RYPnHkrS.js.map +0 -1
  202. package/dist/handle-DAXs7kbJ.js.map +0 -1
  203. package/dist/hex-editor-Caq8vNQk.d.ts.map +0 -1
  204. package/dist/hex-editor-DiYpgIKs.js.map +0 -1
  205. package/dist/highlight-B-eQrhhb.js.map +0 -1
  206. package/dist/icon-1gpwtPx8.js.map +0 -1
  207. package/dist/icon-DR_3rSyZ.d.ts.map +0 -1
  208. package/dist/icons.js.map +0 -1
  209. package/dist/incr-search-JIhwB49y.js.map +0 -1
  210. package/dist/index-BOUaDIW-.d.ts.map +0 -1
  211. package/dist/index-BUB5SICW.d.ts.map +0 -1
  212. package/dist/index-CJ5fshD3.d.ts.map +0 -1
  213. package/dist/index-CnQPCywE.d.ts.map +0 -1
  214. package/dist/index-DV3iaUBW.d.ts.map +0 -1
  215. package/dist/index-Dlah7Zfi.d.ts.map +0 -1
  216. package/dist/index-Dq30pOnn.d.ts.map +0 -1
  217. package/dist/index-garxxqgV.d.ts.map +0 -1
  218. package/dist/index-o-CWDt11.d.ts.map +0 -1
  219. package/dist/index.d.ts.map +0 -1
  220. package/dist/index.js.map +0 -1
  221. package/dist/item-appearance-BjcMyauw.js.map +0 -1
  222. package/dist/keyboard-B5xD7Fz-.js.map +0 -1
  223. package/dist/labelled-input-base-BFa4xlYV.js.map +0 -1
  224. package/dist/labelled-input-base-Dp_9KP0G.d.ts.map +0 -1
  225. package/dist/labelled-radial-input.d.ts.map +0 -1
  226. package/dist/labelled-radial-input.js.map +0 -1
  227. package/dist/labelled-range-input.js.map +0 -1
  228. package/dist/labelled-slider-input-FdCRi6st.js.map +0 -1
  229. package/dist/led.d.ts.map +0 -1
  230. package/dist/led.js.map +0 -1
  231. package/dist/list-group-header.d.ts.map +0 -1
  232. package/dist/list-group-header.js.map +0 -1
  233. package/dist/list-item-animation-BUoEKi5s.js.map +0 -1
  234. package/dist/list-native-drag-controller-B9xO0XWn.js.map +0 -1
  235. package/dist/list-native-drag-controller-ChIi3eK5.d.ts.map +0 -1
  236. package/dist/list-selection-controller-BeE70lbB.js.map +0 -1
  237. package/dist/list-selection-types-PjKdhF-a.d.ts.map +0 -1
  238. package/dist/list-viewport-types-BRZsLcvp.d.ts.map +0 -1
  239. package/dist/menu-CwcXXeLM.js.map +0 -1
  240. package/dist/menu-item-B0zqw2xp.d.ts.map +0 -1
  241. package/dist/menu-item-BDEekBVy.js.map +0 -1
  242. package/dist/miller.d.ts.map +0 -1
  243. package/dist/miller.js.map +0 -1
  244. package/dist/narrowed-text.js.map +0 -1
  245. package/dist/notification-pill-DyZydXoZ.d.ts.map +0 -1
  246. package/dist/notifier.js.map +0 -1
  247. package/dist/pan-text-CoYmt2qd.d.ts.map +0 -1
  248. package/dist/pan-text-CqtvjPyK.js.map +0 -1
  249. package/dist/panel.d.ts.map +0 -1
  250. package/dist/panel.js.map +0 -1
  251. package/dist/polar-pad.d.ts.map +0 -1
  252. package/dist/polar-pad.js.map +0 -1
  253. package/dist/popup-D80sj2QC.js.map +0 -1
  254. package/dist/prominence-DlFShic3.js.map +0 -1
  255. package/dist/radial-input-DU6t2hYO.d.ts.map +0 -1
  256. package/dist/radial-input-KMVltQfe.js.map +0 -1
  257. package/dist/range-input.d.ts.map +0 -1
  258. package/dist/range-input.js.map +0 -1
  259. package/dist/range.d.ts.map +0 -1
  260. package/dist/range.js.map +0 -1
  261. package/dist/registry-BEtb8_wB.js.map +0 -1
  262. package/dist/scroll-fade-BrNUIYnm.js.map +0 -1
  263. package/dist/select-horiz.d.ts.map +0 -1
  264. package/dist/select-horiz.js.map +0 -1
  265. package/dist/slider-input-BxURAAmD.d.ts.map +0 -1
  266. package/dist/slider-input-ByHdotzp.js.map +0 -1
  267. package/dist/snackbar.d.ts.map +0 -1
  268. package/dist/snackbar.js.map +0 -1
  269. package/dist/snap-container.d.ts.map +0 -1
  270. package/dist/snap-container.js.map +0 -1
  271. package/dist/split-layout-C5SYbDrq.d.ts.map +0 -1
  272. package/dist/split-layout-Deoxy47d.js.map +0 -1
  273. package/dist/swipe.d.ts.map +0 -1
  274. package/dist/swipe.js.map +0 -1
  275. package/dist/tab-list-D_dmImJM.d.ts.map +0 -1
  276. package/dist/tabs.js.map +0 -1
  277. package/dist/tickled-controller-D-HZymaZ.js.map +0 -1
  278. package/dist/tickled-controller-DodxD3eQ.d.ts.map +0 -1
  279. package/dist/tickled-styles-BrAHEj1q.js.map +0 -1
  280. package/dist/timeline-BP1Ux2EV.js.map +0 -1
  281. package/dist/titlebar-B5zSTZnF.d.ts.map +0 -1
  282. package/dist/titlebar.js.map +0 -1
  283. package/dist/tooltip-BlvBUQxx.d.ts.map +0 -1
  284. package/dist/tooltip-CJt3WLmN.js.map +0 -1
  285. package/dist/transitory-label.d.ts.map +0 -1
  286. package/dist/transitory-label.js.map +0 -1
  287. package/dist/tree-DD8OaqsK.js.map +0 -1
  288. package/dist/tree-component-Cj8V3uar.d.ts.map +0 -1
  289. package/dist/types-DQ7KOUIj.d.ts.map +0 -1
  290. package/dist/vertical-list-lj_19DCx.d.ts.map +0 -1
  291. package/dist/vertical-list.js.map +0 -1
  292. package/dist/wheel-nudge-By5s_ioH.d.ts.map +0 -1
  293. package/dist/wheel-nudge-D5rmht3v.js.map +0 -1
  294. package/dist/xy-axis-CyMd_Bn1.js.map +0 -1
  295. package/dist/xy-axis-DQqd2yXJ.d.ts.map +0 -1
  296. package/dist/xy-pad.d.ts.map +0 -1
  297. package/dist/xy-pad.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"notification-pill-DyZydXoZ.d.ts","names":[],"sources":["../src/notifier/types.ts","../src/notifier/notification-pill.ts"],"mappings":";;KAAY;KAEA;WACD,MAAM;WACN;WACA;WACA,SAAS;;KAGR,eAAe;WAChB;WACA;WACA;;UAGM;EACf,QAAQ;;UAGO;;EAEf,SAAS,OAAO;;EAEhB;;;;;;EAMA,mBAAmB,eAAe,gBAAgB;;KAGxC;EACV,WAAW;EACX;EACA;EACA;EACA;EACA;EACA,qBAAqB,cAAc;;;;KC9BzB;WAA2B;;KAC3B,eAAe,YAAY;UAEtB;EACf,YAAY;;cAID,gCAAgC;;EAE3C,kBAAkB;EAGlB;EAGA;EAGA;EAGA;YAqCU,wBAAM;SAgBT,sBAAM;;QA6EP;YACI;IACR,0BAA0B;;;UAIb;EACf,oBAAoB,gBAAgB,iCAClC,MAAM,GACN,WAAW,MAAM,yBAAyB,OAAO,gCAAgC,aACjF,oBAAoB,sCAEpB,cACA,UAAU,oCACV,oBAAoB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"notifier.js","names":["#emitTap","#handleClick","#handleKeyDown","#renderIcon","customElement"],"sources":["../src/notifier/notification-pill.ts"],"sourcesContent":["/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { NotificationType } from \"./types.js\";\nimport { css, html, LitElement, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\nimport { hasIcon } from \"../icons/index.js\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\n\nexport type PillTapDetail = { readonly id: string };\nexport type PillTapEvent = CustomEvent<PillTapDetail>;\n\nexport interface NotificationPillElementEventMap {\n 'pill-tap': PillTapEvent;\n}\n\n@customElement(`ixfx-notification-pill`)\nexport class NotificationPillElement extends LitElement {\n @property({ type: String, attribute: `notification-type` })\n notificationType: NotificationType = `info`;\n\n @property({ type: String })\n message = ``;\n\n @property({ type: String })\n icon?: string;\n\n @property({ type: Boolean, reflect: true })\n dismissing = false;\n\n @property({ type: String, attribute: `notification-id` })\n notificationId = ``;\n\n #handleClick(): void {\n this.#emitTap();\n }\n\n #handleKeyDown(e: KeyboardEvent): void {\n if (e.key === `Enter` || e.key === ` `) {\n e.preventDefault();\n this.#emitTap();\n }\n }\n\n #emitTap(): void {\n this.dispatchEvent(\n new CustomEvent<PillTapDetail>(`pill-tap`, {\n detail: { id: this.notificationId },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n #renderIcon() {\n if (!this.icon)\n return nothing;\n\n if (this.icon.startsWith(`<svg`)) {\n return html`<span class=\"pill-icon\">${unsafeHTML(this.icon)}</span>`;\n }\n\n if (!hasIcon(this.icon))\n return nothing;\n\n return html`<ixfx-icon class=\"pill-icon\" name=\"${this.icon}\"></ixfx-icon>`;\n }\n\n protected render() {\n return html`\n <button\n type=\"button\"\n class=\"pill\"\n notification-type=\"${this.notificationType}\"\n @click=${this.#handleClick}\n @keydown=${this.#handleKeyDown}\n aria-label=\"${this.message}\"\n >\n ${this.#renderIcon()}\n <span class=\"pill-message\">${this.message}</span>\n </button>\n `;\n }\n\n static styles = [\n themeFallbacks,\n css`\n :host {\n display: block;\n }\n\n .pill {\n appearance: none;\n cursor: pointer;\n font-family: var(--font-family, inherit);\n font-size: var(--text-m, 12px);\n padding: var(--space-s, 4px) var(--space-m, 8px);\n border-radius: var(--radius-l, 6px);\n border: 1px solid var(--surface-6, #666);\n display: inline-flex;\n align-items: center;\n gap: var(--space-s, 4px);\n max-width: 300px;\n box-shadow: var(--shadow-m);\n transition: opacity 0.2s ease-out, transform 0.2s ease-out;\n pointer-events: auto;\n }\n\n :host([dismissing]) .pill {\n opacity: 0;\n transform: translateX(20px);\n }\n\n .pill[notification-type=\"info\"] {\n background: var(--surface-5, #555);\n color: var(--surface-5-text, #fff);\n }\n\n .pill[notification-type=\"warning\"] {\n background: color-mix(in oklch, oklch(65% 0.18 70) 30%, var(--surface-5));\n border-color: oklch(65% 0.18 70);\n color: var(--surface-5-text, #fff);\n }\n\n .pill[notification-type=\"error\"] {\n background: var(--error, #c00);\n border-color: var(--error, #c00);\n color: var(--error-text, #fff);\n }\n\n .pill-icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n .pill-icon ixfx-icon {\n font-size: var(--text-m, 12px);\n }\n\n .pill-message {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .pill:focus-visible {\n outline: 2px solid var(--accent, #4a9);\n outline-offset: 2px;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .pill {\n transition: opacity 0.1s ease-out;\n transform: none !important;\n }\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-notification-pill': NotificationPillElement;\n }\n}\n\nexport interface NotificationPillElement {\n addEventListener: (<K extends keyof NotificationPillElementEventMap>(\n type: K,\n listener: (this: NotificationPillElement, event: NotificationPillElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n"],"mappings":";;;;;;;;AAiBO,IAAM,0BAAN,MAAM,gCAAgC,WAAW;;;EAEjB,KAAA,mBAAA;EAG3B,KAAA,UAAA;EAMG,KAAA,aAAA;EAGI,KAAA,iBAAA;;CAEjB,eAAqB;EACnB,KAAKA,SAAS;CAChB;CAEA,eAAe,GAAwB;EACrC,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;GACtC,EAAE,eAAe;GACjB,KAAKA,SAAS;EAChB;CACF;CAEA,WAAiB;EACf,KAAK,cACH,IAAI,YAA2B,YAAY;GACzC,QAAQ,EAAE,IAAI,KAAK,eAAe;GAClC,SAAS;GACT,UAAU;EACZ,CAAC,CACH;CACF;CAEA,cAAc;EACZ,IAAI,CAAC,KAAK,MACR,OAAO;EAET,IAAI,KAAK,KAAK,WAAW,MAAM,GAC7B,OAAO,IAAI,2BAA2B,WAAW,KAAK,IAAI,EAAE;EAG9D,IAAI,CAAC,QAAQ,KAAK,IAAI,GACpB,OAAO;EAET,OAAO,IAAI,sCAAsC,KAAK,KAAK;CAC7D;CAEA,SAAmB;EACjB,OAAO,IAAI;;;;6BAIc,KAAK,iBAAiB;iBAClC,KAAKC,aAAa;mBAChB,KAAKC,eAAe;sBACjB,KAAK,QAAQ;;UAEzB,KAAKC,YAAY,EAAE;qCACQ,KAAK,QAAQ;;;CAGhD;;EAEgB,KAAA,SAAA,CACd,gBACA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAwEL;;AACF;AA7IG,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAoB,CAAC,CAAA,GAAA,wBAAA,WAAA,oBAAA,KAAA,CAAA;AAGzD,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,wBAAA,WAAA,WAAA,KAAA,CAAA;AAGzB,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,wBAAA,WAAA,QAAA,KAAA,CAAA;AAGzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,wBAAA,WAAA,cAAA,KAAA,CAAA;AAGzC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAkB,CAAC,CAAA,GAAA,wBAAA,WAAA,kBAAA,KAAA,CAAA;AAdzDC,0BAAAA,WAAAA,CAAAA,kBAAc,wBAAwB,CAAA,GAAA,uBAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pan-text-CoYmt2qd.d.ts","names":[],"sources":["../src/pan-text/pan-text.ts"],"mappings":";;KAeY;cAGC,uBAAuB;EACkB;EACA;;;;;;;EAOU,MAAM;UAEnD;UACA;UACA;UACA;UAEO;UAEhB;UACA;UACA;EAEC;EAOA;EAYA;YASU,QAAQ,SAAS;;;;MAehC;;;;;;EASJ;;;;EAcA;UASQ;UAIA;UAIA;UAOA;UAoBA;UAIA;;;;;;;;;;UAaA;UAwBA;YAiDW,wBAAM;SAaT,sBAAM;;QAmChB;YACI;IACR,iBAAiB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pan-text-CqtvjPyK.js","names":["customElement"],"sources":["../src/pan-text/pan-text.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\nimport { css, html, LitElement } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nconst SPEED = 45; // px per second\nconst END_PADDING = 4;\nconst START_DELAY = 300; // ms to wait on hover before panning begins\nconst END_DWELL = 2000; // ms to dwell at the end of the text in loop mode\nconst RESET_DURATION = 400; // ms to snap back to the start in loop mode\n// Decelerating curve: moves off fast then eases into the reveal (~easeOutQuad).\nconst PAN_EASING = `cubic-bezier(0.25, 0.46, 0.45, 0.94)`;\n\nexport type PanTextMode = `hover` | `loop`;\n\n@customElement(`ixfx-pan-text`)\nexport class PanTextElement extends LitElement {\n @property({ type: String, attribute: `direction` }) direction: `start` | `end` = `end`;\n @property({ type: Boolean, attribute: `disabled` }) disabled = false;\n /**\n * Interaction mode.\n * - `hover` (default): pans once while hovered.\n * - `loop`: pans repeatedly — dwell 2s at the end, reset to the start,\n * and pan again — until `stopLoop()` is called. Auto-starts when set.\n */\n @property({ type: String, attribute: `mode`, reflect: true }) mode: PanTextMode = `hover`;\n\n @state() private _isOverflowing = false;\n @state() private _isHovering = false;\n @state() private _loopActive = false;\n @state() private _loopAtEnd = false;\n\n @query(`.text`) private _textEl!: HTMLElement | null;\n\n private _overflow = 0;\n private _resizeObserver: ResizeObserver | null = null;\n private _loopTimer = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._resizeObserver = new ResizeObserver(() => this._measure());\n this.addEventListener(`mouseenter`, this._onMouseEnter);\n this.addEventListener(`mouseleave`, this._onMouseLeave);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._clearLoopTimer();\n // Reset without requesting an update — the element is leaving the DOM.\n this._loopActive = false;\n this._loopAtEnd = false;\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n this.removeEventListener(`mouseenter`, this._onMouseEnter);\n this.removeEventListener(`mouseleave`, this._onMouseLeave);\n }\n\n override firstUpdated(): void {\n this._measure();\n this._resizeObserver?.observe(this);\n // Text metrics change once web fonts load; re-check when they settle.\n document.fonts?.ready.then(() => this._measure());\n if (this.mode === `loop`)\n this.startLoop();\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n if (changed.has(`mode`)) {\n if (this.mode === `loop`)\n this.startLoop();\n else\n this.stopLoop();\n }\n if (changed.has(`disabled`) && this.disabled)\n this.stopLoop();\n this._measure();\n }\n\n /**\n * Whether a loop pan is currently active (between `startLoop()` and `stopLoop()`).\n */\n get looping(): boolean {\n return this._loopActive;\n }\n\n /**\n * Begin looping: pan to the end, dwell there for 2 seconds, reset to the\n * start and pan again, repeating until `stopLoop()` is called. A no-op when\n * `disabled`, when there is nothing to reveal, or under reduced-motion.\n */\n startLoop(): void {\n if (this.disabled || this._prefersReducedMotion())\n return;\n this._loopActive = true;\n this._loopAtEnd = false;\n this.requestUpdate();\n if (this._isOverflowing && this._loopTimer === 0)\n this._scheduleLoopPan(START_DELAY);\n // Otherwise `_measure()` picks it up once overflow is known.\n }\n\n /**\n * Stop a loop started with `startLoop()` and snap back to the rest position.\n */\n stopLoop(): void {\n if (!this._loopActive && !this._loopAtEnd && this._loopTimer === 0)\n return;\n this._clearLoopTimer();\n this._loopActive = false;\n this._loopAtEnd = false;\n this.requestUpdate();\n }\n\n private _prefersReducedMotion(): boolean {\n return globalThis.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches ?? false;\n }\n\n private _panDuration(): number {\n return Math.max(1.5, (this._overflow + END_PADDING) / SPEED);\n }\n\n private _clearLoopTimer(): void {\n if (this._loopTimer !== 0) {\n clearTimeout(this._loopTimer);\n this._loopTimer = 0;\n }\n }\n\n private _scheduleLoopPan(delay: number): void {\n this._clearLoopTimer();\n this._loopTimer = window.setTimeout(() => {\n this._loopTimer = 0;\n if (!this._loopActive || this.disabled || !this._isOverflowing)\n return;\n this._loopAtEnd = true;\n this.requestUpdate();\n const dwell = this._panDuration() * 1000 + END_DWELL;\n this._loopTimer = window.setTimeout(() => {\n this._loopTimer = 0;\n if (!this._loopActive)\n return;\n this._loopAtEnd = false;\n this.requestUpdate();\n this._scheduleLoopPan(RESET_DURATION + START_DELAY);\n }, dwell);\n }, delay);\n }\n\n private _onMouseEnter = (): void => {\n this._isHovering = true;\n };\n\n private _onMouseLeave = (): void => {\n this._isHovering = false;\n };\n\n /**\n * Measures how far the slotted text overflows its container. The measurement\n * is taken on the inner `.text` span (which clips with an ellipsis), not on\n * the host — the host never overflows, so measuring it always yielded zero\n * and the hover interaction never activated.\n *\n * Skipped while hovering, because the hover styles switch `.text` to\n * `overflow: visible` and the measurement would collapse to zero mid-pan.\n */\n private _measure = (): void => {\n if (this._isHovering || this._loopAtEnd)\n return;\n const el = this._textEl;\n if (!el)\n return;\n\n this._overflow = Math.max(0, el.scrollWidth - el.clientWidth);\n const overflowing = this._overflow > 0;\n\n this.classList.toggle(`is-overflowing`, overflowing);\n if (overflowing !== this._isOverflowing) {\n this._isOverflowing = overflowing;\n }\n // A loop requested before overflow was known (fonts, resize, late slot)\n // starts here once there is something to reveal.\n if (this._loopActive && this.mode === `loop` && !this.disabled && overflowing && this._loopTimer === 0)\n this._scheduleLoopPan(START_DELAY);\n if (!overflowing && this._loopAtEnd) {\n this._loopAtEnd = false;\n this.requestUpdate();\n }\n };\n\n private _textStyle(): string {\n if (!this._isOverflowing)\n return ``;\n\n const distance = this._overflow + END_PADDING;\n const duration = Math.max(1.5, distance / SPEED);\n const revealEnd = this.direction === `end`;\n\n // \"end\": rest shows the start of the text, hover pans left to the end.\n // \"start\": rest shows the end of the text, hover pans right to the start.\n const restX = revealEnd ? 0 : -distance;\n const hoverX = revealEnd ? -distance : 0;\n\n // Loop mode drives the same transform off a timer instead of hover. The\n // dwell/reset delays live in the timeout chain, so the transition itself\n // carries no extra delay.\n if (this._loopActive && this.mode === `loop`) {\n if (this._loopAtEnd) {\n return [\n `transform: translateX(${hoverX}px)`,\n `transition: transform ${duration}s ${PAN_EASING}`,\n `overflow: visible`,\n `text-overflow: clip`,\n ].join(`; `);\n }\n return [\n `transform: translateX(${restX}px)`,\n `transition: transform ${RESET_DURATION}ms ${PAN_EASING}`,\n revealEnd ? `` : `overflow: visible; text-overflow: clip`,\n ].filter(Boolean).join(`; `);\n }\n\n if (this._isHovering) {\n return [\n `transform: translateX(${hoverX}px)`,\n `transition: transform ${duration}s ${PAN_EASING} ${START_DELAY}ms`,\n `overflow: visible`,\n `text-overflow: clip`,\n ].join(`; `);\n }\n\n return [\n `transform: translateX(${restX}px)`,\n `transition: transform 400ms ${PAN_EASING}`,\n // \"start\" mode keeps the tail visible at rest, so it can't clip/ellipsis.\n revealEnd ? `` : `overflow: visible; text-overflow: clip`,\n ].filter(Boolean).join(`; `);\n }\n\n protected override render() {\n const textClasses = {\n 'is-overflowing': this._isOverflowing,\n 'is-hovering': this._isHovering,\n };\n\n return html`\n <span class=\"text ${classMap(textClasses)}\" part=\"text\" style=${this._textStyle()}>\n <slot @slotchange=${this._measure}></slot>\n </span>\n `;\n }\n\n static override styles = [themeFallbacks, css`\n /* Renders like plain inline text: no colours, border, padding or margin\n of its own — it only adds the clipping needed to pan on hover. */\n :host {\n display: inline-block;\n overflow: hidden;\n white-space: nowrap;\n max-width: 100%;\n box-sizing: border-box;\n font: inherit;\n color: inherit;\n }\n\n :host([disabled]) {\n opacity: var(--disabled-opacity, 0.5);\n pointer-events: none;\n }\n\n .text {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n will-change: transform;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .text {\n transition: none !important;\n transform: none !important;\n }\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-pan-text': PanTextElement;\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"panel.d.ts","names":[],"sources":["../src/panel/panel.ts"],"mappings":";;;;KAgBY,mBAAmB;KACnB,eAAe;KACf,yBAAyB;KACzB,oBAAoB;KACpB,mBAAmB;KACnB,kBAAkB;UAEb;EACf,QAAQ;EACR,OAAO;;cAII,qBAAqB;EACY;EACyB,aAAa;EACrD;;EAEe;EAChB;EACwB;EACS,mBAAmB;EACf,SAAS;;EAEjB;;EAED;UAEhD;UAYA;YAWW,wBAAM;SA8BT,sBAAM;;QAmHhB;YACI;IACR,cAAc;;;UAID;EACf,oBAAoB,gBAAgB,sBAClC,MAAM,GACN,WAAW,MAAM,cAAc,OAAO,qBAAqB,aAC3D,oBAAoB,sCAEpB,cACA,UAAU,oCACV,oBAAoB"}
package/dist/panel.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"panel.js","names":["customElement"],"sources":["../src/panel/panel.ts"],"sourcesContent":["/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type {\n TitlebarCloseEvent,\n TitlebarOrientation,\n TitlebarToggleDetail,\n TitlebarToggleEvent,\n TitlebarToggleInteraction,\n TitlebarVariant,\n} from '../titlebar/titlebar.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../titlebar/titlebar.js';\n\n/** Backwards-compatible aliases: canonical types now live in `../titlebar/titlebar.js`. */\nexport type PanelOrientation = TitlebarOrientation;\nexport type PanelVariant = TitlebarVariant;\nexport type PanelToggleInteraction = TitlebarToggleInteraction;\nexport type PanelToggleDetail = TitlebarToggleDetail;\nexport type PanelToggleEvent = TitlebarToggleEvent;\nexport type PanelCloseEvent = TitlebarCloseEvent;\n\nexport interface PanelElementEventMap {\n toggle: PanelToggleEvent;\n close: PanelCloseEvent;\n}\n\n@customElement(`ixfx-panel`)\nexport class PanelElement extends LitElement {\n @property({ type: Boolean, reflect: true }) collapsed = false;\n @property({ type: String, attribute: `orientation`, reflect: true }) orientation: PanelOrientation = `horizontal`;\n @property({ type: Boolean }) closable = false;\n /** Show the collapse/expand caret and enable toggle behaviour. Defaults to true so existing panels stay collapsible. */\n @property({ type: Boolean, reflect: true }) collapsible = true;\n @property({ type: String }) title = ``;\n @property({ type: String, attribute: `icon-name` }) iconName = ``;\n @property({ type: String, attribute: `toggle-interaction` }) toggleInteraction: PanelToggleInteraction = `implicit`;\n @property({ type: String, attribute: `variant`, reflect: true }) variant: PanelVariant = `titlebar`;\n /** Suppress the titlebar entirely (content-only chrome, e.g. dock tabbed mode). */\n @property({ type: Boolean, attribute: `hide-titlebar` }) hideTitlebar = false;\n /** Keep the toolbar visible even when the panel is collapsed. */\n @property({ type: Boolean, attribute: `keep-toolbar` }) keepToolbar = false;\n\n private _onTitlebarToggle(event: TitlebarToggleEvent) {\n event.stopPropagation();\n this.collapsed = event.detail.collapsed;\n this.dispatchEvent(\n new CustomEvent<PanelToggleDetail>(`toggle`, {\n detail: { collapsed: this.collapsed },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _onCloseClick(event: Event) {\n event.stopPropagation();\n this.dispatchEvent(\n new CustomEvent<void>(`close`, {\n bubbles: true,\n composed: true,\n }),\n );\n this.remove();\n }\n\n protected override render() {\n const showToolbar = this.keepToolbar || !this.collapsed;\n return html`\n ${this.hideTitlebar\n ? nothing\n : html`\n <ixfx-titlebar\n .title=${this.title}\n .iconName=${this.iconName}\n .orientation=${this.orientation}\n .variant=${this.variant}\n .closable=${this.closable}\n .collapsible=${this.collapsible}\n .collapsed=${this.collapsed}\n .toggleInteraction=${this.toggleInteraction}\n @toggle=${this._onTitlebarToggle}\n @close=${this._onCloseClick}\n >\n ${showToolbar ? html`<slot name=\"toolbar\" slot=\"toolbar\"></slot>` : nothing}\n </ixfx-titlebar>\n `}\n\n <div class=\"content-wrapper\" ?expanded=${!this.collapsed}>\n <div class=\"content-inner\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n\n static override styles = [themeFallbacks, css`\n :host {\n display: flex;\n flex-direction: column;\n background: var(--surface-3);\n border: var(--border-subtle);\n border-radius: var(--radius-m);\n overflow: hidden;\n box-sizing: border-box;\n }\n\n :host([orientation=\"vertical\"]) {\n flex-direction: row;\n align-self: flex-start;\n min-width: 0 !important;\n flex-shrink: 1;\n }\n\n ixfx-titlebar {\n flex-shrink: 0;\n }\n\n .content-wrapper {\n interpolate-size: allow-keywords;\n overflow: hidden;\n height: 0;\n transition: height var(--transition, 0.2s ease-out);\n background: var(--surface-3);\n }\n\n .content-wrapper[expanded] {\n height: auto;\n }\n\n :host([orientation=\"vertical\"]) .content-wrapper {\n height: unset;\n width: 0;\n transition: width var(--transition, 0.2s ease-out);\n }\n\n :host([orientation=\"vertical\"]) .content-wrapper[expanded] {\n width: auto;\n }\n\n .content-inner {\n box-shadow: var(--deboss-3);\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n padding: var(--space-s);\n transform: translateY(-100%);\n transition: transform var(--transition, 0.2s ease-out);\n }\n\n .content-wrapper[expanded] .content-inner {\n transform: translateY(0);\n }\n\n :host([orientation=\"vertical\"]) .content-inner {\n width: max-content;\n height: 100%;\n transform: translateX(-100%);\n }\n\n :host([orientation=\"vertical\"]) .content-wrapper[expanded] .content-inner {\n transform: translateX(0);\n }\n\n /* === Midline variant (host + content only; bar chrome lives in ixfx-titlebar) === */\n\n :host([variant=\"midline\"]) {\n border: none !important;\n border-radius: 0 !important;\n background: transparent;\n }\n\n :host([variant=\"midline\"]) .content-inner {\n box-shadow: none;\n background: var(--surface-3);\n }\n\n :host([variant=\"midline\"]) .content-wrapper {\n background: transparent;\n }\n\n :host([variant=\"midline\"][orientation=\"vertical\"]) .content-wrapper {\n background: transparent;\n }\n\n /* === Tree variant: VS Code explorer / Outline style === */\n\n :host([variant=\"tree\"]) {\n border: none !important;\n border-radius: 0 !important;\n background: transparent;\n }\n\n :host([variant=\"tree\"]) .content-inner {\n box-shadow: none;\n background: transparent;\n padding: 0;\n }\n\n :host([variant=\"tree\"]) .content-wrapper {\n background: transparent;\n }\n\n :host([variant=\"tree\"][orientation=\"vertical\"]) .content-inner {\n width: max-content;\n height: 100%;\n transform: none;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-panel': PanelElement;\n }\n}\n\nexport interface PanelElement {\n addEventListener: (<K extends keyof PanelElementEventMap>(\n type: K,\n listener: (this: PanelElement, event: PanelElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n"],"mappings":";;;;;;AA6BO,IAAM,eAAN,MAAM,qBAAqB,WAAW;;;EACa,KAAA,YAAA;EAC6C,KAAA,cAAA;EAC7D,KAAA,WAAA;EAEkB,KAAA,cAAA;EACtB,KAAA,QAAA;EAC2B,KAAA,WAAA;EAC0C,KAAA,oBAAA;EAChB,KAAA,UAAA;EAEjB,KAAA,eAAA;EAEF,KAAA,cAAA;;CAEtE,kBAA0B,OAA4B;EACpD,MAAM,gBAAgB;EACtB,KAAK,YAAY,MAAM,OAAO;EAC9B,KAAK,cACH,IAAI,YAA+B,UAAU;GAC3C,QAAQ,EAAE,WAAW,KAAK,UAAU;GACpC,SAAS;GACT,UAAU;EACZ,CAAC,CACH;CACF;CAEA,cAAsB,OAAc;EAClC,MAAM,gBAAgB;EACtB,KAAK,cACH,IAAI,YAAkB,SAAS;GAC7B,SAAS;GACT,UAAU;EACZ,CAAC,CACH;EACA,KAAK,OAAO;CACd;CAEA,SAA4B;EAC1B,MAAM,cAAc,KAAK,eAAe,CAAC,KAAK;EAC9C,OAAO,IAAI;QACP,KAAK,eACH,UACA,IAAI;;mBAEK,KAAK,MAAM;sBACR,KAAK,SAAS;yBACX,KAAK,YAAY;qBACrB,KAAK,QAAQ;sBACZ,KAAK,SAAS;yBACX,KAAK,YAAY;uBACnB,KAAK,UAAU;+BACP,KAAK,kBAAkB;oBAClC,KAAK,kBAAkB;mBACxB,KAAK,cAAc;;YAE1B,cAAc,IAAI,gDAAgD,QAAQ;;UAE5E;;+CAEqC,CAAC,KAAK,UAAU;;;;;;CAM7D;;EAEyB,KAAA,SAAA,CAAC,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgH5C;;AACH;AApLG,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,aAAA,WAAA,aAAA,KAAA,CAAA;AACzC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;CAAe,SAAS;AAAK,CAAC,CAAA,GAAA,aAAA,WAAA,eAAA,KAAA,CAAA;AAClE,WAAA,CAAA,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,aAAA,WAAA,YAAA,KAAA,CAAA;AAE1B,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,aAAA,WAAA,eAAA,KAAA,CAAA;AACzC,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,aAAA,WAAA,SAAA,KAAA,CAAA;AACzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAY,CAAC,CAAA,GAAA,aAAA,WAAA,YAAA,KAAA,CAAA;AACjD,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAqB,CAAC,CAAA,GAAA,aAAA,WAAA,qBAAA,KAAA,CAAA;AAC1D,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;CAAW,SAAS;AAAK,CAAC,CAAA,GAAA,aAAA,WAAA,WAAA,KAAA,CAAA;AAE9D,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;AAAgB,CAAC,CAAA,GAAA,aAAA,WAAA,gBAAA,KAAA,CAAA;AAEtD,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;AAAe,CAAC,CAAA,GAAA,aAAA,WAAA,eAAA,KAAA,CAAA;AAdvDA,eAAAA,WAAAA,CAAAA,kBAAc,YAAY,CAAA,GAAA,YAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"polar-pad.d.ts","names":[],"sources":["../src/polar-pad/polar-pad.ts"],"mappings":";;;;cAqLa,iBAAiB;SACZ,sBAAM;;EAwIM;;EAGA;;EAGA;;EAGA;;EAGuC;;EAGG;;EAGA;;EAGD;;EAGzB;;EAGhB;;EAG0B;;EAGC;;EAGF;;EAGC;UAE9C;UACA;UACA;UACA;UACA;UACA;UAMA;UAgBA;UAOA;UAeA;UAuCA;UAsBA;UAIA;;;;;;UAkDA;EAyBC,iBAAiB,WAAW,gBAAgB,OAAO;UAQpD;EAMC,QAAQ,UAAU;EAKlB;UAUD;UAWA;UAiBA;UAMA;EAUC,UAAU,kBAAkB;;mBA+CpB;;KAOP;WACD;WACA;;KAGC,qBAAqB,YAAY;QAErC;YACI;IACR,kBAAkB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"polar-pad.js","names":["customElement"],"sources":["../src/polar-pad/polar-pad.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\n/**\n * <ixfx-polar-pad> — circular pad for setting polar coordinates (angle + radius).\n *\n * Mouse wheel: up = increase radius, down = decrease radius (angle is\n * unaffected). Same step math as keyboard `ArrowUp`/`ArrowDown`; Shift halves\n * the step. Pad must have focus by default, or set `lighttouch` to react on\n * hover. See `docs/infra-mousewheel.md`.\n *\n * The user clicks or drags within a circle to position a marker. The marker's\n * position encodes an angle (degrees, 0 = right, clockwise) and a radius (0–1).\n *\n * Properties / attributes\n * angle – current angle in degrees (0 = right, clockwise). Default: 0\n * radius – current radius 0–1 where 1 = edge. Default: 0.5\n * rings – number of concentric rings to draw (0 = none). Default: 0\n * rays – number of evenly-spaced radial spokes to draw (0 = none). Default: 0\n * show-ray – draw a line from the origin to the marker\n * show-origin – draw a dot at the centre\n * hide-cursor – hide cursor during drag and hover (default: false)\n * snap-value – when set, marker snaps to nearest ring/spoke depending on what's displayed\n * disabled – disable all interaction (default: false)\n * stops – quantise value to N discrete positions (both axes); overridden by stops-angle/stops-radius\n * stops-angle – quantise angle to N stops (degrees)\n * stops-radius – quantise radius to N stops\n * step-angle – explicit keyboard nudge step for angle (degrees). Overrides 10% default.\n * step-radius – explicit keyboard nudge step for radius (0..1 units). Overrides 10% default.\n * Home / End – jump radius to 0 (centre) / 1 (edge). Angle unchanged (it wraps).\n *\n * Customisable CSS variables:\n *\n * Pad background\n * --pad-background – CSS `background` of the circular pad. Accepts any CSS background\n * value: solid colour, conic-gradient(), radial-gradient(), etc.\n * Dynamic CSS vars like --angle-deg / --radius-pct are available\n * so the gradient can track the current marker position.\n * Default: var(--surface-4)\n * --pad-border-color – stroke of the outer circle (default: --surface-6)\n * --pad-border-width – thickness of outer border (default: 1px)\n *\n * Marker\n * --marker-size – diameter of the draggable marker (default: 10cqb)\n * --marker-color – fill colour of the marker (default: --accent)\n * --marker-opacity – opacity of the marker (default: 1)\n * --marker-stroke – stroke colour of the marker (default: none)\n * --marker-stroke-width – stroke thickness of the marker (default: 0)\n *\n * Origin dot (show-origin)\n * --origin-size – diameter of the origin dot (default: 6cqb)\n * --origin-color – fill colour of the origin dot (default: --accent)\n * --origin-opacity – opacity of the origin dot (default: 1)\n *\n * Ray line (show-ray)\n * --ray-color – stroke colour (default: --surface-6)\n * --ray-width – thickness (default: 2px)\n * --ray-opacity – opacity (default: 1)\n * --ray-dash – stroke-dasharray value e.g. \"4 2\" (default: none)\n *\n * Concentric rings (rings > 0)\n * --ring-color – stroke colour (default: --surface-6)\n * --ring-width – thickness (default: 1px)\n * --ring-opacity – opacity (default: 1)\n * --ring-dash – stroke-dasharray e.g. \"4 2\" (default: none)\n *\n * Radial spokes (rays > 0)\n * --spoke-color – stroke colour (default: --surface-6)\n * --spoke-width – thickness (default: 1px)\n * --spoke-opacity – opacity (default: 1)\n * --spoke-dash – stroke-dasharray e.g. \"4 2\" (default: none)\n *\n * CSS variables set on host for external dynamic styling:\n * --angle-deg – current angle as unitless number in degrees\n * --angle-rad – current angle as unitless number in radians\n * --radius-pct – current radius as unitless number 0–100\n *\n * Events\n * input – CustomEvent<PolarPadInputDetail> { angle: number (deg), radius: number (0–1) }\n * bubbles + composed, fires continuously during drag\n * change – CustomEvent<PolarPadInputDetail> { angle: number (deg), radius: number (0–1) }\n * bubbles + composed, fires when drag ends\n */\nimport { css, html, LitElement, svg } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { resolveAxisStep } from '../keyboard.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n// ---------------------------------------------------------------------------\n// Geometry helpers\n// ---------------------------------------------------------------------------\n\nconst DEG_TO_RAD = Math.PI / 180;\nconst RAD_TO_DEG = 180 / Math.PI;\n\n/**\n * Convert polar (angle in radians, radius 0-1) to SVG coordinates.\n * SVG viewBox 0 0 100 100; origin at (50,50); full radius = 50.\n * Convention: 0 rad = right (+x), increases CLOCKWISE (+y = downward in SVG).\n */\nfunction polarToSvg(angleRad: number, radius: number): { x: number; y: number } {\n const r = radius * 50;\n return { x: 50 + Math.cos(angleRad) * r, y: 50 + Math.sin(angleRad) * r };\n}\n\n/**\n * Convert SVG coordinates back to polar (angle in radians 0..2π, radius 0-1).\n * SVG: Y increases downward. Convention: 0=right, CW positive.\n */\nfunction svgToPolar(svgX: number, svgY: number): { angleRad: number; radius: number } {\n const dx = svgX - 50;\n const dy = svgY - 50; // +dy = downward = clockwise\n const dist = Math.sqrt(dx * dx + dy * dy);\n const radius = Math.min(1, dist / 50);\n const raw = Math.atan2(dy, dx);\n const angleRad = ((raw % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);\n return { angleRad, radius };\n}\n\nconst clamp01 = (v: number): number => Math.max(0, Math.min(1, v));\n\n// ---------------------------------------------------------------------------\n// Direction-aware snapping helpers\n// ---------------------------------------------------------------------------\n\nfunction snapAngle(angleDeg: number, prevAngleDeg: number, rays: number, snapEnabled: boolean): number {\n if (rays <= 0 || !snapEnabled)\n return angleDeg;\n const spokeDeg = 360 / rays;\n const normalized = ((angleDeg % 360) + 360) % 360;\n const nearest = Math.round(normalized / spokeDeg) * spokeDeg;\n const remainder = normalized % spokeDeg;\n const tie = Math.abs(remainder) < 0.0001 || Math.abs(spokeDeg - remainder) < 0.0001;\n if (tie) {\n let delta = angleDeg - prevAngleDeg;\n if (delta > 180)\n delta -= 360;\n if (delta < -180)\n delta += 360;\n const direction = delta >= 0 ? 1 : -1;\n return (nearest + direction * spokeDeg + 360) % 360;\n }\n return nearest;\n}\n\nfunction snapRadius(radius: number, prevRadius: number, rings: number, snapEnabled: boolean): number {\n if (rings <= 0 || !snapEnabled)\n return radius;\n const ringStep = 1 / rings;\n const nearest = Math.round(radius / ringStep) * ringStep;\n const remainder = radius % ringStep;\n const tie = Math.abs(remainder) < 0.0001 || Math.abs(ringStep - remainder) < 0.0001;\n if (tie) {\n const direction = radius >= prevRadius ? 1 : -1;\n return Math.max(0, Math.min(1, nearest + direction * ringStep));\n }\n return nearest;\n}\n\nfunction quantiseAngle(angleDeg: number, stops?: number): number {\n if (!stops || stops <= 1)\n return angleDeg;\n const stepDeg = 360 / stops;\n const normalized = ((angleDeg % 360) + 360) % 360;\n return Math.round(normalized / stepDeg) * stepDeg;\n}\n\nfunction quantiseRadius(radius: number, stops?: number): number {\n if (!stops || stops <= 1)\n return radius;\n const step = 1 / stops;\n return Math.round(radius / step) * step;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n@customElement(`ixfx-polar-pad`)\nexport class PolarPad extends WheelNudgeMixin(LitElement) {\n static override styles = [prominenceStyles, themeFallbacks, css`\n :host {\n display: block;\n width: 200px;\n height: 200px;\n touch-action: none;\n user-select: none;\n container-type: size;\n\n /* Pad background */\n --pad-background: var(--surface-4, oklch(22% 0.02 240));\n --pad-border-color: var(--surface-6, oklch(35% 0.02 240));\n --pad-border-width: 1px;\n\n /* Marker */\n --marker-size: 10cqb;\n --marker-color: var(--accent, oklch(60% 0.15 140));\n --marker-opacity: 1;\n --marker-stroke: none;\n --marker-stroke-width: 0;\n\n /* Origin dot */\n --origin-size: 6cqb;\n --origin-color: var(--accent, oklch(60% 0.15 140));\n --origin-opacity: 1;\n\n /* Ray line */\n --ray-color: var(--surface-6, oklch(35% 0.02 240));\n --ray-width: 2px;\n --ray-opacity: 1;\n --ray-dash: none;\n\n /* Concentric rings */\n --ring-color: var(--surface-6, oklch(35% 0.02 240));\n --ring-width: 1px;\n --ring-opacity: 1;\n --ring-dash: none;\n\n /* Radial spokes */\n --spoke-color: var(--surface-6, oklch(35% 0.02 240));\n --spoke-width: 1px;\n --spoke-opacity: 1;\n --spoke-dash: none;\n }\n\n :host([disabled]) {\n opacity: var(--prominence-disabled-opacity);\n pointer-events: none;\n }\n\n .polar-pad-area {\n position: relative;\n width: 100%;\n height: 100%;\n cursor: var(--cursor-display, crosshair);\n }\n\n :host([dragging]) .polar-pad-area {\n cursor: none;\n }\n\n svg {\n width: 100%;\n height: 100%;\n overflow: visible;\n }\n\n .pad-background {\n /* Used on the foreignObject div — accepts any CSS background value */\n width: 100%;\n height: 100%;\n background: var(--pad-background);\n }\n\n .pad-border {\n fill: none;\n stroke: var(--pad-border-color);\n stroke-width: var(--pad-border-width);\n vector-effect: non-scaling-stroke;\n }\n\n .ring {\n fill: none;\n stroke: var(--ring-color);\n stroke-width: var(--ring-width);\n stroke-dasharray: var(--ring-dash);\n opacity: var(--ring-opacity);\n vector-effect: non-scaling-stroke;\n }\n\n .spoke {\n fill: none;\n stroke: var(--spoke-color);\n stroke-width: var(--spoke-width);\n stroke-dasharray: var(--spoke-dash);\n opacity: var(--spoke-opacity);\n vector-effect: non-scaling-stroke;\n }\n\n .ray {\n fill: none;\n stroke: var(--ray-color);\n stroke-width: var(--ray-width);\n stroke-dasharray: var(--ray-dash);\n opacity: var(--ray-opacity);\n vector-effect: non-scaling-stroke;\n }\n\n .origin-dot {\n fill: var(--origin-color);\n opacity: var(--origin-opacity);\n }\n\n .marker {\n fill: var(--marker-color);\n opacity: var(--marker-opacity);\n stroke: var(--marker-stroke);\n stroke-width: var(--marker-stroke-width);\n cursor: grab;\n }\n\n .marker:active {\n cursor: grabbing;\n }\n\n svg:focus {\n outline: none;\n }\n\n svg:focus-visible .pad-border {\n stroke: var(--accent);\n stroke-width: 3;\n }\n `];\n\n /** Current angle in degrees. 0 = right, increases clockwise. */\n @property({ type: Number }) angle = 0;\n\n /** Current radius 0–1. 0 = origin, 1 = edge. */\n @property({ type: Number }) radius = 0.5;\n\n /** Number of concentric rings to display. 0 = none. */\n @property({ type: Number }) rings = 0;\n\n /** Number of evenly-spaced radial spoke lines to display. 0 = none. */\n @property({ type: Number }) rays = 0;\n\n /** Show a line from origin to the marker. */\n @property({ type: Boolean, reflect: true, attribute: `show-ray` }) showRay = false;\n\n /** Show a dot at the origin (centre). */\n @property({ type: Boolean, reflect: true, attribute: `show-origin` }) showOrigin = false;\n\n /** Hide cursor during drag and hover. */\n @property({ type: Boolean, reflect: true, attribute: `hide-cursor` }) hideCursor = false;\n\n /** When set, marker snaps to nearest ring/spoke depending on what's displayed. */\n @property({ type: Boolean, attribute: `snap-value`, reflect: true }) snapValue = false;\n\n /** Disable all interaction (pointer and keyboard). */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Number of quantised stops for both angle and radius. Overridden by stops-angle/stops-radius if set. */\n @property({ type: Number }) stops?: number;\n\n /** Number of quantised stops for angle. If set, overrides the stops setting for angle. */\n @property({ type: Number, attribute: `stops-angle` }) stopsAngle?: number;\n\n /** Number of quantised stops for radius. If set, overrides the stops setting for radius. */\n @property({ type: Number, attribute: `stops-radius` }) stopsRadius?: number;\n\n /** Explicit keyboard nudge step for angle (degrees). Overrides the 10% default. */\n @property({ type: Number, attribute: `step-angle` }) stepAngle?: number;\n\n /** Explicit keyboard nudge step for radius (0..1 units). Overrides the 10% default. */\n @property({ type: Number, attribute: `step-radius` }) stepRadius?: number;\n\n private _dragging = false;\n private _dragStartAngle = 0;\n private _dragStartRadius = 0;\n private _pressedKeys = new Set<string>();\n private _prevAngle = 0;\n private _prevRadius = 0;\n\n // -------------------------------------------------------------------------\n // Pointer handling\n // -------------------------------------------------------------------------\n\n private _onPointerDown = (e: PointerEvent): void => {\n e.preventDefault();\n const svg = this.renderRoot.querySelector(`svg`) as SVGSVGElement | undefined;\n (svg as HTMLElement | undefined)?.focus();\n const area = this.renderRoot.querySelector(`.polar-pad-area`) as HTMLElement | undefined;\n if (area)\n area.setPointerCapture(e.pointerId);\n this._dragging = true;\n this._dragStartAngle = this.angle;\n this._dragStartRadius = this.radius;\n this.setAttribute(`dragging`, ``);\n this._updateFromPointer(e);\n globalThis.addEventListener(`pointermove`, this._onPointerMove);\n globalThis.addEventListener(`pointerup`, this._onPointerUp);\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!this._dragging)\n return;\n e.preventDefault();\n this._updateFromPointer(e);\n };\n\n private _onPointerUp = (): void => {\n const hasChanged = this.angle !== this._dragStartAngle || this.radius !== this._dragStartRadius;\n this._dragging = false;\n this.removeAttribute(`dragging`);\n globalThis.removeEventListener(`pointermove`, this._onPointerMove);\n globalThis.removeEventListener(`pointerup`, this._onPointerUp);\n if (hasChanged) {\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`change`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n private _updateFromPointer(e: PointerEvent): void {\n const area = this.renderRoot.querySelector(`.polar-pad-area`);\n if (!area)\n return;\n\n const rect = area.getBoundingClientRect();\n const size = Math.min(rect.width, rect.height);\n const svgX = ((e.clientX - rect.left) / size) * 100;\n const svgY = ((e.clientY - rect.top) / size) * 100;\n\n const { angleRad, radius } = svgToPolar(svgX, svgY);\n const newAngleDeg = angleRad * RAD_TO_DEG;\n const newRadius = clamp01(radius);\n\n this._prevAngle = this.angle;\n this._prevRadius = this.radius;\n\n const snappedAngle = snapAngle(newAngleDeg, this._prevAngle, this.rays, this.snapValue);\n const snappedRadius = snapRadius(newRadius, this._prevRadius, this.rings, this.snapValue);\n\n const effectiveStopsAngle = this.stopsAngle ?? this.stops;\n const effectiveStopsRadius = this.stopsRadius ?? this.stops;\n\n this.angle = quantiseAngle(snappedAngle, effectiveStopsAngle);\n this.radius = quantiseRadius(snappedRadius, effectiveStopsRadius);\n this._prevAngle = newAngleDeg;\n this._prevRadius = newRadius;\n\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`input`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n\n // -------------------------------------------------------------------------\n // Keyboard handling\n // -------------------------------------------------------------------------\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this.disabled)\n return;\n if ([`ArrowLeft`, `ArrowRight`, `ArrowUp`, `ArrowDown`].includes(e.key)) {\n e.preventDefault();\n this._pressedKeys.add(e.key);\n this._handleKeyboardMove(e.shiftKey);\n } else if (e.key === `Home` || e.key === `End`) {\n e.preventDefault();\n const newRadius = e.key === `Home` ? 0 : 1;\n if (newRadius !== this.radius) {\n this._prevRadius = this.radius;\n this.radius = newRadius;\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`input`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n }\n };\n\n private _onKeyUp = (e: KeyboardEvent): void => {\n this._pressedKeys.delete(e.key);\n };\n\n private _handleKeyboardMove = (shiftKey: boolean): void => {\n const effectiveStopsAngle = this.stopsAngle ?? this.stops;\n const effectiveStopsRadius = this.stopsRadius ?? this.stops;\n\n const angleStep = resolveAxisStep(360, effectiveStopsAngle, this.stepAngle, shiftKey);\n const radiusStep = resolveAxisStep(1, effectiveStopsRadius, this.stepRadius, shiftKey);\n\n this._prevAngle = this.angle;\n this._prevRadius = this.radius;\n\n let newAngle = this.angle;\n let newRadius = this.radius;\n\n if (this._pressedKeys.has(`ArrowLeft`)) {\n newAngle -= angleStep;\n }\n if (this._pressedKeys.has(`ArrowRight`)) {\n newAngle += angleStep;\n }\n if (this._pressedKeys.has(`ArrowUp`)) {\n newRadius = Math.min(1, newRadius + radiusStep);\n }\n if (this._pressedKeys.has(`ArrowDown`)) {\n newRadius = Math.max(0, newRadius - radiusStep);\n }\n\n newAngle = ((newAngle % 360) + 360) % 360;\n\n let finalAngle = snapAngle(newAngle, this._prevAngle, this.rays, this.snapValue);\n let finalRadius = snapRadius(newRadius, this._prevRadius, this.rings, this.snapValue);\n\n finalAngle = quantiseAngle(finalAngle, effectiveStopsAngle);\n finalRadius = quantiseRadius(finalRadius, effectiveStopsRadius);\n\n if (finalAngle !== this.angle || finalRadius !== this.radius) {\n this.angle = finalAngle;\n this.radius = finalRadius;\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`input`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n /**\n * Apply a radius nudge by direction. Wheel affects radius only (matches the\n * keyboard `ArrowUp`/`ArrowDown` semantic per `plans/mousewheel.md`); the\n * angle is unchanged.\n */\n private _stepRadiusByDelta(direction: 1 | -1, shiftKey: boolean): void {\n const effectiveStopsRadius = this.stopsRadius ?? this.stops;\n const radiusStep = resolveAxisStep(1, effectiveStopsRadius, this.stepRadius, shiftKey);\n\n this._prevRadius = this.radius;\n const newRadius = direction === 1\n ? Math.min(1, this.radius + radiusStep)\n : Math.max(0, this.radius - radiusStep);\n\n const finalRadius = quantiseRadius(\n snapRadius(newRadius, this._prevRadius, this.rings, this.snapValue),\n effectiveStopsRadius,\n );\n if (finalRadius === this.radius)\n return;\n\n this.radius = finalRadius;\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`input`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n\n // Wheel handler — installed by WheelNudgeMixin on the host.\n override _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void {\n this._stepRadiusByDelta(direction, event.shiftKey);\n }\n\n // -------------------------------------------------------------------------\n // CSS variable sync\n // -------------------------------------------------------------------------\n\n private _setCssVars(): void {\n this.style.setProperty(`--angle-deg`, `${this.angle}`);\n this.style.setProperty(`--angle-rad`, `${this.angle * DEG_TO_RAD}`);\n this.style.setProperty(`--radius-pct`, `${clamp01(this.radius) * 100}`);\n }\n\n override updated(_changed: PropertyValues): void {\n super.updated(_changed);\n this._setCssVars();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._onPointerUp();\n this._pressedKeys.clear();\n }\n\n // -------------------------------------------------------------------------\n // SVG helpers\n // -------------------------------------------------------------------------\n\n private _renderRings() {\n if (this.rings <= 0)\n return ``;\n const items = [];\n for (let i = 1; i <= this.rings; i++) {\n const r = (i / this.rings) * 50;\n items.push(svg`<circle class=\"ring\" cx=\"50\" cy=\"50\" r=\"${r}\" />`);\n }\n return items;\n }\n\n private _renderSpokes() {\n if (this.rays <= 0)\n return ``;\n const items = [];\n for (let i = 0; i < this.rays; i++) {\n const angleRad = (i / this.rays) * 2 * Math.PI;\n const cos = Math.cos(angleRad);\n const sin = Math.sin(angleRad); // SVG +y downward matches CW convention directly\n const x1 = 50 + cos * 50;\n const y1 = 50 + sin * 50;\n const x2 = 50 - cos * 50;\n const y2 = 50 - sin * 50;\n items.push(svg`<line class=\"spoke\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" />`);\n }\n return items;\n }\n\n private _renderRay(markerX: number, markerY: number) {\n if (!this.showRay)\n return ``;\n return svg`<line class=\"ray\" x1=\"50\" y1=\"50\" x2=\"${markerX}\" y2=\"${markerY}\" />`;\n }\n\n private _renderOrigin() {\n if (!this.showOrigin)\n return ``;\n return svg`<circle class=\"origin-dot\" cx=\"50\" cy=\"50\" r=\"3\" style=\"r: calc(var(--origin-size) / 2)\" />`;\n }\n\n // -------------------------------------------------------------------------\n // Render\n // -------------------------------------------------------------------------\n\n override render(): ReturnType<typeof html> {\n const angleRad = this.angle * DEG_TO_RAD;\n const { x: markerX, y: markerY } = polarToSvg(angleRad, clamp01(this.radius));\n\n return html`\n <div class=\"polar-pad-area\"\n @pointerdown=${this._onPointerDown}\n @keydown=${this._onKeyDown}\n @keyup=${this._onKeyUp}\n @blur=${() => this._pressedKeys.clear()}>\n <svg viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"xMidYMid meet\"\n tabindex=${this.disabled ? -1 : 0}>\n <defs>\n <clipPath id=\"circle-clip-${this._uid}\">\n <circle cx=\"50\" cy=\"50\" r=\"50\" />\n </clipPath>\n </defs>\n\n <!-- clipped group: background + rings + spokes -->\n <g clip-path=\"url(#circle-clip-${this._uid})\">\n <foreignObject x=\"0\" y=\"0\" width=\"100\" height=\"100\">\n <div class=\"pad-background\" xmlns=\"http://www.w3.org/1999/xhtml\"></div>\n </foreignObject>\n ${this._renderRings()}\n ${this._renderSpokes()}\n </g>\n\n <!-- border circle (on top of clip, non-scaling stroke) -->\n <circle class=\"pad-border\" cx=\"50\" cy=\"50\" r=\"49.75\" />\n\n <!-- ray + origin + marker -->\n ${this._renderRay(markerX, markerY)}\n ${this._renderOrigin()}\n <circle\n class=\"marker\"\n cx=\"${markerX}\"\n cy=\"${markerY}\"\n r=\"5\"\n style=\"r: calc(var(--marker-size) / 2)\"\n />\n </svg>\n </div>\n `;\n }\n\n /** Stable per-instance uid for SVG clipPath IDs. */\n private readonly _uid = Math.random().toString(36).slice(2, 8);\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type PolarPadInputDetail = {\n readonly angle: number; // degrees, 0 = right, clockwise\n readonly radius: number; // 0–1\n};\n\nexport type PolarPadInputEvent = CustomEvent<PolarPadInputDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-polar-pad': PolarPad;\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"popup-D80sj2QC.js","names":[],"sources":["../src/styles/popup.ts"],"sourcesContent":["import { css } from \"lit\";\n\n/**\n * Canonical surface styles for floating popup elements (menus, dropdowns,\n * colour picker, tooltips). Apply by adding `popupSurfaceStyles` to a\n * component's `static styles` array and the class `popup-surface` to the\n * popup container element - or to the host itself (via `this.classList.add`)\n * when the component's host element is the popup container.\n *\n * Intentionally omitted (remain per-component): positioning, padding,\n * dimensions, z-index, and open/close animations.\n */\nexport const popupSurfaceStyles = css`\n .popup-surface,\n :host(.popup-surface) {\n background: var(--surface-5);\n border: 1px solid var(--surface-6);\n border-radius: var(--radius-l);\n box-shadow: var(--shadow-m);\n color: var(--surface-5-text);\n }\n`;\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,qBAAqB,GAAG"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"prominence-DlFShic3.js","names":[],"sources":["../src/styles/prominence.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * Shared CSS variable defaults for prominence-based interaction feedback.\n *\n * Defines the `--prominence-*` variables on `:host`. Include this if you\n * are building custom prominence selectors; otherwise use `prominenceStyles`\n * or `prominenceSubStyles` which include these variables automatically.\n */\nexport const prominenceVars = css`\n :host {\n --prominence-idle-opacity: 0.6;\n --prominence-idle-saturate: 0.4;\n --prominence-tickled-opacity: 0.85;\n --prominence-tickled-saturate: 0.8;\n --prominence-disabled-opacity: 0.3;\n --prominence-disabled-saturate: 0.1;\n }\n`;\n\n/**\n * Host-based prominence interaction feedback.\n *\n * Applies CSS `filter` to **the whole component host** to convey state:\n * - **Disabled** (`[disabled]` / `:disabled`): heavily muted\n * - **Idle** (default): reduced opacity + desaturated\n * - **Tickled** (`:hover` / `:focus-within`): elevated opacity + saturation\n * - **Active** (`:active` / `[dragging]`): full vibrancy (filter removed)\n *\n * Defaults are defined on `:host` and can be overridden per-instance.\n *\n * Usage:\n * ```ts\n * import { prominenceStyles } from '../styles/prominence.js';\n *\n * class MyComponent extends LitElement {\n * static styles = [prominenceStyles, css`...`];\n * }\n * ```\n */\nexport const prominenceStyles = css`\n ${prominenceVars}\n\n :host {\n filter:\n opacity(var(--prominence-idle-opacity))\n saturate(var(--prominence-idle-saturate));\n transition: filter var(--transition, 0.15s ease-out);\n }\n\n :host(:hover),\n :host(:focus-within) {\n filter:\n opacity(var(--prominence-tickled-opacity))\n saturate(var(--prominence-tickled-saturate));\n }\n\n :host(:active),\n :host([dragging]) {\n filter: none;\n }\n\n /* Disabled comes last to override tickled/active selectors of equal specificity */\n :host([disabled]),\n :host(:disabled) {\n filter:\n opacity(var(--prominence-disabled-opacity))\n saturate(var(--prominence-disabled-saturate));\n pointer-events: none;\n }\n`;\n\n/**\n * Sub-element prominence interaction feedback.\n *\n * Same prominence effect as `prominenceStyles`, but applied to **child\n * elements** via the `.prominence` class instead of `:host`. Use this when\n * you want prominence feedback on a specific sub-element rather than the\n * whole component.\n *\n * Usage:\n * ```ts\n * import { prominenceSubStyles } from '../styles/prominence.js';\n *\n * class MyComponent extends LitElement {\n * static styles = [prominenceSubStyles, css`\n * .thumb { }\n * `];\n *\n * render() {\n * return html`<div class=\"thumb prominence\"></div>`;\n * }\n * }\n * ```\n *\n * States are driven by pseudo-classes on the element itself:\n * - Default idle state applies the muted filter.\n * - `:hover` / `:focus-within` transitions to tickled.\n * - `:active` / `.dragging` removes the filter entirely.\n * - `[disabled]` / `:disabled` applies the disabled mute.\n */\nexport const prominenceSubStyles = css`\n ${prominenceVars}\n\n .prominence {\n filter:\n opacity(var(--prominence-idle-opacity))\n saturate(var(--prominence-idle-saturate));\n transition: filter var(--transition, 0.15s ease-out);\n }\n\n .prominence:hover,\n .prominence:focus-within {\n filter:\n opacity(var(--prominence-tickled-opacity))\n saturate(var(--prominence-tickled-saturate));\n }\n\n .prominence:active,\n .prominence.dragging {\n filter: none;\n }\n\n .prominence[disabled],\n .prominence:disabled {\n filter:\n opacity(var(--prominence-disabled-opacity))\n saturate(var(--prominence-disabled-saturate));\n pointer-events: none;\n }\n`;\n"],"mappings":";;;;;;;;;AASA,MAAa,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BjC,MAAa,mBAAmB,GAAG;IAC/B,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DgB,GAAG;IAClC,eAAe"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"radial-input-DU6t2hYO.d.ts","names":[],"sources":["../src/radial-input/types.ts","../src/radial-input/radial-input.ts"],"mappings":";;;;;;KAIY;KACA;KACA;UAEK;EACf;EACA;EACA,MAAM;EACN;EACA;;UAGe;EACf;EACA;;UAGe;EACf;EACA;EACA;;KAGU,wBAAwB,YAAY;KACpC,yBAAyB,YAAY;;;;cCepC,2BAA2B;;MAMlC;MAIA,OAAO;EAMX;EAGA;EAGA;EAGA;EAGA;EAIA,WAAW;EAIX;EAGA,aAAa;EAGb;EAIA;;EA+BA,QACE,aACA;IACE;IACA,OAAO;IACP;IACA;;EAcJ,aAAa,aAAa;EAQ1B,WAAW;EAKX,YAAY,oBAAoB;EAIhC,QAAQ,cAAc;EA+Mb,iBAAiB,WAAW,gBAAgB,OAAO;YA4PzC,WAAW,SAAS;EAa9B;YAgDU,QAAQ,SAAS;EA4B3B;EAQA;SAYO,sBAAM;;QAwHhB;YACI;IACR,qBAAqB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"radial-input-KMVltQfe.js","names":["#_radius","#dragging","#dragStartY","#valueAtDragStart","#onPointerMove","#onPointerUp","#setValueFromRelative","#stepByRelativeDelta","#lanes","#getRelativeValue","#quantise","#isUserInteraction","#scheduleChangeEvent","#fireChangeEvent","#changeDebounceTimer","#getCssVar","#getEffectiveMarkerStyle","#getNeedlePath","#onPointerDown","#onKeyDown","#renderCircleFill","#renderWedge","#renderCircleBorder","#renderLane","#renderMidpointMarker","#renderValueMarker","customElement"],"sources":["../src/radial-input/svg-utils.ts","../src/radial-input/radial-input.ts"],"sourcesContent":["/**\n * SVG utilities for radial input component\n * Handles geometry calculations for flattened circle arcs\n */\n\nimport type { ValueMode } from './types.js';\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface ArcParameters {\n startAngle: number; // radians\n endAngle: number; // radians\n radius: number;\n center: Point;\n}\n\nconst PI2 = Math.PI * 2;\nconst MIDPOINT_ANGLE = -Math.PI / 2; // Top-center of circle\n\n/**\n * Convert polar coordinates (angle in radians, radius) to SVG Cartesian coordinates\n * @param angle - Angle in radians (0 = right/east, increases clockwise in SVG)\n * @param radius - Distance from center\n * @param center - Center point (default: {x: 50, y: 50})\n * @returns Point in SVG coordinates\n */\nexport function polarToCartesian(\n angle: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n): Point {\n return {\n x: center.x + Math.cos(angle) * radius,\n y: center.y + Math.sin(angle) * radius,\n };\n}\n\n/**\n * Convert SVG Cartesian coordinates to polar (angle in radians, radius)\n * @param x - X coordinate\n * @param y - Y coordinate\n * @param center - Center point (default: {x: 50, y: 50})\n * @returns Angle in radians (0..2π) and radius\n */\nexport function cartesianToPolar(\n x: number,\n y: number,\n center: Point = { x: 50, y: 50 },\n): { angle: number; radius: number } {\n const dx = x - center.x;\n const dy = y - center.y;\n const radius = Math.sqrt(dx * dx + dy * dy);\n const raw = Math.atan2(dy, dx);\n const angle = ((raw % PI2) + PI2) % PI2; // Normalize to 0..2π\n return { angle, radius };\n}\n\n/**\n * Calculate start and end angles for a flattened circle\n * @param flatten - How much of the circle to hide (0..1): 0 = full circle, 0.5 = half circle, 1 = no arc\n * @returns Start and end angles in radians\n */\nexport function getFlattenedCircleAngles(flatten: number): {\n startAngle: number;\n endAngle: number;\n totalArc: number;\n} {\n // flatten represents the percentage of circle hidden\n // 0 = full circle (360°), 0.5 = half circle (180°), 1 = no arc (0°)\n const visibleArc = PI2 * (1 - flatten); // Total visible arc in radians\n\n // Center the visible arc at the top (angle = -π/2)\n // Start and end angles are symmetric around top-center\n const halfArc = visibleArc / 2;\n const topAngle = -Math.PI / 2; // Top center (270° in standard coords, but -90° from east)\n\n const startAngle = topAngle - halfArc;\n const endAngle = topAngle + halfArc;\n const totalArc = endAngle - startAngle;\n\n return { startAngle, endAngle, totalArc };\n}\n\n/**\n * Map a value (0..1) to an angle based on value mode\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Angle in radians\n */\nexport function valueToAngle(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n): number {\n const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);\n\n switch (valueMode) {\n case `range`:\n // Linear mapping from start to end\n return startAngle + relativeValue * totalArc;\n\n case `bipolar`: {\n // Midpoint is at top (MIDPOINT_ANGLE = -π/2)\n if (relativeValue <= 0.5) {\n // Map 0..0.5 to startAngle..MIDPOINT_ANGLE (going counterclockwise to top)\n const t = relativeValue / 0.5;\n return startAngle + t * (MIDPOINT_ANGLE - startAngle);\n } else {\n // Map 0.5..1 to MIDPOINT_ANGLE..endAngle (going clockwise from top)\n const t = (relativeValue - 0.5) / 0.5;\n return MIDPOINT_ANGLE + t * (endAngle - MIDPOINT_ANGLE);\n }\n }\n\n case `unipolar`: {\n // Marker stays at top for unipolar mode\n return MIDPOINT_ANGLE;\n }\n\n default:\n return startAngle;\n }\n}\n\n/**\n * Get start and end angles for a value arc\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Start and end angles for the arc\n */\nexport function getValueArcAngles(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n): { startAngle: number; endAngle: number } {\n const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);\n\n switch (valueMode) {\n case `range`:\n // Arc from start to value position\n return {\n startAngle,\n endAngle: startAngle + relativeValue * totalArc,\n };\n\n case `bipolar`: {\n // Midpoint is at top (MIDPOINT_ANGLE = -π/2)\n if (relativeValue < 0.5) {\n // Arc from some point toward top (going counterclockwise)\n const t = relativeValue / 0.5;\n const valueAngle = startAngle + t * (MIDPOINT_ANGLE - startAngle);\n return {\n startAngle: valueAngle,\n endAngle: MIDPOINT_ANGLE,\n };\n } else if (relativeValue > 0.5) {\n // Arc from top going clockwise\n const t = (relativeValue - 0.5) / 0.5;\n const valueAngle = MIDPOINT_ANGLE + t * (endAngle - MIDPOINT_ANGLE);\n return {\n startAngle: MIDPOINT_ANGLE,\n endAngle: valueAngle,\n };\n } else {\n // Exactly at midpoint, no arc\n return { startAngle: MIDPOINT_ANGLE, endAngle: MIDPOINT_ANGLE };\n }\n }\n\n case `unipolar`: {\n // Spread symmetrically from top (MIDPOINT_ANGLE = -π/2)\n const spreadAmount = relativeValue * totalArc / 2;\n return {\n startAngle: MIDPOINT_ANGLE - spreadAmount,\n endAngle: MIDPOINT_ANGLE + spreadAmount,\n };\n }\n\n default:\n return { startAngle, endAngle: startAngle };\n }\n}\n\n/**\n * Get start and end angles for an anchored arc\n * Centered on current value position, extends equally in both directions\n * @param relativeValue - Current value position (0..1)\n * @param laneValue - Width of the arc (0..1, where 1 = full range)\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Start and end angles for the arc\n */\nexport function getAnchoredArcAngles(\n relativeValue: number,\n laneValue: number,\n valueMode: ValueMode,\n flatten: number,\n): { startAngle: number; endAngle: number } {\n const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);\n\n // Get the angle for the current value (this is the center of the arc)\n const centerAngle = valueToAngle(relativeValue, valueMode, flatten);\n\n // Calculate half-width of the arc\n // laneValue is 0..1, where 1 = full range\n const halfWidth = (laneValue * totalArc) / 2;\n\n let arcStart = centerAngle - halfWidth;\n let arcEnd = centerAngle + halfWidth;\n\n // Clamp to valid bounds (prevent wrapping)\n // The valid range is [startAngle, endAngle]\n if (arcStart < startAngle)\n arcStart = startAngle;\n if (arcEnd > endAngle)\n arcEnd = endAngle;\n\n // If the arc would be degenerate after clamping, return a single point\n if (arcStart >= arcEnd) {\n return { startAngle: centerAngle, endAngle: centerAngle };\n }\n\n return { startAngle: arcStart, endAngle: arcEnd };\n}\n\n/**\n * Generate SVG path for an arc\n * @param startAngle - Start angle in radians\n * @param endAngle - End angle in radians\n * @param radius - Arc radius\n * @param center - Center point\n * @returns SVG path data string\n */\nexport function generateArcPath(\n startAngle: number,\n endAngle: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n): string {\n if (startAngle === endAngle) {\n return ``; // No arc to draw\n }\n\n // Calculate arc length to determine large-arc-flag\n let arcLength = endAngle - startAngle;\n\n // Handle wrap-around case (e.g., from 5.5 to 0.5 radians)\n if (arcLength < 0) {\n arcLength += PI2;\n }\n\n // Handle full or near-full circle case\n // When arcLength is nearly 2π, start and end points are essentially the same\n // and drawing a full circle needs special handling\n if (arcLength >= PI2 - 0.001) {\n // Draw a full circle by going almost all the way around\n const adjustedEnd = startAngle + PI2 - 0.001;\n const start = polarToCartesian(startAngle, radius, center);\n const end = polarToCartesian(adjustedEnd, radius, center);\n return `M ${start.x},${start.y} A ${radius},${radius} 0 1 1 ${end.x},${end.y}`;\n }\n\n const start = polarToCartesian(startAngle, radius, center);\n const end = polarToCartesian(endAngle, radius, center);\n\n const largeArcFlag = arcLength > Math.PI ? 1 : 0;\n\n return `M ${start.x},${start.y} A ${radius},${radius} 0 ${largeArcFlag} 1 ${end.x},${end.y}`;\n}\n\n/**\n * Generate SVG path for a full flattened circle border\n * @param radius - Circle radius\n * @param flatten - Flattening amount (0..1)\n * @param center - Center point\n * @returns SVG path data string\n */\nexport function generateCircleBorderPath(\n radius: number,\n flatten: number,\n center: Point = { x: 50, y: 50 },\n): string {\n const { startAngle, endAngle } = getFlattenedCircleAngles(flatten);\n return generateArcPath(startAngle, endAngle, radius, center);\n}\n\n/**\n * Generate SVG path data for a filled wedge (pie-slice) sector\n * @param startAngle - Start angle in radians\n * @param endAngle - End angle in radians\n * @param radius - Wedge radius (same as dial radius)\n * @param center - Center point\n * @param clockwise - Whether to draw arc clockwise (true) or counterclockwise (false)\n * @returns SVG path data string for filled wedge\n */\nexport function generateWedgePath(\n startAngle: number,\n endAngle: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n clockwise: boolean = true,\n): string {\n if (startAngle === endAngle) {\n return ``; // No wedge to draw\n }\n\n // Calculate arc length (always positive, representing shortest path)\n let arcLength = endAngle - startAngle;\n if (arcLength < 0) {\n arcLength += PI2;\n }\n\n // Handle full or near-full circle case\n if (arcLength >= PI2 - 0.001) {\n // Draw a near-full circle wedge\n const start = polarToCartesian(startAngle, radius, center);\n const adjustedEnd = startAngle + PI2 - 0.001;\n const adjEnd = polarToCartesian(adjustedEnd, radius, center);\n const largeArcFlag = 1;\n const sweepFlag = clockwise ? 1 : 0;\n return `M ${center.x},${center.y} L ${start.x},${start.y} A ${radius},${radius} 0 ${largeArcFlag} ${sweepFlag} ${adjEnd.x},${adjEnd.y} Z`;\n }\n\n let actualStartAngle = startAngle;\n let actualEndAngle = endAngle;\n let actualClockwise = clockwise;\n\n // When going counterclockwise and arcLength > π, we want the short clockwise path instead\n // by swapping start and end\n if (!clockwise && arcLength > Math.PI) {\n actualStartAngle = endAngle;\n actualEndAngle = startAngle;\n actualClockwise = true;\n arcLength = PI2 - arcLength;\n }\n\n const start = polarToCartesian(actualStartAngle, radius, center);\n const end = polarToCartesian(actualEndAngle, radius, center);\n\n const largeArcFlag = arcLength > Math.PI ? 1 : 0;\n const sweepFlag = actualClockwise ? 1 : 0;\n\n // M center L start A radius radius 0 large sweep end Z\n return `M ${center.x},${center.y} L ${start.x},${start.y} A ${radius},${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.x},${end.y} Z`;\n}\n\n/**\n * Get wedge angles based on value mode\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Object with startAngle, endAngle, and clockwise flag\n */\nexport function getWedgeAngles(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n): { startAngle: number; endAngle: number; clockwise: boolean } {\n const { startAngle, totalArc } = getFlattenedCircleAngles(flatten);\n const valueAngle = valueToAngle(relativeValue, valueMode, flatten);\n\n switch (valueMode) {\n case `range`:\n // Wedge from startAngle to valueAngle (always clockwise)\n return {\n startAngle,\n endAngle: valueAngle,\n clockwise: true,\n };\n\n case `bipolar`: {\n // When value < 0.5, go counterclockwise from midpoint to value\n // When value >= 0.5, go clockwise from midpoint to value\n if (relativeValue < 0.5) {\n return {\n startAngle: MIDPOINT_ANGLE,\n endAngle: valueAngle,\n clockwise: false,\n };\n } else {\n return {\n startAngle: MIDPOINT_ANGLE,\n endAngle: valueAngle,\n clockwise: true,\n };\n }\n }\n\n case `unipolar`: {\n // Wedge centered at MIDPOINT, spreading value * totalArc/2 in each direction\n const halfSpread = relativeValue * totalArc / 2;\n return {\n startAngle: MIDPOINT_ANGLE - halfSpread,\n endAngle: MIDPOINT_ANGLE + halfSpread,\n clockwise: true,\n };\n }\n\n default:\n return { startAngle, endAngle: startAngle, clockwise: true };\n }\n}\n\n/**\n * Get position for a marker (needle or dot) at a given value\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @param radius - Circle radius\n * @param center - Center point\n * @returns Angle in radians and position point\n */\nexport function getMarkerPosition(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n): { angle: number; position: Point } {\n const angle = valueToAngle(relativeValue, valueMode, flatten);\n const position = polarToCartesian(angle, radius, center);\n return { angle, position };\n}\n\n/**\n * Get position for midpoint marker (used in bipolar/unipolar modes)\n * @param radius - Circle radius\n * @param center - Center point\n * @returns Position at top-center of circle\n */\nexport function getMidpointPosition(\n radius: number,\n center: Point = { x: 50, y: 50 },\n): { angle: number; position: Point } {\n const position = polarToCartesian(MIDPOINT_ANGLE, radius, center);\n return { angle: MIDPOINT_ANGLE, position };\n}\n\n/**\n * Clamp a value between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Scale a value from one range to another\n */\nexport function scale(\n value: number,\n fromMin: number,\n fromMax: number,\n toMin: number,\n toMax: number,\n): number {\n const normalized = (value - fromMin) / (fromMax - fromMin);\n return toMin + normalized * (toMax - toMin);\n}\n","/**\n * Radial input component\n * A rotary dial input inspired by Ableton Live and music production software.\n *\n * Mouse wheel: up = increase, down = decrease, with the same step resolution as\n * arrow keys (Shift halves the step). The dial must have focus by default, or\n * set the `lighttouch` boolean attribute to react on hover instead. See\n * `docs/infra-mousewheel.md`.\n */\n\nimport type { PropertyValues } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport type {\n LaneData,\n LaneType,\n MarkerStyle,\n RadialInputChangeDetail,\n RadialInputInputDetail,\n ValueMode,\n} from './types.js';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KEY_STEP_DIVISOR, resolveAxisStep } from '../keyboard.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport {\n clamp,\n generateArcPath,\n generateCircleBorderPath,\n generateWedgePath,\n getAnchoredArcAngles,\n getMarkerPosition,\n getMidpointPosition,\n getValueArcAngles,\n getWedgeAngles,\n scale,\n} from './svg-utils.js';\n\nconst CENTER = { x: 50, y: 50 }; // Center point in viewBox\n\n@customElement(`ixfx-radial-input`)\nexport class RadialInputElement extends WheelNudgeMixin(LitElement) {\n // Internal backing field for radius (used with custom setter for clamping)\n #_radius = 45;\n\n // Radius property (controls dial size, 10-50 range to prevent clipping)\n @property({ type: Number })\n get radius(): number {\n return this.#_radius;\n }\n\n set radius(v: number) {\n this.#_radius = clamp(v, 10, 50);\n }\n\n // Value properties (matches ixfx-range API)\n @property({ type: Number })\n value = 0;\n\n @property({ type: Number })\n min = 0;\n\n @property({ type: Number })\n max = 100;\n\n @property({ type: Number })\n step: number | undefined = undefined;\n\n @property({ type: Number })\n stops?: number;\n\n // Value mode\n @property({ type: String, attribute: `value-mode` })\n valueMode: ValueMode = `range`;\n\n // Appearance\n @property({ type: Number })\n flatten = 0.3;\n\n @property({ type: String, attribute: `marker-style` })\n markerStyle: MarkerStyle = `needle`;\n\n @property({ type: Boolean })\n wedge = false;\n\n // Interaction\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // Internal state\n #lanes: Map<string, LaneData> = new Map();\n #dragging = false;\n #dragStartY = 0;\n #valueAtDragStart = 0;\n #changeDebounceTimer: number | undefined;\n #isUserInteraction = false;\n\n constructor() {\n super();\n // Initialize default lanes\n // Note: value lane will be updated in willUpdate() to reflect initial value\n this.#lanes.set(`track`, {\n key: `track`,\n value: 1, // Full range\n type: `fixed`,\n offset: 0,\n width: 0.16,\n });\n this.#lanes.set(`value`, {\n key: `value`,\n value: 0, // Will be updated in willUpdate()\n type: `value`,\n offset: 0,\n width: 0.24,\n });\n }\n\n // Lane management API\n addLane(\n key: string,\n options?: {\n value?: number;\n type?: LaneType;\n offset?: number;\n width?: number;\n },\n ): void {\n const relativeValue = this.#getRelativeValue();\n this.#lanes.set(key, {\n key,\n value: options?.value ?? relativeValue,\n type: options?.type ?? `value`,\n offset: options?.offset ?? 0,\n width: options?.width ?? 0.1,\n });\n this.requestUpdate();\n }\n\n setLaneValue(key: string, value: number): void {\n const lane = this.#lanes.get(key);\n if (lane) {\n lane.value = clamp(value, 0, 1);\n this.requestUpdate();\n }\n }\n\n removeLane(key: string): void {\n this.#lanes.delete(key);\n this.requestUpdate();\n }\n\n getLanes(): ReadonlyMap<string, LaneData> {\n return new Map(this.#lanes);\n }\n\n getLane(key: string): LaneData | undefined {\n return this.#lanes.get(key);\n }\n\n // Internal helpers\n #getRelativeValue(): number {\n return scale(this.value, this.min, this.max, 0, 1);\n }\n\n #getEffectiveMarkerStyle(): MarkerStyle {\n if (this.valueMode === `unipolar` && this.markerStyle === `needle`) {\n return `none`;\n }\n return this.markerStyle;\n }\n\n #quantise(value: number): number {\n if (this.stops && this.stops > 1) {\n const range = this.max - this.min;\n const step = range / this.stops;\n return Math.round((value - this.min) / step) * step + this.min;\n }\n return value;\n }\n\n #setValueFromRelative(relativeValue: number, isUserInteraction = false): void {\n const newValue = scale(relativeValue, 0, 1, this.min, this.max);\n const clampedValue = this.#quantise(clamp(newValue, this.min, this.max));\n\n if (clampedValue === this.value)\n return;\n\n const previousValue = this.value;\n this.value = clampedValue;\n this.#isUserInteraction = isUserInteraction;\n\n // Update 'value' lane if it exists\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n valueLane.value = this.#getRelativeValue();\n }\n\n // Update data-tooltip for live tooltips\n if (this.hasAttribute(`data-tooltip-live`)) {\n const percentage = Math.round(this.#getRelativeValue() * 100);\n this.setAttribute(`data-tooltip`, `${percentage}%`);\n }\n\n // Fire input event only for user interactions\n if (isUserInteraction) {\n this.dispatchEvent(\n new CustomEvent<RadialInputInputDetail>(`input`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n // Debounce change event\n this.#scheduleChangeEvent(previousValue);\n } else {\n // Immediate change event for programmatic changes\n this.#fireChangeEvent(previousValue);\n }\n }\n\n #scheduleChangeEvent(previousValue: number): void {\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n\n this.#changeDebounceTimer = window.setTimeout(() => {\n this.#fireChangeEvent(previousValue);\n this.#changeDebounceTimer = undefined;\n }, 150);\n }\n\n #fireChangeEvent(previousValue: number): void {\n this.dispatchEvent(\n new CustomEvent<RadialInputChangeDetail>(`change`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n previousValue,\n },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // Pointer interaction handlers\n #onPointerDown = (event: PointerEvent): void => {\n if (this.disabled)\n return;\n\n event.preventDefault();\n const svg = this.renderRoot.querySelector(`svg`);\n svg?.focus();\n this.#dragging = true;\n this.#dragStartY = event.clientY;\n this.#valueAtDragStart = this.value;\n this.toggleAttribute(`dragging`, true);\n\n if (svg) {\n svg.setPointerCapture(event.pointerId);\n }\n\n window.addEventListener(`pointermove`, this.#onPointerMove);\n window.addEventListener(`pointerup`, this.#onPointerUp);\n window.addEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n #onPointerMove = (event: PointerEvent): void => {\n if (!this.#dragging)\n return;\n\n event.preventDefault();\n\n // Calculate sensitivity: full range = 2× component height\n const sensitivity = this.clientHeight * 2;\n const shiftDivisor = event.shiftKey ? KEY_STEP_DIVISOR : 1;\n const effectiveSensitivity = sensitivity * shiftDivisor;\n\n // Calculate delta (negative because up = increase)\n const deltaY = this.#dragStartY - event.clientY;\n const deltaValue = (deltaY / effectiveSensitivity) * (this.max - this.min);\n const newValue = this.#valueAtDragStart + deltaValue;\n\n const relativeValue = scale(newValue, this.min, this.max, 0, 1);\n this.#setValueFromRelative(clamp(relativeValue, 0, 1), true);\n };\n\n #onPointerUp = (): void => {\n this.#dragging = false;\n this.toggleAttribute(`dragging`, false);\n\n const svg = this.renderRoot.querySelector(`svg`);\n if (svg && `hasPointerCapture` in svg && typeof svg.hasPointerCapture === `function`) {\n if (svg.hasPointerCapture(1)) {\n svg.releasePointerCapture(1);\n }\n }\n\n window.removeEventListener(`pointermove`, this.#onPointerMove);\n window.removeEventListener(`pointerup`, this.#onPointerUp);\n window.removeEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n // Keyboard interaction handler\n #onKeyDown = (event: KeyboardEvent): void => {\n if (this.disabled)\n return;\n\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n\n let handled = false;\n\n switch (event.key) {\n case `ArrowUp`:\n case `ArrowRight`:\n this.#stepByRelativeDelta(effectiveStep / range, true);\n handled = true;\n break;\n\n case `ArrowDown`:\n case `ArrowLeft`:\n this.#stepByRelativeDelta(-effectiveStep / range, true);\n handled = true;\n break;\n\n case `Home`:\n this.#setValueFromRelative(0, true);\n handled = true;\n break;\n\n case `End`:\n this.#setValueFromRelative(1, true);\n handled = true;\n break;\n }\n\n if (handled) {\n event.preventDefault();\n }\n };\n\n /**\n * Apply a relative-delta nudge to the current value, clamped to [min, max] and\n * quantised. Shared between keyboard arrow keys and the wheel handler.\n */\n #stepByRelativeDelta(relativeDelta: number, isUserInteraction: boolean): void {\n this.#setValueFromRelative(\n clamp(this.#getRelativeValue() + relativeDelta, 0, 1),\n isUserInteraction,\n );\n }\n\n // Wheel handler — installed by WheelNudgeMixin on the host. Inverted from the\n // shared convention (`docs/infra-mousewheel.md`): wheel forward/up decreases\n // the value, wheel backward/down increases it. Matches the perceived\n // rotation of a physical rotary dial — turning the dial clockwise is the\n // most natural \"forward\" gesture and should reduce the value.\n override _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void {\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n this.#stepByRelativeDelta(-direction * effectiveStep / range, true);\n }\n\n // Rendering helpers\n #renderCircleBorder() {\n const path = generateCircleBorderPath(this.radius, this.flatten, CENTER);\n const borderWidth = this.#getCssVar(`--dial-border-width`, 2);\n const borderColor = getComputedStyle(this).getPropertyValue(`--dial-border-color`).trim() || `var(--surface-4)`;\n return svg`<path class=\"dial-border\" d=\"${path}\" fill=\"none\" stroke=\"${borderColor}\" stroke-width=\"${borderWidth}\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />`;\n }\n\n #renderCircleFill() {\n const path = generateCircleBorderPath(this.radius, this.flatten, CENTER);\n const fill = getComputedStyle(this).getPropertyValue(`--dial-fill`).trim() || `transparent`;\n return svg`<path class=\"dial-fill\" d=\"${path}\" fill=\"${fill}\" />`;\n }\n\n #renderWedge() {\n const relativeValue = this.#getRelativeValue();\n const { startAngle, endAngle, clockwise } = getWedgeAngles(\n relativeValue,\n this.valueMode,\n this.flatten,\n );\n\n const path = generateWedgePath(startAngle, endAngle, this.radius, CENTER, clockwise);\n if (!path)\n return svg``;\n\n return svg`<path class=\"wedge\" d=\"${path}\" />`;\n }\n\n #renderLane(lane: LaneData) {\n let arcPath = ``;\n\n if (lane.type === `fixed`) {\n // Fixed lanes always show full range\n arcPath = generateCircleBorderPath(\n this.radius - lane.offset * this.radius,\n this.flatten,\n CENTER,\n );\n } else if (lane.type === `anchored`) {\n // Anchored lanes: centered on current value, arc width based on lane.value\n const { startAngle, endAngle } = getAnchoredArcAngles(\n this.#getRelativeValue(),\n lane.value,\n this.valueMode,\n this.flatten,\n );\n arcPath = generateArcPath(\n startAngle,\n endAngle,\n this.radius - lane.offset * this.radius,\n CENTER,\n );\n } else {\n // Value lanes follow the value mode\n const { startAngle, endAngle } = getValueArcAngles(\n lane.value,\n this.valueMode,\n this.flatten,\n );\n arcPath = generateArcPath(\n startAngle,\n endAngle,\n this.radius - lane.offset * this.radius,\n CENTER,\n );\n }\n\n if (!arcPath)\n return svg``;\n\n return svg`\n <path \n class=\"lane\" \n data-lane-key=\"${lane.key}\" \n part=\"lane lane-${lane.key}\"\n d=\"${arcPath}\"\n style=\"\n stroke-width: calc(var(--lane-${lane.key}-width, var(--lane-width)) * ${this.radius}%);\n stroke-linecap: round;\n \"\n />\n `;\n }\n\n #getNeedlePath(angle: number, length: number, offset: number): string {\n const startRadius = offset * this.radius;\n const endRadius = length * this.radius;\n\n const start = {\n x: CENTER.x + Math.cos(angle) * startRadius,\n y: CENTER.y + Math.sin(angle) * startRadius,\n };\n const end = {\n x: CENTER.x + Math.cos(angle) * endRadius,\n y: CENTER.y + Math.sin(angle) * endRadius,\n };\n\n return `M ${start.x} ${start.y} L ${end.x} ${end.y}`;\n }\n\n #renderValueMarker(needlePath?: string) {\n const relativeValue = this.#getRelativeValue();\n const { angle, position } = getMarkerPosition(\n relativeValue,\n this.valueMode,\n this.flatten,\n this.radius,\n CENTER,\n );\n\n const markerOffset = this.#getCssVar(`--marker-offset`, 1);\n const markerBorderWidth = this.#getCssVar(`--marker-border-width`, 0);\n const effectiveStyle = this.#getEffectiveMarkerStyle();\n\n if (effectiveStyle === `dot`) {\n const size = this.#getCssVar(`--marker-thickness`, 0.15);\n const r = size * this.radius;\n const dotX = CENTER.x + (position.x - CENTER.x) * markerOffset;\n const dotY = CENTER.y + (position.y - CENTER.y) * markerOffset;\n\n if (markerBorderWidth > 0) {\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <use href=\"#dot-path\" class=\"marker-border\" />\n <use href=\"#dot-path\" class=\"marker-fill\" />\n </g>\n `;\n }\n\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <circle cx=\"${dotX}\" cy=\"${dotY}\" r=\"${r}\" />\n </g>\n `;\n } else if (effectiveStyle === `needle`) {\n if (markerBorderWidth > 0 && needlePath) {\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <use href=\"#needle-path\" class=\"marker-border\" />\n <use href=\"#needle-path\" class=\"marker-fill\" />\n </g>\n `;\n }\n\n const length = this.#getCssVar(`--marker-length`, 0.8);\n const offset = this.#getCssVar(`--marker-offset`, 0.2);\n const path = this.#getNeedlePath(angle, length, offset);\n\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <path d=\"${path}\" />\n </g>\n `;\n }\n }\n\n #renderMidpointMarker() {\n // Only show in bipolar/unipolar modes\n if (this.valueMode !== `bipolar` && this.valueMode !== `unipolar`) {\n return svg``;\n }\n\n const { position } = getMidpointPosition(this.radius, CENTER);\n\n if (this.markerStyle === `dot`) {\n const size = this.#getCssVar(`--midpoint-thickness`, 0.08);\n return svg`\n <g class=\"midpoint-marker\" part=\"midpoint-marker\">\n <circle \n cx=\"${position.x}\" \n cy=\"${position.y}\" \n r=\"${size * this.radius}\" \n />\n </g>\n `;\n } else {\n // Needle style\n const length = this.#getCssVar(`--midpoint-length`, 0.15);\n const offset = this.#getCssVar(`--midpoint-offset`, 0.85);\n\n const angle = -Math.PI / 2; // Top of circle\n const startRadius = offset * this.radius;\n const endRadius = (offset + length) * this.radius;\n\n const start = {\n x: CENTER.x + Math.cos(angle) * startRadius,\n y: CENTER.y + Math.sin(angle) * startRadius,\n };\n const end = {\n x: CENTER.x + Math.cos(angle) * endRadius,\n y: CENTER.y + Math.sin(angle) * endRadius,\n };\n\n return svg`\n <g class=\"midpoint-marker\" part=\"midpoint-marker\">\n <line \n x1=\"${start.x}\" \n y1=\"${start.y}\" \n x2=\"${end.x}\" \n y2=\"${end.y}\" \n />\n </g>\n `;\n }\n }\n\n #getCssVar(name: string, defaultValue: number): number {\n const style = getComputedStyle(this);\n const val = style.getPropertyValue(name).trim();\n if (!val)\n return defaultValue;\n\n // Handle CSS calc() expressions with var(--value-relative)\n if (val.includes(`calc(`)) {\n // Get the current --value-relative value\n const valueRelative = style.getPropertyValue(`--value-relative`).trim();\n if (!valueRelative) {\n // Fallback to default if --value-relative not set\n const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n\n // Replace var(--value-relative) with the actual value\n const evalStr = val.replace(/var\\(--value-relative\\)/g, valueRelative);\n\n // Use Function constructor for safe evaluation (no eval)\n try {\n // Create a function that evaluates math expressions\n // eslint-disable-next-line no-new-func\n const fn = new Function(`return ${evalStr.replace(/calc\\s*\\(([^)]+)\\)/g, `$1`)}`);\n const result = fn();\n return typeof result === `number` && !Number.isNaN(result) ? result : defaultValue;\n } catch {\n // Fallback: try to parse just numbers\n const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n }\n\n const parsed = Number.parseFloat(val);\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n\n // Lifecycle methods\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n\n // Ensure value lane reflects current value before first render\n // This handles declaratively set initial values\n if (changed.has(`value`) || !this.hasUpdated) {\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n valueLane.value = this.#getRelativeValue();\n }\n }\n }\n\n override render(): unknown {\n const lanes = Array.from(this.#lanes.values());\n\n const relativeValue = this.#getRelativeValue();\n const { angle, position } = getMarkerPosition(\n relativeValue,\n this.valueMode,\n this.flatten,\n this.radius,\n CENTER,\n );\n\n const needleLength = this.#getCssVar(`--marker-length`, 0.8);\n const needleOffset = this.#getCssVar(`--marker-offset`, 0.2);\n const markerBorderWidth = this.#getCssVar(`--marker-border-width`, 0);\n const needlePath = markerBorderWidth > 0 ? this.#getNeedlePath(angle, needleLength, needleOffset) : undefined;\n\n const dotSize = this.#getCssVar(`--marker-thickness`, 0.15);\n const dotR = dotSize * this.radius;\n\n const defs = [];\n if (needlePath) {\n defs.push(svg`<path id=\"needle-path\" d=\"${needlePath}\" />`);\n }\n if (markerBorderWidth > 0) {\n defs.push(svg`<circle id=\"dot-path\" cx=\"${position.x}\" cy=\"${position.y}\" r=\"${dotR}\" />`);\n }\n\n return html`\n <svg\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"xMidYMid meet\"\n tabindex=\"${this.disabled ? -1 : 0}\"\n @pointerdown=\"${this.#onPointerDown}\"\n @keydown=\"${this.#onKeyDown}\"\n style=\"cursor: ${this.#dragging ? `ns-resize` : `grab`}\"\n >\n ${defs.length > 0 ? svg`<defs>${defs}</defs>` : ``}\n ${this.#renderCircleFill()}\n ${this.wedge ? this.#renderWedge() : ``}\n ${this.#renderCircleBorder()}\n ${lanes.map(lane => this.#renderLane(lane))}\n ${this.#renderMidpointMarker()}\n ${this.#renderValueMarker(needlePath)}\n </svg>\n `;\n }\n\n protected override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n // Update --radius CSS variable when property changes\n if (changed.has(`radius`)) {\n this.style.setProperty(`--radius`, `${this.radius}%`);\n }\n\n // Update --value-relative CSS variable\n this.style.setProperty(`--value-relative`, this.#getRelativeValue().toString());\n\n // Adjust component height based on flatten to reduce wasted vertical space.\n // The dial is flattened at the top, so we don't need full height.\n if (changed.has(`flatten`)) {\n const markerThickness = this.#getCssVar(`--marker-thickness`, 0.15);\n const radius = this.#getCssVar(`--radius`, 45);\n const markerPadding = Math.round(markerThickness * radius) + 5;\n const viewBoxHeight = Math.round(100 * (1 - this.flatten)) + markerPadding;\n // Set CSS variable to control host height\n this.style.setProperty(`--dial-height`, `${viewBoxHeight}px`);\n // Also update SVG viewBox to match\n const svg = this.renderRoot.querySelector(`svg`);\n if (svg) {\n svg.setAttribute(`viewBox`, `0 0 100 ${viewBoxHeight}`);\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n this.#onPointerUp();\n }\n\n override firstUpdated(): void {\n const markerThickness = this.#getCssVar(`--marker-thickness`, 0.15);\n const radius = this.#getCssVar(`--radius`, 45);\n const markerPadding = Math.round(markerThickness * radius);\n const viewBoxHeight = Math.round(100 * (1 - this.flatten)) + markerPadding;\n this.style.setProperty(`--dial-height`, `${viewBoxHeight}px`);\n const svg = this.renderRoot.querySelector(`svg`);\n if (svg) {\n svg.setAttribute(`viewBox`, `0 0 100 ${viewBoxHeight}`);\n }\n }\n\n static override styles = [themeFallbacks, prominenceStyles, css`\n :host {\n display: inline-block;\n width: 100px;\n height: var(--dial-height, 100px);\n touch-action: none;\n user-select: none;\n tabindex: 0;\n\n /* Dynamic value - set by JS */\n --value-relative: 0;\n\n /* Lane widths (used in stroke-width calculations) */\n --lane-width: 0.16;\n --lane-track-width: 0.08;\n --lane-value-width: 0.12;\n }\n\n :host([disabled]) {\n cursor: not-allowed;\n }\n\n svg {\n width: 100%;\n height: 100%;\n outline: none;\n }\n\n svg:active {\n cursor: grabbing;\n }\n\n svg:focus-visible {\n outline: var(--radial-input-svg-focus-outline, 2px solid var(--accent));\n outline-offset: var(--radial-input-svg-focus-outline-offset, 2px);\n }\n\n .dial-border {\n fill: none;\n stroke: var(--dial-border-color, var(--surface-4));\n stroke-width: var(--dial-border-width, 2px);\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .dial-fill {\n fill: var(--dial-fill, transparent);\n }\n\n .wedge {\n fill: var(--wedge-fill, var(--accent));\n fill-opacity: var(--wedge-fill-opacity, 0.25);\n stroke: var(--wedge-border-color, var(--accent));\n stroke-width: var(--wedge-border-width, 0);\n stroke-opacity: var(--wedge-border-opacity, 1);\n vector-effect: non-scaling-stroke;\n }\n\n .lane {\n fill: none;\n stroke-linecap: round;\n stroke-dasharray: var(--lane-dasharray, none);\n stroke-dashoffset: var(--lane-dashoffset, 0);\n vector-effect: non-scaling-stroke;\n }\n\n .lane[data-lane-key='track'] {\n stroke: var(--lane-track-color, var(--surface-4));\n }\n\n .lane[data-lane-key='value'] {\n stroke: var(--lane-value-color, var(--accent));\n }\n\n .lane:not([data-lane-key='track']):not([data-lane-key='value']) {\n stroke: var(--lane-color, var(--accent));\n }\n\n .value-marker path,\n .value-marker .marker-fill {\n stroke: var(--marker-color, var(--accent));\n stroke-width: calc(var(--marker-thickness, 0.15) * var(--radius, 45%));\n stroke-linecap: round;\n stroke-dasharray: var(--marker-dasharray, none);\n stroke-dashoffset: var(--marker-dashoffset, 0);\n vector-effect: non-scaling-stroke;\n }\n\n .value-marker .marker-border {\n stroke: var(--marker-border-color, transparent);\n stroke-width: calc((var(--marker-thickness, 0.15) + var(--marker-border-width, 0) * 2) * var(--radius, 45%));\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .value-marker .marker-border {\n fill: none;\n }\n\n .value-marker .marker-fill,\n .value-marker circle {\n fill: var(--marker-color, var(--accent));\n }\n\n .midpoint-marker line {\n stroke: var(--midpoint-color, var(--surface-muted-text));\n stroke-width: var(--midpoint-thickness, 1px);\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .midpoint-marker circle {\n fill: var(--midpoint-color, var(--surface-muted-text));\n stroke: var(--midpoint-border-color, transparent);\n stroke-width: var(--midpoint-border-width, 0);\n vector-effect: non-scaling-stroke;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-radial-input': RadialInputElement;\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"range-input.d.ts","names":[],"sources":["../src/range-input/range-input.ts"],"mappings":";;;;;cA4Ea,mBAAmB;EACF;EACA;EACA;EACA;EACe;EACC;EACf;EACiC,oBAAoB;EAClD,kBAAkB,kBAAkB;EAGpE,UAAW;EAGX,aAAa;;UAGL;EAEC;EAQA;UASD;UAWA;UASA;UASA;UAMA;UAQA;UAOA;EAOC,QAAQ,mBAAmB;EAgBpC,eAAgB,GAAG;EAUnB;EAQA;;;;;;;;;;EAcS,iBAAiB,WAAW,gBAAgB,QAAQ;EAepD,wBAAM;SA4BR,QAAQ;;QA2RT;YACI;IACR,oBAAoB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"range-input.js","names":["customElement"],"sources":["../src/range-input/range-input.ts"],"sourcesContent":["/**\n * <ixfx-range-input> — styled range input with no label.\n *\n * A thin wrapper around <input type=\"range\"> that adds the same\n * fancy track/thumb/fill styling as the linear-value components,\n * without the label display.\n *\n * Supports horizontal (default) and vertical orientation in a single element.\n * Set orientation=\"vertical\" attribute to switch.\n *\n * CSS Variables:\n * --track-thickness Track cross-axis size (default 1.5em)\n * --thumb-color Thumb fill (default var(--surface-2-text))\n * --thumb-color-active Thumb fill on hover/active (default var(--accent))\n * --thumb-size Thumb cross-axis size (default var(--track-thickness))\n * --thumb-thickness Thumb inline size (default 2em)\n * --thumb-radius Thumb border-radius (default 0)\n * --thumb-border Thumb border (default none)\n * --thumb-shadow Thumb box-shadow (default none)\n * --background-track Unfilled track background (default var(--surface-4))\n * --background-track-hover Unfilled track on hover (default --background-track)\n * --background-track-value Filled track color (default var(--surface-6))\n * --background-track-value-hover Filled track on hover (default var(--accent))\n * --background-track-value-active Filled track on active (default var(--accent))\n *\n * Optional vertical-specific overrides (fall back to horizontal vars when unset):\n * --background-track-vertical\n * --background-track-value-vertical\n * --background-track-value-hover-vertical\n * --background-track-value-active-vertical\n *\n * Tooltip:\n * tooltip Boolean attribute — enables value tooltip on hover/focus\n * tooltip-orientation 'top' (default) | 'right'\n * labelFormatter Function property (not attribute): (rawValue: number, scaledValue: number) => string\n * rawValue = native input value within min..max\n * scaledValue = normalised 0..1 position\n *\n * Swipeable mode:\n * swipeable Boolean attribute — enables swipe-to-draw gesture.\n * When active, pressing down on the slider or entering it while the\n * pointer is pressed sets the value from the cursor coordinate.\n * Pointer capture is NOT held, so the cursor can move to adjacent\n * swipeable sliders and update them too (step-sequencer style).\n * Kill-axis exit (above/below for horizontal, left/right for vertical)\n * freezes the value; re-entering re-engages.\n *\n * Wheel:\n * lighttouch Boolean attribute — wheel adjusts the value on hover instead\n * of requiring focus. The native `<input type=\"range\">` inside\n * already responds to wheel when focused; the host listener\n * fires under `lighttouch` (or when focus is on the host) and\n * synthesises a value change via `input`/`change` events.\n * See `docs/infra-mousewheel.md`.\n *\n * Events:\n * input — CustomEvent<{ value: number }>\n * change — CustomEvent<{ value: number }>\n * In swipeable mode fires on pointerleave (or pointerup if released\n * while still inside). In normal mode delegates to native change.\n */\nimport type { CSSResultGroup } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport type { TooltipElement, TooltipOrientations } from '../util/tooltip.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { tooltipValueStyles } from '../styles/tooltip.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nfunction normalize(value: number, min: number, max: number): number {\n return max === min ? 0 : (value - min) / (max - min);\n}\n\n@customElement(`ixfx-range-input`)\nexport class RangeInput extends WheelNudgeMixin(LitElement) {\n @property({ type: Number }) min = 0;\n @property({ type: Number }) max = 1;\n @property({ type: Number }) value = 0;\n @property({ type: Number }) step = 0.01;\n @property({ type: String, reflect: true }) orientation: `horizontal` | `vertical` = `horizontal`;\n @property({ type: Boolean, reflect: true }) swipeable = false;\n @property({ type: Boolean }) tooltip = false;\n @property({ type: String, attribute: `tooltip-orientation` }) tooltipOrientation: TooltipOrientations = `top`;\n @property({ attribute: false }) labelFormatter?: (rawValue: number, scaledValue: number) => string;\n\n @query(`input`)\n _inputEl!: HTMLInputElement;\n\n @query(`ixfx-tooltip`)\n _tooltipEl?: TooltipElement | null;\n\n /** True if this slider changed its value during the current pointer visit. */\n private _swipeModified = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener(`pointerdown`, this._onPointerDown);\n this.addEventListener(`pointermove`, this._onPointerMove);\n this.addEventListener(`pointerenter`, this._onPointerEnter);\n this.addEventListener(`pointerleave`, this._onPointerLeave);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`pointerdown`, this._onPointerDown);\n this.removeEventListener(`pointermove`, this._onPointerMove);\n this.removeEventListener(`pointerenter`, this._onPointerEnter);\n this.removeEventListener(`pointerleave`, this._onPointerLeave);\n window.removeEventListener(`pointerup`, this._onWindowPointerUp);\n }\n\n private _valueFromPointer(e: PointerEvent): number {\n const rect = this.getBoundingClientRect();\n // vertical: top = max, bottom = min (writing-mode: vertical-rl; direction: rtl)\n const normalized = this.orientation === `vertical`\n ? Math.max(0, Math.min(1, 1 - (e.clientY - rect.top) / rect.height))\n : Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n const raw = this.min + normalized * (this.max - this.min);\n const snapped = Math.round((raw - this.min) / this.step) * this.step + this.min;\n return Math.max(this.min, Math.min(this.max, snapped));\n }\n\n private _applySwipeValue(value: number): void {\n this.value = value;\n if (this._inputEl)\n this._inputEl.value = String(value);\n this.style.setProperty(`--value`, String(normalize(value, this.min, this.max)));\n this.dispatchEvent(new CustomEvent(`input`, { detail: { value }, bubbles: true, composed: true }));\n this._swipeModified = true;\n }\n\n private _onPointerDown = (e: PointerEvent): void => {\n if (!this.swipeable)\n return;\n e.preventDefault();\n this._swipeModified = false;\n this._applySwipeValue(this._valueFromPointer(e));\n window.addEventListener(`pointerup`, this._onWindowPointerUp, { once: true });\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!this.swipeable || e.buttons === 0)\n return;\n this._applySwipeValue(this._valueFromPointer(e));\n };\n\n private _onPointerEnter = (e: PointerEvent): void => {\n if (!this.swipeable || e.buttons === 0)\n return;\n this._swipeModified = false;\n this._applySwipeValue(this._valueFromPointer(e));\n window.addEventListener(`pointerup`, this._onWindowPointerUp, { once: true });\n };\n\n private _onPointerLeave = (_e: PointerEvent): void => {\n if (!this.swipeable || !this._swipeModified)\n return;\n this._swipeModified = false;\n this.dispatchEvent(new CustomEvent(`change`, { detail: { value: this.value }, bubbles: true, composed: true }));\n };\n\n private _onWindowPointerUp = (): void => {\n if (!this._swipeModified)\n return;\n this._swipeModified = false;\n this.dispatchEvent(new CustomEvent(`change`, { detail: { value: this.value }, bubbles: true, composed: true }));\n };\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has(`value`) || changedProperties.has(`min`) || changedProperties.has(`max`)) {\n this.style.setProperty(`--value`, String(normalize(this.value, this.min, this.max)));\n }\n if (this._tooltipEl) {\n this._tooltipEl.valueFormatTooltip = (v: unknown) => {\n const num = typeof v === `number` ? v : Number(v);\n if (this.labelFormatter)\n return this.labelFormatter(num, normalize(num, this.min, this.max));\n const decimals = this.step >= 1 ? 0 : this.step >= 0.1 ? 1 : 2;\n return num.toFixed(decimals);\n };\n }\n }\n\n _handleInput = (e: Event): void => {\n e.preventDefault();\n e.stopImmediatePropagation();\n const target = e.target as HTMLInputElement;\n const value = Number.parseFloat(target.value);\n this.value = value;\n this.style.setProperty(`--value`, String(normalize(value, this.min, this.max)));\n this.dispatchEvent(new CustomEvent(`input`, { detail: { value }, bubbles: true, composed: true }));\n };\n\n _formatTooltipLabel(): string {\n const normalized = normalize(this.value, this.min, this.max);\n if (this.labelFormatter)\n return this.labelFormatter(this.value, normalized);\n const decimals = this.step >= 1 ? 0 : this.step >= 0.1 ? 1 : 2;\n return this.value.toFixed(decimals);\n }\n\n _handleChange = (): void => {\n const value = Number.parseFloat(this._inputEl.value);\n this.dispatchEvent(new CustomEvent(`change`, { detail: { value }, bubbles: true, composed: true }));\n };\n\n /**\n * Wheel handler — installed by WheelNudgeMixin on the host. Synthesises a\n * value change by writing to the inner `<input type=\"range\">` and dispatching\n * `input` + `change`, so the existing `_handleInput` and `_handleChange`\n * handlers run unchanged and re-bubble the events to listeners.\n *\n * Native wheel handling is left intact for the focused-inner-input case;\n * the host listener fires under `lighttouch` or when focus is on the host.\n */\n override _applyWheelDelta(direction: WheelDirection, _event: WheelEvent): void {\n const input = this._inputEl;\n if (!input)\n return;\n const step = this.step > 0 ? this.step : Math.max((this.max - this.min) / 100, 0.01);\n const candidate = this.value + direction * step;\n const clamped = Math.min(this.max, Math.max(this.min, candidate));\n if (clamped === this.value)\n return;\n\n input.value = String(clamped);\n input.dispatchEvent(new CustomEvent(`input`, { detail: { value: clamped }, bubbles: true }));\n input.dispatchEvent(new CustomEvent(`change`, { detail: { value: clamped }, bubbles: true }));\n }\n\n override render() {\n const tooltipEl = this.tooltip\n ? html`\n <ixfx-tooltip\n style=\"--tooltip-background: var(--surface-5); --tooltip-color: var(--surface-5-text)\"\n .orientation=${this.tooltipOrientation}\n anchor=\"--ixfx-ri-thumb\"\n .value=${this.value}\n ></ixfx-tooltip>\n `\n : nothing;\n\n return html`\n <div class=\"wrap\">\n <div class=\"range-bg\"></div>\n <input\n type=\"range\"\n .min=${String(this.min)}\n .max=${String(this.max)}\n .step=${String(this.step)}\n .value=${String(this.value)}\n @input=${this._handleInput}\n @change=${this._handleChange}\n >${tooltipEl}\n </div>\n `;\n }\n\n static styles: CSSResultGroup = [themeFallbacks, tooltipValueStyles, css`\n :host {\n display: block;\n container-type: size;\n user-select: none;\n touch-action: none;\n -webkit-touch-action: none;\n width: var(--width, 200px);\n height: var(--height, 2em);\n\n /*\n * Internal resolved vars — read public vars and apply defaults here.\n * Public vars are NOT defined in :host {}, only read via fallback.\n * This lets inherited values from ancestor elements flow through.\n */\n --_track-thickness: var(--track-thickness, 100%);\n --_thumb-thickness: var(--thumb-thickness, 2em);\n --_thumb-color: var(--thumb-color, var(--surface-2-text));\n --_thumb-color-active: var(--thumb-color-active, var(--surface-2-text));\n --_thumb-opacity: var(--thumb-opacity, 0.7);\n --_thumb-opacity-hover: var(--thumb-opacity-hover, 0.8);\n --_thumb-opacity-active: var(--thumb-opacity-active, 1); \n --_thumb-size: var(--thumb-size, var(--_track-thickness));\n --_thumb-radius: var(--thumb-radius, 0);\n --_thumb-border: var(--thumb-border, none);\n --_thumb-shadow: var(--thumb-shadow, none);\n --_track-radius: var(--track-radius, none);\n --_track-corner-shape: var(--track-corner-shape, none);\n --_bg-track: var(--background-track, var(--surface-4));\n --_bg-track-hover: var(--background-track-hover, var(--_bg-track));\n --_bg-track-value: var(--background-track-value, var(--surface-6));\n --_bg-track-value-hover: var(--background-track-value-hover, var(--accent));\n --_bg-track-value-active: var(--background-track-value-active, var(--accent));\n\n --value: 0;\n --sx1: calc(var(--_thumb-thickness) + var(--value) * (100% - var(--_thumb-thickness)));\n --track-avail: calc(100% - var(--_thumb-thickness));\n --sx: calc(var(--_thumb-thickness) + (var(--value) * var(--track-avail)));\n --track-mask: linear-gradient(to right, rgba(0,0,0,1) var(--sx), rgba(0,0,0,0) var(--sx) 100%);\n --track-mask-vertical: linear-gradient(to top, rgba(0,0,0,1) var(--sx), rgba(0,0,0,0) var(--sx) 100%);\n }\n\n :host([orientation=\"vertical\"]) {\n width: var(--width, 2em);\n height: var(--height, 200px);\n }\n\n .wrap {\n display: grid;\n width: 100%;\n height: 100%;\n }\n\n .wrap > * {\n grid-area: 1 / 1;\n }\n\n .range-bg {\n background: var(--_bg-track);\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n border-radius: var(--_track-radius);\n corner-shape: var(--_track-corner-shape);\n }\n\n .wrap:hover .range-bg {\n background: var(--_bg-track-hover);\n }\n\n input[type=range] {\n margin: 0;\n padding: 0;\n -webkit-appearance: none;\n background: unset;\n box-shadow: none;\n width: 100%;\n height: var(--_track-thickness);\n align-self: center;\n }\n\n input[type=range]:focus {\n outline: none;\n }\n\n /* Vertical layout */\n :host([orientation=\"vertical\"]) .range-bg {\n background: var(--background-track-vertical, var(--_bg-track));\n width: var(--_track-thickness);\n height: 100%;\n justify-self: center;\n }\n\n :host([orientation=\"vertical\"]) .wrap:hover .range-bg {\n background: var(--background-track-hover-vertical, var(--_bg-track-hover));\n }\n\n :host([orientation=\"vertical\"]) input[type=range] {\n writing-mode: vertical-rl;\n direction: rtl;\n width: var(--_track-thickness);\n height: 100%;\n justify-self: center;\n }\n\n /* ── Webkit thumb ── */\n input[type=range]::-webkit-slider-thumb {\n -webkit-appearance: none;\n opacity: var(--_thumb-opacity);\n box-sizing: border-box;\n anchor-name: --ixfx-ri-thumb;\n width: var(--_thumb-thickness);\n height: var(--_thumb-size);\n border-radius: var(--_thumb-radius);\n background: var(--_thumb-color);\n border: var(--_thumb-border);\n box-shadow: var(--_thumb-shadow);\n margin-top: calc(max((var(--_thumb-thickness) - 1px - 1px) * 0.5, 0px) - var(--_thumb-thickness) * 0.5);\n }\n\n :host([orientation=\"vertical\"]) input[type=range]::-webkit-slider-thumb {\n width: var(--_thumb-size);\n height: var(--_thumb-thickness);\n margin-top: 0;\n margin-left: calc(max((1em - 1px - 1px) * 0.5, 0px) - 1.2em * 0.5);\n }\n\n input[type=range]::-webkit-slider-thumb:hover {\n opacity: var(--_thumb-opacity-hover);\n }\n\n input[type=range]::-webkit-slider-thumb:active {\n opacity: var(--_thumb-opacity-active);\n }\n input[type=range]::-webkit-slider-thumb:hover,\n input[type=range]::-webkit-slider-thumb:active {\n background: var(--_thumb-color-active);\n }\n\n /* ── Webkit track ── */\n input[type=range]::-webkit-slider-runnable-track {\n height: var(--_track-thickness);\n background: var(--_bg-track-value);\n mask-image: var(--track-mask);\n box-shadow: none;\n margin: 0;\n padding: 0;\n border-radius: var(--_track-radius);\n corner-shape: var(--_track-corner-shape);\n }\n\n input[type=range]:hover::-webkit-slider-runnable-track {\n background: var(--_bg-track-value-hover);\n mask-image: var(--track-mask);\n }\n\n input[type=range]:active::-webkit-slider-runnable-track {\n background: var(--_bg-track-value-active);\n mask-image: var(--track-mask);\n }\n\n :host([orientation=\"vertical\"]) input[type=range]::-webkit-slider-runnable-track {\n background: var(--background-track-value-vertical, var(--_bg-track-value));\n mask-image: var(--track-mask-vertical);\n width: var(--_track-thickness);\n height: unset;\n }\n\n :host([orientation=\"vertical\"]) input[type=range]:hover::-webkit-slider-runnable-track {\n background: var(--background-track-value-hover-vertical, var(--_bg-track-value-hover));\n mask-image: var(--track-mask-vertical);\n }\n\n :host([orientation=\"vertical\"]) input[type=range]:active::-webkit-slider-runnable-track {\n background: var(--background-track-value-active-vertical, var(--_bg-track-value-active));\n mask-image: var(--track-mask-vertical);\n }\n\n /* ── Mozilla thumb ── */\n input[type=range]::-moz-range-thumb {\n box-sizing: border-box;\n width: var(--_thumb-thickness);\n height: var(--_thumb-size);\n border-radius: var(--_thumb-radius);\n background: var(--_thumb-color);\n border: var(--_thumb-border);\n box-shadow: var(--_thumb-shadow);\n }\n\n :host([orientation=\"vertical\"]) input[type=range]::-moz-range-thumb {\n width: var(--_thumb-size);\n height: var(--_thumb-thickness);\n }\n\n input[type=range]::-moz-range-thumb:hover,\n input[type=range]::-moz-range-thumb:active {\n background: var(--_thumb-color-active);\n }\n\n /* ── Mozilla track ── */\n input[type=range]::-moz-range-track {\n height: var(--_track-thickness);\n background: var(--_bg-track-value);\n mask-image: var(--track-mask);\n box-shadow: none;\n margin: 0;\n padding: 0;\n }\n\n input[type=range]:hover::-moz-range-track {\n background: var(--_bg-track-value-hover);\n mask-image: var(--track-mask);\n }\n\n input[type=range]:active::-moz-range-track {\n background: var(--_bg-track-value-active);\n mask-image: var(--track-mask);\n }\n\n :host([orientation=\"vertical\"]) input[type=range]::-moz-range-track {\n background: var(--background-track-value-vertical, var(--_bg-track-value));\n mask-image: var(--track-mask-vertical);\n height: unset;\n width: var(--_track-thickness);\n }\n\n :host([orientation=\"vertical\"]) input[type=range]:hover::-moz-range-track {\n background: var(--background-track-value-hover-vertical, var(--_bg-track-value-hover));\n mask-image: var(--track-mask-vertical);\n }\n\n :host([orientation=\"vertical\"]) input[type=range]:active::-moz-range-track {\n background: var(--background-track-value-active-vertical, var(--_bg-track-value-active));\n mask-image: var(--track-mask-vertical);\n }\n\n /* ── Swipeable mode ── */\n /* Disable native pointer capture so the cursor can move freely between sliders */\n :host([swipeable]) input {\n pointer-events: none;\n }\n\n /* In swipeable mode, disable pointer events on wrap so host receives hover */\n :host([swipeable]) .wrap {\n pointer-events: none;\n }\n\n /* In swipeable mode, use host hover to trigger track/thumb hover styles */\n :host([swipeable]):hover input[type=range]::-webkit-slider-runnable-track {\n background: var(--_bg-track-value-hover);\n }\n\n :host([swipeable]):hover input[type=range]::-webkit-slider-thumb {\n background: var(--_thumb-color-active);\n }\n\n :host([swipeable][orientation=\"vertical\"]):hover input[type=range]::-webkit-slider-runnable-track {\n background: var(--background-track-value-hover-vertical, var(--_bg-track-value-hover));\n }\n\n :host([swipeable]):hover input[type=range]::-moz-range-track {\n background: var(--_bg-track-value-hover);\n }\n\n :host([swipeable]):hover input[type=range]::-moz-range-thumb {\n background: var(--_thumb-color-active);\n }\n\n :host([swipeable][orientation=\"vertical\"]):hover input[type=range]::-moz-range-track {\n background: var(--background-track-value-hover-vertical, var(--_bg-track-value-hover));\n }\n\n :host([swipeable]):hover .range-bg {\n background: var(--_bg-track-hover);\n }\n\n :host([swipeable][orientation=\"vertical\"]):hover .range-bg {\n background: var(--background-track-hover-vertical, var(--_bg-track-hover));\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-range-input': RangeInput;\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"range.d.ts","names":[],"sources":["../src/range/range.ts"],"mappings":";;;;;cAWa,qBAAqB;;EAEhC;EAGA,oBAAoB;EAGpB;EAGA;EAGA;EAGA;MAGI,MAAM;MAIN;EAOJ;EAEA,aAAa,OAAO;;;;;;;;;;EAwBX,iBAAiB,WAAW,gBAAgB,QAAQ;YAenD;SAiBH,sBAAM;;QAmEP;YACI;IACR,cAAc"}
package/dist/range.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"range.js","names":["#value","customElement"],"sources":["../src/range/range.ts"],"sourcesContent":["import type { WheelDirection } from \"../mixins/wheel-nudge.js\";\nimport type { TooltipOrientations } from \"../util/tooltip.js\";\nimport { css, html, LitElement, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { WheelNudgeMixin } from \"../mixins/wheel-nudge.js\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { prominenceStyles } from \"../styles/prominence.js\";\nimport { tooltipValueStyles } from \"../styles/tooltip.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\n\n@customElement(`ixfx-range`)\nexport class RangeElement extends WheelNudgeMixin(LitElement) {\n @property({ type: Boolean })\n tooltip = true;\n\n @property({ type: String, attribute: `tooltip-orientation` })\n tooltipOrientation: TooltipOrientations = `top`;\n\n @property({ type: String, reflect: true })\n orientation: `horizontal` | `vertical` = `horizontal`;\n\n @property({ type: Boolean, attribute: true })\n disabled = false;\n\n @property({ type: Number })\n min = 0;\n\n @property({ type: Number })\n max = 100;\n\n @property({ type: Number })\n set value(v: number) {\n this.#value = v;\n }\n\n get value() {\n return this.#value;\n }\n\n #value = 0;\n\n @property({ type: Number })\n step = 0;\n\n onRangeInput(event: InputEvent) {\n const valueNum = (event.target as HTMLInputElement).valueAsNumber;\n const valueStr = (event.target as HTMLInputElement).value;\n this.#value = valueNum;\n\n if (this.tooltip) {\n const o = this.shadowRoot?.querySelector(`output`);\n if (o) {\n o.value = valueStr;\n } else {\n console.warn(`Output element not found`);\n }\n }\n }\n\n /**\n * Wheel handler — installed by WheelNudgeMixin on the host. Synthesises a\n * value change by writing to the inner `<input type=\"range\">` and dispatching\n * `input` + `change`, so the existing `onRangeInput` handler runs unchanged.\n *\n * The native input still responds to wheel when focused (focus rule wins by\n * default). The host handler fires when `lighttouch` is set or when the host\n * itself has focus, ensuring Shift-aware step math and consistent event firing.\n */\n override _applyWheelDelta(direction: WheelDirection, _event: WheelEvent): void {\n const input = this.renderRoot?.querySelector(`input[type=range]`) as HTMLInputElement | null;\n if (!input)\n return;\n const step = this.step > 0 ? this.step : Math.max((this.max - this.min) / 100, 0.01);\n const candidate = this.#value + direction * step;\n const clamped = Math.min(this.max, Math.max(this.min, candidate));\n if (clamped === this.#value)\n return;\n\n input.value = String(clamped);\n input.dispatchEvent(new Event(`input`, { bubbles: true }));\n input.dispatchEvent(new Event(`change`, { bubbles: true }));\n }\n\n protected render(): unknown {\n const tt = this.tooltip\n ? html`<ixfx-tooltip\n style=\"--tooltip-background: var(--surface-5); --tooltip-color: var(--surface-5-text)\"\n .orientation=${this.tooltipOrientation}\n anchor=\"--thumb-tooltip\"\n .value=${this.value}></ixfx-tooltip>`\n : nothing;\n const verticalStyle = this.orientation === `vertical`\n ? `writing-mode: vertical-lr; direction: rtl;`\n : nothing;\n return html`\n <input ?disabled=${this.disabled} step=${this.step} min=${this.min} max=${this.max} value=${this.value} @input=${this.onRangeInput} type=\"range\" style=${verticalStyle}>\n ${tt}\n `;\n }\n\n static styles = [\n themeFallbacks,\n prominenceStyles,\n tooltipValueStyles,\n css`\n :host {\n display: inline-block;\n --value-label-color: unset;\n --thumb-background: ButtonFace;\n --thumb-radius: 50%;\n --thumb-width: 1em;\n --thumb-height: 1em;\n }\n\n :host([orientation=\"vertical\"]) {\n display: block;\n width: 1.5em;\n height: 200px;\n }\n\n [type=\"range\"] {\n width: 100%;\n height: 1.5em;\n accent-color: var(--accent, AccentColor);\n }\n\n :host([orientation=\"vertical\"]) [type=\"range\"] {\n writing-mode: vertical-lr;\n direction: rtl;\n width: 1.5em;\n height: 100%;\n }\n\n [type=\"range\"]::-webkit-slider-thumb {\n width: var(--thumb-width);\n height: var(--thumb-height);\n border-radius: var(--thumb-radius);\n background: var(--thumb-background);\n anchor-name: --thumb-tooltip;\n }\n\n :host([orientation=\"vertical\"]) [type=\"range\"]::-webkit-slider-thumb {\n width: var(--thumb-height);\n height: var(--thumb-width);\n }\n\n [type=\"range\"]::-moz-range-thumb {\n width: var(--thumb-width);\n height: var(--thumb-height);\n border-radius: var(--thumb-radius);\n background: var(--thumb-background);\n box-shadow: var(--shadow-m);\n anchor-name: --thumb-tooltip;\n }\n\n :host([orientation=\"vertical\"]) [type=\"range\"]::-moz-range-thumb {\n width: var(--thumb-height);\n height: var(--thumb-width);\n }\n\n [type=\"range\"]:focus {\n outline: none;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementMap {\n \"ixfx-range\": RangeElement;\n }\n}\n"],"mappings":";;;;;;;;AAWO,IAAM,eAAN,MAAM,qBAAqB,gBAAgB,UAAU,CAAC,CAAC;;;EAElD,KAAA,UAAA;EAGgC,KAAA,qBAAA;EAGD,KAAA,cAAA;EAG9B,KAAA,WAAA;EAGL,KAAA,MAAA;EAGA,KAAA,MAAA;EAWG,KAAA,SAAA;EAGF,KAAA,OAAA;;CAZP,IACI,MAAM,GAAW;EACnB,KAAKA,SAAS;CAChB;CAEA,IAAI,QAAQ;EACV,OAAO,KAAKA;CACd;CAEA;CAKA,aAAa,OAAmB;EAC9B,MAAM,WAAY,MAAM,OAA4B;EACpD,MAAM,WAAY,MAAM,OAA4B;EACpD,KAAKA,SAAS;EAEd,IAAI,KAAK,SAAS;GAChB,MAAM,IAAI,KAAK,YAAY,cAAc,QAAQ;GACjD,IAAI,GACF,EAAE,QAAQ;QAEV,QAAQ,KAAK,0BAA0B;EAE3C;CACF;;;;;;;;;;CAWA,iBAA0B,WAA2B,QAA0B;EAC7E,MAAM,QAAQ,KAAK,YAAY,cAAc,mBAAmB;EAChE,IAAI,CAAC,OACH;EACF,MAAM,OAAO,KAAK,OAAO,IAAI,KAAK,OAAO,KAAK,KAAK,KAAK,MAAM,KAAK,OAAO,KAAK,GAAI;EACnF,MAAM,YAAY,KAAKA,SAAS,YAAY;EAC5C,MAAM,UAAU,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,SAAS,CAAC;EAChE,IAAI,YAAY,KAAKA,QACnB;EAEF,MAAM,QAAQ,OAAO,OAAO;EAC5B,MAAM,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;EACzD,MAAM,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;CAC5D;CAEA,SAA4B;EAC1B,MAAM,KAAK,KAAK,UACZ,IAAI;;yBAEa,KAAK,mBAAmB;;mBAE9B,KAAK,MAAM,oBACtB;EACJ,MAAM,gBAAgB,KAAK,gBAAgB,aACvC,+CACA;EACJ,OAAO,IAAI;yBACU,KAAK,SAAS,QAAQ,KAAK,KAAK,OAAO,KAAK,IAAI,OAAO,KAAK,IAAI,SAAS,KAAK,MAAM,UAAU,KAAK,aAAa,sBAAsB,cAAc;QACrK,GAAG;;CAET;;EAEgB,KAAA,SAAA;GACd;GACA;GACA;GACA,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4DL;;AACF;AAzJG,WAAA,CAAA,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,aAAA,WAAA,WAAA,KAAA,CAAA;AAG1B,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAsB,CAAC,CAAA,GAAA,aAAA,WAAA,sBAAA,KAAA,CAAA;AAG3D,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,aAAA,WAAA,eAAA,KAAA,CAAA;AAGxC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;AAAK,CAAC,CAAA,GAAA,aAAA,WAAA,YAAA,KAAA,CAAA;AAG3C,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,aAAA,WAAA,OAAA,KAAA,CAAA;AAGzB,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,aAAA,WAAA,OAAA,KAAA,CAAA;AAGzB,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,aAAA,WAAA,SAAA,IAAA;AAWzB,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,aAAA,WAAA,QAAA,KAAA,CAAA;AA/B3BC,eAAAA,WAAAA,CAAAA,kBAAc,YAAY,CAAA,GAAA,YAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry-BEtb8_wB.js","names":[],"sources":["../src/icons/registry.ts"],"sourcesContent":["const _registry = new Map<string, IconEntry>();\n\nlet _iconFont: string | undefined;\n\nexport const iconBus = new EventTarget();\n\nexport type IconChangedDetail = { readonly name: string };\nexport type IconChangedEvent = CustomEvent<IconChangedDetail>;\n\nexport type IconEntry\n = | { kind: `svg`; svg: string }\n | { kind: `font`; char: string };\n\nexport function registerIcon(name: string, svg: string): void {\n _registry.set(name, { kind: `svg`, svg });\n iconBus.dispatchEvent(new CustomEvent<IconChangedDetail>(`ixfx-icon-change`, { detail: { name } }));\n}\n\nexport function registerFontIcon(name: string, glyph: string | number): void {\n let char: string;\n if (typeof glyph === `number`) {\n char = String.fromCodePoint(glyph);\n } else {\n char = glyph;\n }\n if (char.length === 0)\n throw new Error(`registerFontIcon: glyph must be non-empty`);\n _registry.set(name, { kind: `font`, char });\n iconBus.dispatchEvent(new CustomEvent<IconChangedDetail>(`ixfx-icon-change`, { detail: { name } }));\n}\n\nexport function getIcon(name: string): string | undefined {\n const entry = _registry.get(name);\n return entry?.kind === `svg` ? entry.svg : undefined;\n}\n\nexport function getIconEntry(name: string): IconEntry | undefined {\n return _registry.get(name);\n}\n\nexport function hasIcon(name: string): boolean {\n return _registry.has(name);\n}\n\nexport function setIconFont(fontFamily: string): void {\n _iconFont = fontFamily;\n iconBus.dispatchEvent(new CustomEvent<IconChangedDetail>(`ixfx-icon-font-change`, { detail: { name: `` } }));\n}\n\nexport function getIconFont(): string | undefined {\n return _iconFont;\n}\n\nexport function svgToDataUri(svg: string): string {\n return `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`;\n}\n"],"mappings":";AAAA,MAAM,4BAAY,IAAI,IAAuB;AAE7C,IAAI;AAEJ,MAAa,UAAU,IAAI,YAAY;AASvC,SAAgB,aAAa,MAAc,KAAmB;CAC5D,UAAU,IAAI,MAAM;EAAE,MAAM;EAAO;CAAI,CAAC;CACxC,QAAQ,cAAc,IAAI,YAA+B,oBAAoB,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;AACpG;AAEA,SAAgB,iBAAiB,MAAc,OAA8B;CAC3E,IAAI;CACJ,IAAI,OAAO,UAAU,UACnB,OAAO,OAAO,cAAc,KAAK;MAEjC,OAAO;CAET,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,MAAM,2CAA2C;CAC7D,UAAU,IAAI,MAAM;EAAE,MAAM;EAAQ;CAAK,CAAC;CAC1C,QAAQ,cAAc,IAAI,YAA+B,oBAAoB,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;AACpG;AAEA,SAAgB,QAAQ,MAAkC;CACxD,MAAM,QAAQ,UAAU,IAAI,IAAI;CAChC,OAAO,OAAO,SAAS,QAAQ,MAAM,MAAM,KAAA;AAC7C;AAEA,SAAgB,aAAa,MAAqC;CAChE,OAAO,UAAU,IAAI,IAAI;AAC3B;AAEA,SAAgB,QAAQ,MAAuB;CAC7C,OAAO,UAAU,IAAI,IAAI;AAC3B;AAEA,SAAgB,YAAY,YAA0B;CACpD,YAAY;CACZ,QAAQ,cAAc,IAAI,YAA+B,yBAAyB,EAAE,QAAQ,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAC7G;AAEA,SAAgB,cAAkC;CAChD,OAAO;AACT;AAEA,SAAgB,aAAa,KAAqB;CAChD,OAAO,2BAA2B,mBAAmB,GAAG,EAAE;AAC5D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"scroll-fade-BrNUIYnm.js","names":[],"sources":["../src/styles/scroll-fade.ts"],"sourcesContent":["import { css, unsafeCSS } from 'lit';\n\nexport type ScrollFadeAxis = `x` | `y`;\n\n/**\n * Zero-JS scroll edge fade.\n *\n * A CSS alpha mask driven by a scroll-linked animation (`scroll-timeline`),\n * rather than a JS scroll/resize listener - so it can never go stale after\n * a resize (widening a scroller so content fully fits clears the fade\n * immediately, with no JS involved), and it fades the whole element\n * including its children, not just a background layer that an opaque\n * item background would hide.\n *\n * Apply the returned `.scroll-fade-x` / `.scroll-fade-y` class to\n * whichever element actually has `overflow` scrolling on that axis.\n *\n * NOTE: apply only one axis class per element. Each class sets\n * `mask-image`, so putting both on the same element makes the second\n * overwrite the first. An element that scrolls on both axes at once (e.g.\n * a grid viewport with `overflow: auto`) should use the vertical fade on\n * the viewport itself and handle the horizontal axis separately (e.g. a\n * synced header strip with its own `scroll-fade-x`).\n *\n * CSS variables:\n * - `--scroll-fade-width` (default `30px`): how far the fade extends from each edge.\n * - `--scroll-fade-strength` (default `1`): how completely content fades out\n * at the edge, `0`–`1`. `1` fades to fully transparent (current behaviour);\n * `0` disables the fade entirely. Dense layouts (e.g. a data grid) typically\n * want something like `0.7`–`0.8` so the edge row stays partly readable.\n * Deliberately *not* `@property`-registered, so it inherits normally and a\n * consumer override on the host reaches the shadow-DOM scroller.\n *\n * ```ts\n * import { scrollFadeStyles } from '../styles/scroll-fade.js';\n *\n * static styles = [scrollFadeStyles(`x`), css`...`];\n * ```\n * ```html\n * <div class=\"scroll-fade-x\" style=\"overflow-x: scroll\">...</div>\n * ```\n */\nexport function scrollFadeStyles(axis: ScrollFadeAxis) {\n const className = `scroll-fade-${axis}`;\n const start = `--${className}-start`;\n const end = `--${className}-end`;\n const timeline = `--${className}-timeline`;\n const keyframesName = `${className}-fade`;\n const gradientDirection = axis === `x` ? `to right` : `to bottom`;\n\n return css`\n @property ${unsafeCSS(start)} {\n syntax: '<length>';\n inherits: false;\n initial-value: 0px;\n }\n\n @property ${unsafeCSS(end)} {\n syntax: '<length>';\n inherits: false;\n initial-value: 0px;\n }\n\n @keyframes ${unsafeCSS(keyframesName)} {\n 0% { ${unsafeCSS(start)}: 0px; }\n 10%, 100% { ${unsafeCSS(start)}: var(--scroll-fade-width, 30px); }\n 0%, 90% { ${unsafeCSS(end)}: var(--scroll-fade-width, 30px); }\n 100% { ${unsafeCSS(end)}: 0px; }\n }\n\n .${unsafeCSS(className)} {\n scroll-timeline: ${unsafeCSS(timeline)} ${unsafeCSS(axis)};\n animation: ${unsafeCSS(keyframesName)};\n animation-timeline: ${unsafeCSS(timeline)};\n mask-image: linear-gradient(${unsafeCSS(gradientDirection)},\n rgb(0 0 0 / calc(1 - var(--scroll-fade-strength, 1))),\n black var(${unsafeCSS(start)}, 0px) calc(100% - var(${unsafeCSS(end)}, 0px)),\n rgb(0 0 0 / calc(1 - var(--scroll-fade-strength, 1)))\n );\n }\n `;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,SAAgB,iBAAiB,MAAsB;CACrD,MAAM,YAAY,eAAe;CACjC,MAAM,QAAQ,KAAK,UAAU;CAC7B,MAAM,MAAM,KAAK,UAAU;CAC3B,MAAM,WAAW,KAAK,UAAU;CAChC,MAAM,gBAAgB,GAAG,UAAU;CACnC,MAAM,oBAAoB,SAAS,MAAM,aAAa;CAEtD,OAAO,GAAG;gBACI,UAAU,KAAK,EAAE;;;;;;gBAMjB,UAAU,GAAG,EAAE;;;;;;iBAMd,UAAU,aAAa,EAAE;aAC7B,UAAU,KAAK,EAAE;oBACV,UAAU,KAAK,EAAE;kBACnB,UAAU,GAAG,EAAE;eAClB,UAAU,GAAG,EAAE;;;OAGvB,UAAU,SAAS,EAAE;yBACH,UAAU,QAAQ,EAAE,GAAG,UAAU,IAAI,EAAE;mBAC7C,UAAU,aAAa,EAAE;4BAChB,UAAU,QAAQ,EAAE;oCACZ,UAAU,iBAAiB,EAAE;;oBAE7C,UAAU,KAAK,EAAE,yBAAyB,UAAU,GAAG,EAAE;;;;;AAK7E"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"select-horiz.d.ts","names":[],"sources":["../src/select-horiz/select-horiz.ts"],"mappings":";;;KAUY;WACD;WACA,cAAc;WACd;;KAGC,yBAAyB,YAAY;UAEhC;EACf,QAAQ;;QAGF;YACI;IACR,qBAAqB;;;UAIR;EACf,oBAAoB,gBAAgB,qBAClC,MAAM,GACN,WAAW,MAAM,oBAAoB,OAAO,oBAAoB,aAChE,oBAAoB,sCAEpB,cACA,UAAU,oCACV,oBAAoB;;;cAKX,2BAA2B;SACtB,sBAAM;UA2Fd;UAGA;UAEA;MAUJ;MAIA,cAAc;MAoBd;MAKA,cAAc;MASd,gBAAgB;MAIhB,SAAS;YAIM,wBAAM;EAkBhB,WAAW,SAAS,IAAI;UAKzB;UAoBA;UAaA;UAUA;UAOA;UAoBA;UAOA;EAOR,iBAAiB,WAAW,gBAAgB,QAAQ;UAc5C;UAYA;UAUA;UAOA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"select-horiz.js","names":["customElement"],"sources":["../src/select-horiz/select-horiz.ts"],"sourcesContent":["/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { TickledController, tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { scrollFadeStyles } from '../styles/scroll-fade.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type SelectHorizChangeDetail = {\n readonly selectedIndex: number;\n readonly selectedItem: HTMLElement | null;\n readonly selectedValue: string | null;\n};\n\nexport type SelectHorizChangeEvent = CustomEvent<SelectHorizChangeDetail>;\n\nexport interface SelectHorizEventMap {\n change: SelectHorizChangeEvent;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-select-horiz': SelectHorizElement;\n }\n}\n\nexport interface SelectHorizElement {\n addEventListener: (<K extends keyof SelectHorizEventMap>(\n type: K,\n listener: (this: SelectHorizElement, event: SelectHorizEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n\n@customElement(`ixfx-select-horiz`)\nexport class SelectHorizElement extends WheelNudgeMixin(LitElement) {\n static override styles = [\n themeFallbacks,\n tickledStyles,\n tickledItemStyles,\n scrollFadeStyles(`x`),\n css`\n :host {\n --select-horiz-item-width: 80%;\n --select-horiz-gap: var(--space-s);\n --select-horiz-bg: var(--surface-3);\n --select-horiz-border: var(--border);\n --select-horiz-radius: var(--radius-l);\n display: flex;\n width: 100%;\n background: var(--select-horiz-bg);\n border: var(--select-horiz-border);\n border-radius: var(--select-horiz-radius);\n }\n\n /* Edge fade (the scroll-fade-x class, see ../styles/scroll-fade.ts) must sit on\n * the element that actually scrolls - its mask is sized to this element's own\n * box, and content overflowing a *different*, non-scrolling ancestor gets the\n * mask tiled across it instead of fading correctly. */\n .items {\n display: flex;\n align-items: center;\n gap: var(--select-horiz-gap);\n padding: var(--space-xs) var(--scroll-fade-width, 30px);\n width: 100%;\n min-height: 48px;\n overflow-x: scroll;\n overflow-y: hidden;\n scrollbar-width: none;\n scroll-snap-type: x mandatory;\n -webkit-overflow-scrolling: touch;\n cursor: grab;\n \n box-sizing: border-box;\n }\n\n .items:focus-within {\n cursor: default;\n }\n\n .spacer {\n flex: 0 0 var(--select-horiz-spacer-width, 10%);\n pointer-events: none;\n user-select: none;\n }\n\n ::slotted(*) {\n flex: 0 0 var(--select-horiz-item-width);\n scroll-snap-align: center;\n user-select: none;\n min-height: 100%;\n box-sizing: border-box;\n transition: opacity var(--transition), background var(--transition), border-color var(--transition), color var(--transition);\n background: var(--item-bg);\n border: var(--item-border);\n border-radius: var(--item-border-radius);\n padding: var(--item-padding);\n display: grid;\n align-content: center;\n justify-content: center;\n }\n\n ::slotted(.tickled) {\n background: var(--item-bg-tickled);\n border: var(--item-border-tickled);\n color: var(--item-text-tickled);\n }\n\n ::slotted([selected]) {\n background: var(--item-bg-selected);\n border: var(--item-border-selected);\n color: var(--item-text-selected);\n }\n\n ::slotted([selected].tickled) {\n background: var(--item-bg-selected-tickled);\n outline: 2px dashed var(--surface-3);\n outline-offset: -2px;\n }\n\n ::-webkit-scrollbar {\n display: none;\n }\n `,\n ];\n\n @state()\n private _selectedIndex = -1;\n\n @state()\n private _slottedItems: HTMLElement[] = [];\n\n private tickled = new TickledController<number>(this, {\n getItems: () =>\n this._slottedItems.map((_, i) => ({\n id: i,\n enabled: true,\n })),\n onStateChange: () => this._syncTickled(),\n });\n\n @property({ type: Number, reflect: true, attribute: `selected-index` })\n get selectedIndex(): number {\n return this._selectedIndex;\n }\n\n set selectedIndex(value: number) {\n const oldValue = this._selectedIndex;\n // Upper bound is only enforced once items are known - this lets a\n // declarative `selected-index` attribute be accepted before slotchange\n // has had a chance to populate `_slottedItems`.\n if (value < -1 || (this._slottedItems.length > 0 && value >= this._slottedItems.length))\n return;\n this._selectedIndex = value;\n this._updateSelectedAttribute();\n this._scrollSelectedIntoView();\n // Keep the keyboard-navigation cursor anchored to the current selection,\n // so left/right always steps from here - not from wherever it was last\n // left by a stale hover or an earlier keyboard session.\n this.tickled.setTickled(value === -1 ? undefined : value);\n if (oldValue !== value) {\n this._emitChange();\n }\n }\n\n @property({ type: String })\n get selectedValue(): string | null {\n const item = this._slottedItems[this._selectedIndex];\n return item?.getAttribute(`value`) ?? null;\n }\n\n set selectedValue(value: string | null) {\n if (value === null)\n return;\n const index = this._slottedItems.findIndex(item => item.getAttribute(`value`) === value);\n if (index >= 0) {\n this.selectedIndex = index;\n }\n }\n\n get selectedItem(): HTMLElement | null {\n return this._slottedItems[this._selectedIndex] ?? null;\n }\n\n get items(): HTMLCollection {\n return this._slottedItems as unknown as HTMLCollection;\n }\n\n protected override render() {\n return html`\n <div\n class=\"items scroll-fade-x\"\n tabindex=\"0\"\n data-input-mode=${this.tickled.inputMode}\n @pointerover=${this._handlePointerOver}\n @pointerleave=${(e: PointerEvent) => this.tickled.handlePointerLeave(e)}\n @keydown=${this._handleKeyDown}\n @click=${this._handleClick}\n >\n <div class=\"spacer\"></div>\n <slot @slotchange=${this._onSlotChange}></slot>\n <div class=\"spacer\"></div>\n </div>\n `;\n }\n\n override willUpdate(changed: Map<PropertyKey, unknown>): void {\n super.willUpdate(changed);\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n }\n\n private _onSlotChange = (): void => {\n this._slottedItems = Array.from(\n this.shadowRoot?.querySelector(`slot`)?.assignedElements() ?? [],\n ) as HTMLElement[];\n\n // A child's own `selected` attribute (declared in markup) takes priority\n // over whatever `selected-index` resolved to.\n const declaredIndex = this._slottedItems.findIndex(item => item.hasAttribute(`selected`));\n let resolvedIndex = declaredIndex >= 0 ? declaredIndex : this._selectedIndex;\n\n if (resolvedIndex >= this._slottedItems.length) {\n resolvedIndex = this._slottedItems.length - 1;\n }\n if (resolvedIndex < 0 && this._slottedItems.length > 0) {\n resolvedIndex = 0;\n }\n\n this.selectedIndex = resolvedIndex;\n };\n\n private _syncTickled = (): void => {\n this._slottedItems.forEach((item, i) => {\n const isTickled = this.tickled.isTickled(i);\n item.classList.toggle(`tickled`, isTickled);\n // Roving tabindex only follows keyboard navigation - a mouse hover\n // shouldn't relocate where Tab lands next.\n item.tabIndex = (isTickled && this.tickled.inputMode === `keyboard`) ? 0 : -1;\n });\n };\n\n // Slotted items may contain nested markup (icons, labels, ...), so a\n // pointer/click target isn't necessarily the item element itself - walk up\n // to the nearest ancestor that is one of our direct slotted children.\n private _findSlottedItem = (target: EventTarget | null): HTMLElement | undefined => {\n let el = target instanceof Element ? target : null;\n while (el) {\n if (this._slottedItems.includes(el as HTMLElement))\n return el as HTMLElement;\n el = el.parentElement;\n }\n return undefined;\n };\n\n private _handlePointerOver = (e: PointerEvent): void => {\n const item = this._findSlottedItem(e.target);\n if (item) {\n this.tickled.handlePointerEnter(this._slottedItems.indexOf(item));\n }\n };\n\n private _handleKeyDown = (e: KeyboardEvent): void => {\n if (e.key === `ArrowLeft`) {\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n this._applyTickledSelection();\n } else if (e.key === `ArrowRight`) {\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n this._applyTickledSelection();\n } else if (e.key === `Home`) {\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`first`);\n this._applyTickledSelection();\n } else if (e.key === `End`) {\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`last`);\n this._applyTickledSelection();\n }\n };\n\n private _applyTickledSelection = (): void => {\n const id = this.tickled.tickledId;\n if (id !== undefined && id !== this._selectedIndex) {\n this.selectedIndex = id;\n }\n };\n\n private _wheelCooldown = false;\n\n // WheelNudgeMixin contract: direction follows the codebase-wide \"up =\n // increase\" convention (wheel up/away = +1), which here maps naturally to\n // \"next\" since selectedIndex increases moving forward through the list -\n // same direction as every other consumer of this mixin except the\n // deliberately-inverted rotary-dial case in radial-input.\n _applyWheelDelta(direction: WheelDirection, _event: WheelEvent): void {\n if (this._wheelCooldown)\n return;\n\n // Trackpads fire many wheel ticks per gesture; a short cooldown collapses\n // that into one step, matching a single arrow-key press.\n this._wheelCooldown = true;\n this.tickled.handleKeyboardNavigation(direction === 1 ? `next` : `previous`);\n this._applyTickledSelection();\n setTimeout(() => {\n this._wheelCooldown = false;\n }, 250);\n }\n\n private _handleClick = (e: MouseEvent): void => {\n // Focusing this (shadow-internal) element also focuses the host from the\n // outside - document.activeElement retargets to the host across an open\n // shadow boundary - so a single click lets arrow keys take over right away.\n (e.currentTarget as HTMLElement).focus();\n const item = this._findSlottedItem(e.target);\n const index = item ? this._slottedItems.indexOf(item) : -1;\n if (index >= 0 && index !== this._selectedIndex) {\n this.selectedIndex = index;\n }\n };\n\n private _updateSelectedAttribute = (): void => {\n this._slottedItems.forEach((item, i) => {\n if (i === this._selectedIndex) {\n item.setAttribute(`selected`, ``);\n } else {\n item.removeAttribute(`selected`);\n }\n });\n };\n\n private _scrollSelectedIntoView = (): void => {\n const item = this._slottedItems[this._selectedIndex];\n if (item) {\n item.scrollIntoView({ inline: `center`, behavior: `smooth` });\n }\n };\n\n private _emitChange = (): void => {\n this.dispatchEvent(\n new CustomEvent<SelectHorizChangeDetail>(`change`, {\n detail: {\n selectedIndex: this._selectedIndex,\n selectedItem: this.selectedItem,\n selectedValue: this.selectedValue,\n },\n bubbles: true,\n composed: true,\n }),\n );\n };\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"slider-input-BxURAAmD.d.ts","names":[],"sources":["../src/slider-input/types.ts","../src/slider-input/slider-input.ts"],"mappings":";;;;;;KAIY;KACA;KACA;KACA;KACA;KACA;;;;;;;KAOA;KACA;KACA;;;;;;;UAQK;EACf;EACA,MAAM;;;;;EAKN;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;KAOU;;;;;;;;UASK;WACN;WACA;;WAEA;;WAEA;WACA;WACA;;WAEA;WACA;;WAEA,UAAU;;UAGJ;WACN;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,UAAU;;KAGT,wBAAwB,YAAY;KACpC,yBAAyB,YAAY;UAEhC;EACf,OAAO;EACP,QAAQ;;;;;cCiFG,2BAA2B;;EAGtC;EAGA;;;;;;EAQA;EAGA;EAGA;EAGA;EAGA;EAGA,WAAW;EAGX,aAAa;EAGb,aAAa;EAGb,aAAa;;;;;;EAQb,cAAc;EAGd,WAAW;EAGX,WAAW;;;;;;;EASX,cAAc;EAGd;EAGA;;;;;;;;;;;;;EAeA;;EAyFS;EAiFT,QACE,aACA;IACE;IACA;IACA;IACA,OAAO;IACP;IACA;;EAgBJ,aAAa,aAAa;EAQ1B,aAAa,aAAa,kBAAkB;EAW5C,WAAW;EAKX,YAAY,oBAAoB;EAIhC,QAAQ,cAAc;EAunCb,iBAAiB,WAAW,gBAAgB,OAAO;YAoXzC,WAAW,SAAS;EAsE9B;YA2JU,QAAQ,SAAS;EAkB3B;SAiBO,sBAAM;;QAqJhB;YACI;IACR,qBAAqB;;;UAKR;EACf,oBAAoB,gBAAgB,4BAClC,MAAM,GACN,WAAW,MAAM,oBAAoB,OAAO,2BAA2B,aACvE,oBAAoB,sCAEpB,cACA,UAAU,oCACV,oBAAoB"}