@ggts-sh/svelte 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (656) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +97 -0
  3. package/bin/ggts-codemod.js +47 -0
  4. package/dist/GGPlot.svelte +491 -0
  5. package/dist/GGPlot.svelte.d.ts +67 -0
  6. package/dist/a11y/CanvasA11y.svelte +115 -0
  7. package/dist/a11y/CanvasA11y.svelte.d.ts +15 -0
  8. package/dist/a11y/canvas-a11y.d.ts +1 -0
  9. package/dist/a11y/canvas-a11y.js +2 -0
  10. package/dist/assembly/assemble.d.ts +1 -0
  11. package/dist/assembly/assemble.js +1 -0
  12. package/dist/assembly/labels.d.ts +43 -0
  13. package/dist/assembly/labels.js +126 -0
  14. package/dist/assembly/layout.d.ts +158 -0
  15. package/dist/assembly/layout.js +175 -0
  16. package/dist/chrome/StatusChrome.svelte +125 -0
  17. package/dist/chrome/StatusChrome.svelte.d.ts +16 -0
  18. package/dist/chrome/ToolRail.svelte +293 -0
  19. package/dist/chrome/ToolRail.svelte.d.ts +26 -0
  20. package/dist/chrome/chrome-state.svelte.d.ts +63 -0
  21. package/dist/chrome/chrome-state.svelte.js +158 -0
  22. package/dist/chrome/theme-css.d.ts +16 -0
  23. package/dist/chrome/theme-css.js +16 -0
  24. package/dist/codemod/cli.d.ts +16 -0
  25. package/dist/codemod/cli.js +150 -0
  26. package/dist/codemod/edits.d.ts +28 -0
  27. package/dist/codemod/edits.js +36 -0
  28. package/dist/codemod/index.d.ts +10 -0
  29. package/dist/codemod/index.js +10 -0
  30. package/dist/codemod/migrate-plot-props-rewrite.d.ts +86 -0
  31. package/dist/codemod/migrate-plot-props-rewrite.js +228 -0
  32. package/dist/codemod/migrate-plot-props.d.ts +38 -0
  33. package/dist/codemod/migrate-plot-props.js +159 -0
  34. package/dist/coord/Coord.svelte +21 -0
  35. package/dist/coord/Coord.svelte.d.ts +16 -0
  36. package/dist/coord/CoordCartesian.svelte +11 -0
  37. package/dist/coord/CoordCartesian.svelte.d.ts +18 -0
  38. package/dist/coord/CoordFixed.svelte +17 -0
  39. package/dist/coord/CoordFixed.svelte.d.ts +10 -0
  40. package/dist/coord/CoordFlip.svelte +11 -0
  41. package/dist/coord/CoordFlip.svelte.d.ts +18 -0
  42. package/dist/coord/CoordPolar.svelte +16 -0
  43. package/dist/coord/CoordPolar.svelte.d.ts +9 -0
  44. package/dist/coord/CoordRadial.svelte +16 -0
  45. package/dist/coord/CoordRadial.svelte.d.ts +9 -0
  46. package/dist/coord/CoordSf.svelte +16 -0
  47. package/dist/coord/CoordSf.svelte.d.ts +9 -0
  48. package/dist/coord/CoordTransform.svelte +16 -0
  49. package/dist/coord/CoordTransform.svelte.d.ts +9 -0
  50. package/dist/data/index.d.ts +1 -0
  51. package/dist/data/index.js +2 -0
  52. package/dist/diagnostics/composition.d.ts +112 -0
  53. package/dist/diagnostics/composition.js +203 -0
  54. package/dist/diagnostics/deprecation.d.ts +58 -0
  55. package/dist/diagnostics/deprecation.js +27 -0
  56. package/dist/diagnostics/plot-engine-diagnostics.svelte.d.ts +44 -0
  57. package/dist/diagnostics/plot-engine-diagnostics.svelte.js +193 -0
  58. package/dist/facet/Facet.svelte +23 -0
  59. package/dist/facet/Facet.svelte.d.ts +16 -0
  60. package/dist/facet/FacetGrid.svelte +32 -0
  61. package/dist/facet/FacetGrid.svelte.d.ts +16 -0
  62. package/dist/facet/FacetWrap.svelte +32 -0
  63. package/dist/facet/FacetWrap.svelte.d.ts +16 -0
  64. package/dist/fonts/RobotoCondensed-Bold.ttf +0 -0
  65. package/dist/fonts/RobotoCondensed-Light.ttf +0 -0
  66. package/dist/fonts/RobotoCondensed-Regular.ttf +0 -0
  67. package/dist/fonts/THIRD_PARTY_NOTICES.txt +416 -0
  68. package/dist/geoms/GeomAbline.svelte +25 -0
  69. package/dist/geoms/GeomAbline.svelte.d.ts +7 -0
  70. package/dist/geoms/GeomArea.svelte +12 -0
  71. package/dist/geoms/GeomArea.svelte.d.ts +7 -0
  72. package/dist/geoms/GeomBar.svelte +12 -0
  73. package/dist/geoms/GeomBar.svelte.d.ts +7 -0
  74. package/dist/geoms/GeomBin2d.svelte +21 -0
  75. package/dist/geoms/GeomBin2d.svelte.d.ts +7 -0
  76. package/dist/geoms/GeomBlank.svelte +12 -0
  77. package/dist/geoms/GeomBlank.svelte.d.ts +7 -0
  78. package/dist/geoms/GeomBoxplot.svelte +25 -0
  79. package/dist/geoms/GeomBoxplot.svelte.d.ts +7 -0
  80. package/dist/geoms/GeomCol.svelte +12 -0
  81. package/dist/geoms/GeomCol.svelte.d.ts +7 -0
  82. package/dist/geoms/GeomContour.svelte +25 -0
  83. package/dist/geoms/GeomContour.svelte.d.ts +7 -0
  84. package/dist/geoms/GeomCount.svelte +12 -0
  85. package/dist/geoms/GeomCount.svelte.d.ts +7 -0
  86. package/dist/geoms/GeomCrossbar.svelte +25 -0
  87. package/dist/geoms/GeomCrossbar.svelte.d.ts +7 -0
  88. package/dist/geoms/GeomCurve.svelte +21 -0
  89. package/dist/geoms/GeomCurve.svelte.d.ts +7 -0
  90. package/dist/geoms/GeomDensity.svelte +25 -0
  91. package/dist/geoms/GeomDensity.svelte.d.ts +7 -0
  92. package/dist/geoms/GeomDensity2d.svelte +25 -0
  93. package/dist/geoms/GeomDensity2d.svelte.d.ts +7 -0
  94. package/dist/geoms/GeomDensity2dFilled.svelte +25 -0
  95. package/dist/geoms/GeomDensity2dFilled.svelte.d.ts +7 -0
  96. package/dist/geoms/GeomDotplot.svelte +25 -0
  97. package/dist/geoms/GeomDotplot.svelte.d.ts +7 -0
  98. package/dist/geoms/GeomErrorbar.svelte +25 -0
  99. package/dist/geoms/GeomErrorbar.svelte.d.ts +7 -0
  100. package/dist/geoms/GeomFreqpoly.svelte +25 -0
  101. package/dist/geoms/GeomFreqpoly.svelte.d.ts +7 -0
  102. package/dist/geoms/GeomFunction.svelte +25 -0
  103. package/dist/geoms/GeomFunction.svelte.d.ts +7 -0
  104. package/dist/geoms/GeomHex.svelte +21 -0
  105. package/dist/geoms/GeomHex.svelte.d.ts +7 -0
  106. package/dist/geoms/GeomHistogram.svelte +25 -0
  107. package/dist/geoms/GeomHistogram.svelte.d.ts +7 -0
  108. package/dist/geoms/GeomHline.svelte +12 -0
  109. package/dist/geoms/GeomHline.svelte.d.ts +7 -0
  110. package/dist/geoms/GeomJitter.svelte +35 -0
  111. package/dist/geoms/GeomJitter.svelte.d.ts +13 -0
  112. package/dist/geoms/GeomLabel.svelte +12 -0
  113. package/dist/geoms/GeomLabel.svelte.d.ts +7 -0
  114. package/dist/geoms/GeomLine.svelte +12 -0
  115. package/dist/geoms/GeomLine.svelte.d.ts +7 -0
  116. package/dist/geoms/GeomLinerange.svelte +25 -0
  117. package/dist/geoms/GeomLinerange.svelte.d.ts +7 -0
  118. package/dist/geoms/GeomMap.svelte +21 -0
  119. package/dist/geoms/GeomMap.svelte.d.ts +7 -0
  120. package/dist/geoms/GeomPath.svelte +12 -0
  121. package/dist/geoms/GeomPath.svelte.d.ts +7 -0
  122. package/dist/geoms/GeomPoint.svelte +12 -0
  123. package/dist/geoms/GeomPoint.svelte.d.ts +7 -0
  124. package/dist/geoms/GeomPointrange.svelte +25 -0
  125. package/dist/geoms/GeomPointrange.svelte.d.ts +7 -0
  126. package/dist/geoms/GeomPolygon.svelte +25 -0
  127. package/dist/geoms/GeomPolygon.svelte.d.ts +7 -0
  128. package/dist/geoms/GeomQq.svelte +21 -0
  129. package/dist/geoms/GeomQq.svelte.d.ts +7 -0
  130. package/dist/geoms/GeomQqLine.svelte +25 -0
  131. package/dist/geoms/GeomQqLine.svelte.d.ts +7 -0
  132. package/dist/geoms/GeomQuantile.svelte +25 -0
  133. package/dist/geoms/GeomQuantile.svelte.d.ts +7 -0
  134. package/dist/geoms/GeomRaster.svelte +25 -0
  135. package/dist/geoms/GeomRaster.svelte.d.ts +7 -0
  136. package/dist/geoms/GeomRect.svelte +12 -0
  137. package/dist/geoms/GeomRect.svelte.d.ts +7 -0
  138. package/dist/geoms/GeomRibbon.svelte +16 -0
  139. package/dist/geoms/GeomRibbon.svelte.d.ts +7 -0
  140. package/dist/geoms/GeomRug.svelte +21 -0
  141. package/dist/geoms/GeomRug.svelte.d.ts +7 -0
  142. package/dist/geoms/GeomRule.svelte +12 -0
  143. package/dist/geoms/GeomRule.svelte.d.ts +7 -0
  144. package/dist/geoms/GeomSegment.svelte +16 -0
  145. package/dist/geoms/GeomSegment.svelte.d.ts +7 -0
  146. package/dist/geoms/GeomSf.svelte +21 -0
  147. package/dist/geoms/GeomSf.svelte.d.ts +7 -0
  148. package/dist/geoms/GeomSfLabel.svelte +25 -0
  149. package/dist/geoms/GeomSfLabel.svelte.d.ts +7 -0
  150. package/dist/geoms/GeomSfText.svelte +25 -0
  151. package/dist/geoms/GeomSfText.svelte.d.ts +7 -0
  152. package/dist/geoms/GeomSmooth.svelte +25 -0
  153. package/dist/geoms/GeomSmooth.svelte.d.ts +7 -0
  154. package/dist/geoms/GeomSpoke.svelte +21 -0
  155. package/dist/geoms/GeomSpoke.svelte.d.ts +7 -0
  156. package/dist/geoms/GeomStep.svelte +12 -0
  157. package/dist/geoms/GeomStep.svelte.d.ts +7 -0
  158. package/dist/geoms/GeomText.svelte +12 -0
  159. package/dist/geoms/GeomText.svelte.d.ts +7 -0
  160. package/dist/geoms/GeomTile.svelte +21 -0
  161. package/dist/geoms/GeomTile.svelte.d.ts +7 -0
  162. package/dist/geoms/GeomViolin.svelte +25 -0
  163. package/dist/geoms/GeomViolin.svelte.d.ts +7 -0
  164. package/dist/geoms/GeomVline.svelte +12 -0
  165. package/dist/geoms/GeomVline.svelte.d.ts +7 -0
  166. package/dist/geoms/factory.svelte.d.ts +41 -0
  167. package/dist/geoms/factory.svelte.js +60 -0
  168. package/dist/geoms/registry.svelte.d.ts +71 -0
  169. package/dist/geoms/registry.svelte.js +177 -0
  170. package/dist/guides/GuideAxis.svelte +20 -0
  171. package/dist/guides/GuideAxis.svelte.d.ts +14 -0
  172. package/dist/guides/GuideColorbar.svelte +22 -0
  173. package/dist/guides/GuideColorbar.svelte.d.ts +13 -0
  174. package/dist/guides/GuideColorsteps.svelte +22 -0
  175. package/dist/guides/GuideColorsteps.svelte.d.ts +13 -0
  176. package/dist/guides/GuideLegend.svelte +90 -0
  177. package/dist/guides/GuideLegend.svelte.d.ts +37 -0
  178. package/dist/guides/GuideNone.svelte +19 -0
  179. package/dist/guides/GuideNone.svelte.d.ts +7 -0
  180. package/dist/guides/Guides.svelte +14 -0
  181. package/dist/guides/Guides.svelte.d.ts +13 -0
  182. package/dist/guides/factory.svelte.d.ts +36 -0
  183. package/dist/guides/factory.svelte.js +15 -0
  184. package/dist/index.d.ts +418 -0
  185. package/dist/index.js +376 -0
  186. package/dist/inspection/Inspect.svelte +71 -0
  187. package/dist/inspection/Inspect.svelte.d.ts +36 -0
  188. package/dist/inspection/Tooltip.svelte +439 -0
  189. package/dist/inspection/Tooltip.svelte.d.ts +32 -0
  190. package/dist/inspection/apply.d.ts +120 -0
  191. package/dist/inspection/apply.js +99 -0
  192. package/dist/inspection/coordinator.d.ts +51 -0
  193. package/dist/inspection/coordinator.js +354 -0
  194. package/dist/inspection/display-members.d.ts +1 -0
  195. package/dist/inspection/display-members.js +2 -0
  196. package/dist/inspection/frame.d.ts +90 -0
  197. package/dist/inspection/frame.js +76 -0
  198. package/dist/inspection/group-total.d.ts +1 -0
  199. package/dist/inspection/group-total.js +2 -0
  200. package/dist/inspection/inspect-guide-axes.d.ts +10 -0
  201. package/dist/inspection/inspect-guide-axes.js +24 -0
  202. package/dist/inspection/inspection-reconcile.svelte.d.ts +37 -0
  203. package/dist/inspection/inspection-reconcile.svelte.js +33 -0
  204. package/dist/inspection/inspection-state.svelte.d.ts +86 -0
  205. package/dist/inspection/inspection-state.svelte.js +347 -0
  206. package/dist/inspection/inspection-traversal.svelte.d.ts +29 -0
  207. package/dist/inspection/inspection-traversal.svelte.js +52 -0
  208. package/dist/inspection/pointer-inspect.d.ts +74 -0
  209. package/dist/inspection/pointer-inspect.js +158 -0
  210. package/dist/inspection/resolver.d.ts +3 -0
  211. package/dist/inspection/resolver.js +4 -0
  212. package/dist/inspection/teardown.d.ts +199 -0
  213. package/dist/inspection/teardown.js +181 -0
  214. package/dist/inspection/tooltip-chrome.d.ts +19 -0
  215. package/dist/inspection/tooltip-chrome.js +17 -0
  216. package/dist/inspection/tooltip-motion.d.ts +25 -0
  217. package/dist/inspection/tooltip-motion.js +32 -0
  218. package/dist/inspection/tooltip-presence.svelte.d.ts +49 -0
  219. package/dist/inspection/tooltip-presence.svelte.js +110 -0
  220. package/dist/inspection/tooltip-total.d.ts +1 -0
  221. package/dist/inspection/tooltip-total.js +2 -0
  222. package/dist/interaction/capability-resolution.svelte.d.ts +42 -0
  223. package/dist/interaction/capability-resolution.svelte.js +40 -0
  224. package/dist/interaction/capability.d.ts +129 -0
  225. package/dist/interaction/capability.js +134 -0
  226. package/dist/interaction/controller.svelte.d.ts +4 -0
  227. package/dist/interaction/controller.svelte.js +43 -0
  228. package/dist/interaction/inspect-geom-advisories.d.ts +10 -0
  229. package/dist/interaction/inspect-geom-advisories.js +10 -0
  230. package/dist/interaction/interaction-context.svelte.d.ts +57 -0
  231. package/dist/interaction/interaction-context.svelte.js +4 -0
  232. package/dist/interaction/interaction-diagnostics.d.ts +11 -0
  233. package/dist/interaction/interaction-diagnostics.js +173 -0
  234. package/dist/interaction/interaction-states.svelte.d.ts +84 -0
  235. package/dist/interaction/interaction-states.svelte.js +55 -0
  236. package/dist/interaction/interaction.d.ts +304 -0
  237. package/dist/interaction/interaction.js +7 -0
  238. package/dist/interaction/normalize-interaction-config.d.ts +9 -0
  239. package/dist/interaction/normalize-interaction-config.js +112 -0
  240. package/dist/interaction/reducer.d.ts +97 -0
  241. package/dist/interaction/reducer.js +117 -0
  242. package/dist/interaction/resolve-inspect-capability.d.ts +40 -0
  243. package/dist/interaction/resolve-inspect-capability.js +50 -0
  244. package/dist/interaction/scoped-store.svelte.d.ts +73 -0
  245. package/dist/interaction/scoped-store.svelte.js +93 -0
  246. package/dist/interaction/target.d.ts +91 -0
  247. package/dist/interaction/target.js +68 -0
  248. package/dist/interaction/transition-owner.d.ts +19 -0
  249. package/dist/interaction/transition-owner.js +10 -0
  250. package/dist/interaction/wiring-advisories.d.ts +33 -0
  251. package/dist/interaction/wiring-advisories.js +46 -0
  252. package/dist/interval/BoundsEditor.svelte +332 -0
  253. package/dist/interval/BoundsEditor.svelte.d.ts +10 -0
  254. package/dist/interval/bounds-editor.d.ts +1 -0
  255. package/dist/interval/bounds-editor.js +2 -0
  256. package/dist/interval/consumption.d.ts +1 -0
  257. package/dist/interval/consumption.js +2 -0
  258. package/dist/interval/interval-bounds-state.svelte.d.ts +53 -0
  259. package/dist/interval/interval-bounds-state.svelte.js +117 -0
  260. package/dist/interval/interval-state-helpers.d.ts +10 -0
  261. package/dist/interval/interval-state-helpers.js +34 -0
  262. package/dist/interval/interval-state.svelte.d.ts +60 -0
  263. package/dist/interval/interval-state.svelte.js +360 -0
  264. package/dist/interval/interval.d.ts +1 -0
  265. package/dist/interval/interval.js +2 -0
  266. package/dist/interval/precise-bounds.d.ts +1 -0
  267. package/dist/interval/precise-bounds.js +2 -0
  268. package/dist/interval/query.d.ts +1 -0
  269. package/dist/interval/query.js +2 -0
  270. package/dist/labs/Labs.svelte +29 -0
  271. package/dist/labs/Labs.svelte.d.ts +16 -0
  272. package/dist/layers/fold.d.ts +2 -0
  273. package/dist/layers/fold.js +1 -0
  274. package/dist/layers/grammar-families.d.ts +2 -0
  275. package/dist/layers/grammar-families.js +1 -0
  276. package/dist/layers/plot-layer-contract.d.ts +1 -0
  277. package/dist/layers/plot-layer-contract.js +29 -0
  278. package/dist/layers/plot-layer.svelte.d.ts +42 -0
  279. package/dist/layers/plot-layer.svelte.js +34 -0
  280. package/dist/layers/types.d.ts +2 -0
  281. package/dist/layers/types.js +1 -0
  282. package/dist/legend/Legend.svelte +24 -0
  283. package/dist/legend/Legend.svelte.d.ts +5 -0
  284. package/dist/legend/LegendFilters.svelte +196 -0
  285. package/dist/legend/LegendFilters.svelte.d.ts +8 -0
  286. package/dist/legend/LegendTargets.svelte +393 -0
  287. package/dist/legend/LegendTargets.svelte.d.ts +31 -0
  288. package/dist/legend/entry-key-index.d.ts +1 -0
  289. package/dist/legend/entry-key-index.js +2 -0
  290. package/dist/legend/entry-key-index.svelte.d.ts +34 -0
  291. package/dist/legend/entry-key-index.svelte.js +35 -0
  292. package/dist/legend/filter-state.svelte.d.ts +66 -0
  293. package/dist/legend/filter-state.svelte.js +284 -0
  294. package/dist/legend/filter.d.ts +1 -0
  295. package/dist/legend/filter.js +2 -0
  296. package/dist/legend/focus-emphasis.d.ts +72 -0
  297. package/dist/legend/focus-emphasis.js +91 -0
  298. package/dist/legend/focus-plans.d.ts +89 -0
  299. package/dist/legend/focus-plans.js +72 -0
  300. package/dist/legend/focus-reconcile.svelte.d.ts +53 -0
  301. package/dist/legend/focus-reconcile.svelte.js +113 -0
  302. package/dist/legend/focus-state.svelte.d.ts +73 -0
  303. package/dist/legend/focus-state.svelte.js +338 -0
  304. package/dist/legend/focus.d.ts +1 -0
  305. package/dist/legend/focus.js +2 -0
  306. package/dist/legend/resolve-legend-capability.d.ts +52 -0
  307. package/dist/legend/resolve-legend-capability.js +68 -0
  308. package/dist/legend/resolve-legend-filter.d.ts +65 -0
  309. package/dist/legend/resolve-legend-filter.js +54 -0
  310. package/dist/legend/resolve-legend-focus.d.ts +58 -0
  311. package/dist/legend/resolve-legend-focus.js +36 -0
  312. package/dist/legend/surface.d.ts +190 -0
  313. package/dist/legend/surface.js +158 -0
  314. package/dist/plot-engine-deriveds.svelte.d.ts +75 -0
  315. package/dist/plot-engine-deriveds.svelte.js +166 -0
  316. package/dist/plot-engine.svelte.d.ts +116 -0
  317. package/dist/plot-engine.svelte.js +316 -0
  318. package/dist/plot-props.d.ts +144 -0
  319. package/dist/plot-props.js +81 -0
  320. package/dist/runtime/announcer.svelte.d.ts +17 -0
  321. package/dist/runtime/announcer.svelte.js +28 -0
  322. package/dist/runtime/paint.d.ts +38 -0
  323. package/dist/runtime/paint.js +45 -0
  324. package/dist/runtime/resolve-datum-key.d.ts +53 -0
  325. package/dist/runtime/resolve-datum-key.js +73 -0
  326. package/dist/runtime/runtime.svelte.d.ts +37 -0
  327. package/dist/runtime/runtime.svelte.js +233 -0
  328. package/dist/runtime/semantic-candidate-projection.svelte.d.ts +29 -0
  329. package/dist/runtime/semantic-candidate-projection.svelte.js +137 -0
  330. package/dist/runtime/semantic-data-identity.d.ts +64 -0
  331. package/dist/runtime/semantic-data-identity.js +153 -0
  332. package/dist/runtime/semantic-keys-projection.d.ts +22 -0
  333. package/dist/runtime/semantic-keys-projection.js +40 -0
  334. package/dist/runtime/semantic-keys-resolve.d.ts +69 -0
  335. package/dist/runtime/semantic-keys-resolve.js +122 -0
  336. package/dist/runtime/semantic-keys.svelte.d.ts +30 -0
  337. package/dist/runtime/semantic-keys.svelte.js +69 -0
  338. package/dist/runtime/semantic-source-identity.d.ts +9 -0
  339. package/dist/runtime/semantic-source-identity.js +16 -0
  340. package/dist/scale/Scale.svelte +26 -0
  341. package/dist/scale/Scale.svelte.d.ts +21 -0
  342. package/dist/scale/ScaleAlphaBinned.svelte +14 -0
  343. package/dist/scale/ScaleAlphaBinned.svelte.d.ts +4 -0
  344. package/dist/scale/ScaleAlphaContinuous.svelte +14 -0
  345. package/dist/scale/ScaleAlphaContinuous.svelte.d.ts +4 -0
  346. package/dist/scale/ScaleAlphaDate.svelte +15 -0
  347. package/dist/scale/ScaleAlphaDate.svelte.d.ts +5 -0
  348. package/dist/scale/ScaleAlphaDatetime.svelte +15 -0
  349. package/dist/scale/ScaleAlphaDatetime.svelte.d.ts +5 -0
  350. package/dist/scale/ScaleAlphaDiscrete.svelte +14 -0
  351. package/dist/scale/ScaleAlphaDiscrete.svelte.d.ts +4 -0
  352. package/dist/scale/ScaleAlphaIdentity.svelte +14 -0
  353. package/dist/scale/ScaleAlphaIdentity.svelte.d.ts +4 -0
  354. package/dist/scale/ScaleAlphaManual.svelte +14 -0
  355. package/dist/scale/ScaleAlphaManual.svelte.d.ts +4 -0
  356. package/dist/scale/ScaleColorBinned.svelte +14 -0
  357. package/dist/scale/ScaleColorBinned.svelte.d.ts +3 -0
  358. package/dist/scale/ScaleColorBrewer.svelte +14 -0
  359. package/dist/scale/ScaleColorBrewer.svelte.d.ts +4 -0
  360. package/dist/scale/ScaleColorContinuous.svelte +14 -0
  361. package/dist/scale/ScaleColorContinuous.svelte.d.ts +4 -0
  362. package/dist/scale/ScaleColorDate.svelte +15 -0
  363. package/dist/scale/ScaleColorDate.svelte.d.ts +5 -0
  364. package/dist/scale/ScaleColorDatetime.svelte +15 -0
  365. package/dist/scale/ScaleColorDatetime.svelte.d.ts +5 -0
  366. package/dist/scale/ScaleColorDiscrete.svelte +14 -0
  367. package/dist/scale/ScaleColorDiscrete.svelte.d.ts +4 -0
  368. package/dist/scale/ScaleColorDistiller.svelte +14 -0
  369. package/dist/scale/ScaleColorDistiller.svelte.d.ts +4 -0
  370. package/dist/scale/ScaleColorFermenter.svelte +14 -0
  371. package/dist/scale/ScaleColorFermenter.svelte.d.ts +4 -0
  372. package/dist/scale/ScaleColorGradient.svelte +11 -0
  373. package/dist/scale/ScaleColorGradient.svelte.d.ts +4 -0
  374. package/dist/scale/ScaleColorGradient2.svelte +14 -0
  375. package/dist/scale/ScaleColorGradient2.svelte.d.ts +4 -0
  376. package/dist/scale/ScaleColorGradientn.svelte +14 -0
  377. package/dist/scale/ScaleColorGradientn.svelte.d.ts +4 -0
  378. package/dist/scale/ScaleColorGrey.svelte +11 -0
  379. package/dist/scale/ScaleColorGrey.svelte.d.ts +4 -0
  380. package/dist/scale/ScaleColorHue.svelte +11 -0
  381. package/dist/scale/ScaleColorHue.svelte.d.ts +4 -0
  382. package/dist/scale/ScaleColorIdentity.svelte +14 -0
  383. package/dist/scale/ScaleColorIdentity.svelte.d.ts +4 -0
  384. package/dist/scale/ScaleColorLog10.svelte +14 -0
  385. package/dist/scale/ScaleColorLog10.svelte.d.ts +4 -0
  386. package/dist/scale/ScaleColorManual.svelte +14 -0
  387. package/dist/scale/ScaleColorManual.svelte.d.ts +4 -0
  388. package/dist/scale/ScaleColorOrdinal.svelte +14 -0
  389. package/dist/scale/ScaleColorOrdinal.svelte.d.ts +3 -0
  390. package/dist/scale/ScaleColorSqrt.svelte +14 -0
  391. package/dist/scale/ScaleColorSqrt.svelte.d.ts +4 -0
  392. package/dist/scale/ScaleColorSteps.svelte +11 -0
  393. package/dist/scale/ScaleColorSteps.svelte.d.ts +4 -0
  394. package/dist/scale/ScaleColorSteps2.svelte +11 -0
  395. package/dist/scale/ScaleColorSteps2.svelte.d.ts +4 -0
  396. package/dist/scale/ScaleColorStepsn.svelte +11 -0
  397. package/dist/scale/ScaleColorStepsn.svelte.d.ts +4 -0
  398. package/dist/scale/ScaleColorViridisB.svelte +11 -0
  399. package/dist/scale/ScaleColorViridisB.svelte.d.ts +4 -0
  400. package/dist/scale/ScaleColorViridisC.svelte +11 -0
  401. package/dist/scale/ScaleColorViridisC.svelte.d.ts +4 -0
  402. package/dist/scale/ScaleColorViridisD.svelte +11 -0
  403. package/dist/scale/ScaleColorViridisD.svelte.d.ts +4 -0
  404. package/dist/scale/ScaleFillBinned.svelte +11 -0
  405. package/dist/scale/ScaleFillBinned.svelte.d.ts +3 -0
  406. package/dist/scale/ScaleFillBrewer.svelte +11 -0
  407. package/dist/scale/ScaleFillBrewer.svelte.d.ts +4 -0
  408. package/dist/scale/ScaleFillContinuous.svelte +14 -0
  409. package/dist/scale/ScaleFillContinuous.svelte.d.ts +4 -0
  410. package/dist/scale/ScaleFillDate.svelte +12 -0
  411. package/dist/scale/ScaleFillDate.svelte.d.ts +5 -0
  412. package/dist/scale/ScaleFillDatetime.svelte +15 -0
  413. package/dist/scale/ScaleFillDatetime.svelte.d.ts +5 -0
  414. package/dist/scale/ScaleFillDiscrete.svelte +14 -0
  415. package/dist/scale/ScaleFillDiscrete.svelte.d.ts +4 -0
  416. package/dist/scale/ScaleFillDistiller.svelte +14 -0
  417. package/dist/scale/ScaleFillDistiller.svelte.d.ts +4 -0
  418. package/dist/scale/ScaleFillFermenter.svelte +14 -0
  419. package/dist/scale/ScaleFillFermenter.svelte.d.ts +4 -0
  420. package/dist/scale/ScaleFillGradient.svelte +11 -0
  421. package/dist/scale/ScaleFillGradient.svelte.d.ts +4 -0
  422. package/dist/scale/ScaleFillGradient2.svelte +14 -0
  423. package/dist/scale/ScaleFillGradient2.svelte.d.ts +4 -0
  424. package/dist/scale/ScaleFillGradientn.svelte +14 -0
  425. package/dist/scale/ScaleFillGradientn.svelte.d.ts +4 -0
  426. package/dist/scale/ScaleFillGrey.svelte +11 -0
  427. package/dist/scale/ScaleFillGrey.svelte.d.ts +4 -0
  428. package/dist/scale/ScaleFillHue.svelte +11 -0
  429. package/dist/scale/ScaleFillHue.svelte.d.ts +4 -0
  430. package/dist/scale/ScaleFillIdentity.svelte +14 -0
  431. package/dist/scale/ScaleFillIdentity.svelte.d.ts +4 -0
  432. package/dist/scale/ScaleFillLog10.svelte +14 -0
  433. package/dist/scale/ScaleFillLog10.svelte.d.ts +4 -0
  434. package/dist/scale/ScaleFillManual.svelte +11 -0
  435. package/dist/scale/ScaleFillManual.svelte.d.ts +4 -0
  436. package/dist/scale/ScaleFillOrdinal.svelte +14 -0
  437. package/dist/scale/ScaleFillOrdinal.svelte.d.ts +3 -0
  438. package/dist/scale/ScaleFillSqrt.svelte +14 -0
  439. package/dist/scale/ScaleFillSqrt.svelte.d.ts +4 -0
  440. package/dist/scale/ScaleFillSteps.svelte +11 -0
  441. package/dist/scale/ScaleFillSteps.svelte.d.ts +4 -0
  442. package/dist/scale/ScaleFillSteps2.svelte +11 -0
  443. package/dist/scale/ScaleFillSteps2.svelte.d.ts +4 -0
  444. package/dist/scale/ScaleFillStepsn.svelte +11 -0
  445. package/dist/scale/ScaleFillStepsn.svelte.d.ts +4 -0
  446. package/dist/scale/ScaleFillViridisB.svelte +11 -0
  447. package/dist/scale/ScaleFillViridisB.svelte.d.ts +4 -0
  448. package/dist/scale/ScaleFillViridisC.svelte +11 -0
  449. package/dist/scale/ScaleFillViridisC.svelte.d.ts +4 -0
  450. package/dist/scale/ScaleFillViridisD.svelte +11 -0
  451. package/dist/scale/ScaleFillViridisD.svelte.d.ts +4 -0
  452. package/dist/scale/ScaleLinetypeBinned.svelte +15 -0
  453. package/dist/scale/ScaleLinetypeBinned.svelte.d.ts +4 -0
  454. package/dist/scale/ScaleLinetypeDiscrete.svelte +15 -0
  455. package/dist/scale/ScaleLinetypeDiscrete.svelte.d.ts +4 -0
  456. package/dist/scale/ScaleLinetypeIdentity.svelte +15 -0
  457. package/dist/scale/ScaleLinetypeIdentity.svelte.d.ts +4 -0
  458. package/dist/scale/ScaleLinetypeManual.svelte +15 -0
  459. package/dist/scale/ScaleLinetypeManual.svelte.d.ts +4 -0
  460. package/dist/scale/ScaleLinewidthBinned.svelte +14 -0
  461. package/dist/scale/ScaleLinewidthBinned.svelte.d.ts +4 -0
  462. package/dist/scale/ScaleLinewidthContinuous.svelte +14 -0
  463. package/dist/scale/ScaleLinewidthContinuous.svelte.d.ts +4 -0
  464. package/dist/scale/ScaleLinewidthDate.svelte +15 -0
  465. package/dist/scale/ScaleLinewidthDate.svelte.d.ts +5 -0
  466. package/dist/scale/ScaleLinewidthDatetime.svelte +15 -0
  467. package/dist/scale/ScaleLinewidthDatetime.svelte.d.ts +5 -0
  468. package/dist/scale/ScaleLinewidthDiscrete.svelte +14 -0
  469. package/dist/scale/ScaleLinewidthDiscrete.svelte.d.ts +4 -0
  470. package/dist/scale/ScaleLinewidthIdentity.svelte +14 -0
  471. package/dist/scale/ScaleLinewidthIdentity.svelte.d.ts +4 -0
  472. package/dist/scale/ScaleLinewidthManual.svelte +14 -0
  473. package/dist/scale/ScaleLinewidthManual.svelte.d.ts +4 -0
  474. package/dist/scale/ScaleRadius.svelte +11 -0
  475. package/dist/scale/ScaleRadius.svelte.d.ts +4 -0
  476. package/dist/scale/ScaleShapeBinned.svelte +15 -0
  477. package/dist/scale/ScaleShapeBinned.svelte.d.ts +4 -0
  478. package/dist/scale/ScaleShapeDiscrete.svelte +15 -0
  479. package/dist/scale/ScaleShapeDiscrete.svelte.d.ts +4 -0
  480. package/dist/scale/ScaleShapeIdentity.svelte +15 -0
  481. package/dist/scale/ScaleShapeIdentity.svelte.d.ts +4 -0
  482. package/dist/scale/ScaleShapeManual.svelte +15 -0
  483. package/dist/scale/ScaleShapeManual.svelte.d.ts +4 -0
  484. package/dist/scale/ScaleSizeArea.svelte +11 -0
  485. package/dist/scale/ScaleSizeArea.svelte.d.ts +4 -0
  486. package/dist/scale/ScaleSizeBinned.svelte +14 -0
  487. package/dist/scale/ScaleSizeBinned.svelte.d.ts +4 -0
  488. package/dist/scale/ScaleSizeBinnedArea.svelte +14 -0
  489. package/dist/scale/ScaleSizeBinnedArea.svelte.d.ts +4 -0
  490. package/dist/scale/ScaleSizeContinuous.svelte +14 -0
  491. package/dist/scale/ScaleSizeContinuous.svelte.d.ts +4 -0
  492. package/dist/scale/ScaleSizeDate.svelte +15 -0
  493. package/dist/scale/ScaleSizeDate.svelte.d.ts +5 -0
  494. package/dist/scale/ScaleSizeDatetime.svelte +15 -0
  495. package/dist/scale/ScaleSizeDatetime.svelte.d.ts +5 -0
  496. package/dist/scale/ScaleSizeDiscrete.svelte +14 -0
  497. package/dist/scale/ScaleSizeDiscrete.svelte.d.ts +4 -0
  498. package/dist/scale/ScaleSizeIdentity.svelte +14 -0
  499. package/dist/scale/ScaleSizeIdentity.svelte.d.ts +4 -0
  500. package/dist/scale/ScaleSizeManual.svelte +14 -0
  501. package/dist/scale/ScaleSizeManual.svelte.d.ts +4 -0
  502. package/dist/scale/ScaleXBinned.svelte +14 -0
  503. package/dist/scale/ScaleXBinned.svelte.d.ts +4 -0
  504. package/dist/scale/ScaleXContinuous.svelte +14 -0
  505. package/dist/scale/ScaleXContinuous.svelte.d.ts +4 -0
  506. package/dist/scale/ScaleXDate.svelte +12 -0
  507. package/dist/scale/ScaleXDate.svelte.d.ts +5 -0
  508. package/dist/scale/ScaleXDatetime.svelte +12 -0
  509. package/dist/scale/ScaleXDatetime.svelte.d.ts +5 -0
  510. package/dist/scale/ScaleXDiscrete.svelte +14 -0
  511. package/dist/scale/ScaleXDiscrete.svelte.d.ts +4 -0
  512. package/dist/scale/ScaleXLog10.svelte +14 -0
  513. package/dist/scale/ScaleXLog10.svelte.d.ts +4 -0
  514. package/dist/scale/ScaleXMonthDay.svelte +12 -0
  515. package/dist/scale/ScaleXMonthDay.svelte.d.ts +5 -0
  516. package/dist/scale/ScaleXReverse.svelte +15 -0
  517. package/dist/scale/ScaleXReverse.svelte.d.ts +4 -0
  518. package/dist/scale/ScaleXSqrt.svelte +14 -0
  519. package/dist/scale/ScaleXSqrt.svelte.d.ts +4 -0
  520. package/dist/scale/ScaleXTime.svelte +12 -0
  521. package/dist/scale/ScaleXTime.svelte.d.ts +5 -0
  522. package/dist/scale/ScaleYBinned.svelte +14 -0
  523. package/dist/scale/ScaleYBinned.svelte.d.ts +4 -0
  524. package/dist/scale/ScaleYContinuous.svelte +14 -0
  525. package/dist/scale/ScaleYContinuous.svelte.d.ts +4 -0
  526. package/dist/scale/ScaleYDate.svelte +12 -0
  527. package/dist/scale/ScaleYDate.svelte.d.ts +5 -0
  528. package/dist/scale/ScaleYDatetime.svelte +12 -0
  529. package/dist/scale/ScaleYDatetime.svelte.d.ts +5 -0
  530. package/dist/scale/ScaleYDiscrete.svelte +14 -0
  531. package/dist/scale/ScaleYDiscrete.svelte.d.ts +4 -0
  532. package/dist/scale/ScaleYLog10.svelte +14 -0
  533. package/dist/scale/ScaleYLog10.svelte.d.ts +4 -0
  534. package/dist/scale/ScaleYMonthDay.svelte +12 -0
  535. package/dist/scale/ScaleYMonthDay.svelte.d.ts +5 -0
  536. package/dist/scale/ScaleYReverse.svelte +15 -0
  537. package/dist/scale/ScaleYReverse.svelte.d.ts +4 -0
  538. package/dist/scale/ScaleYSqrt.svelte +14 -0
  539. package/dist/scale/ScaleYSqrt.svelte.d.ts +4 -0
  540. package/dist/scale/ScaleYTime.svelte +12 -0
  541. package/dist/scale/ScaleYTime.svelte.d.ts +5 -0
  542. package/dist/scene/Axis.svelte +159 -0
  543. package/dist/scene/Axis.svelte.d.ts +12 -0
  544. package/dist/scene/Batch.svelte +252 -0
  545. package/dist/scene/Batch.svelte.d.ts +23 -0
  546. package/dist/scene/InteractionOverlay.svelte +402 -0
  547. package/dist/scene/InteractionOverlay.svelte.d.ts +44 -0
  548. package/dist/scene/Legend.svelte +278 -0
  549. package/dist/scene/Legend.svelte.d.ts +8 -0
  550. package/dist/scene/MarkStrata.svelte +129 -0
  551. package/dist/scene/MarkStrata.svelte.d.ts +15 -0
  552. package/dist/scene/SceneOverlays.svelte +118 -0
  553. package/dist/scene/SceneOverlays.svelte.d.ts +49 -0
  554. package/dist/scene/SceneView.svelte +478 -0
  555. package/dist/scene/SceneView.svelte.d.ts +32 -0
  556. package/dist/scene/batch-presentation.svelte.d.ts +111 -0
  557. package/dist/scene/batch-presentation.svelte.js +207 -0
  558. package/dist/scene/geometry.d.ts +2 -0
  559. package/dist/scene/geometry.js +3 -0
  560. package/dist/scene/stratum-paint.d.ts +25 -0
  561. package/dist/scene/stratum-paint.js +40 -0
  562. package/dist/selection/selection-state.svelte.d.ts +23 -0
  563. package/dist/selection/selection-state.svelte.js +73 -0
  564. package/dist/selection/selection.d.ts +1 -0
  565. package/dist/selection/selection.js +2 -0
  566. package/dist/surface/CaptureSurface.svelte +109 -0
  567. package/dist/surface/CaptureSurface.svelte.d.ts +27 -0
  568. package/dist/surface/area-brush.d.ts +48 -0
  569. package/dist/surface/area-brush.js +44 -0
  570. package/dist/surface/brush-finish.d.ts +49 -0
  571. package/dist/surface/brush-finish.js +44 -0
  572. package/dist/surface/keyboard.d.ts +97 -0
  573. package/dist/surface/keyboard.js +105 -0
  574. package/dist/surface/pointer.d.ts +241 -0
  575. package/dist/surface/pointer.js +179 -0
  576. package/dist/surface/surface-description.d.ts +10 -0
  577. package/dist/surface/surface-description.js +11 -0
  578. package/dist/surface/surface-handlers.svelte.d.ts +53 -0
  579. package/dist/surface/surface-handlers.svelte.js +418 -0
  580. package/dist/surface/surface-state.svelte.d.ts +90 -0
  581. package/dist/surface/surface-state.svelte.js +161 -0
  582. package/dist/theme/Theme.svelte +27 -0
  583. package/dist/theme/Theme.svelte.d.ts +23 -0
  584. package/dist/theme/ThemeBase.svelte +13 -0
  585. package/dist/theme/ThemeBase.svelte.d.ts +8 -0
  586. package/dist/theme/ThemeBw.svelte +13 -0
  587. package/dist/theme/ThemeBw.svelte.d.ts +8 -0
  588. package/dist/theme/ThemeClassic.svelte +13 -0
  589. package/dist/theme/ThemeClassic.svelte.d.ts +8 -0
  590. package/dist/theme/ThemeClean.svelte +13 -0
  591. package/dist/theme/ThemeClean.svelte.d.ts +8 -0
  592. package/dist/theme/ThemeDark.svelte +13 -0
  593. package/dist/theme/ThemeDark.svelte.d.ts +8 -0
  594. package/dist/theme/ThemeDefault.svelte +13 -0
  595. package/dist/theme/ThemeDefault.svelte.d.ts +8 -0
  596. package/dist/theme/ThemeEconomist.svelte +13 -0
  597. package/dist/theme/ThemeEconomist.svelte.d.ts +8 -0
  598. package/dist/theme/ThemeEconomistwhite.svelte +13 -0
  599. package/dist/theme/ThemeEconomistwhite.svelte.d.ts +8 -0
  600. package/dist/theme/ThemeFew.svelte +13 -0
  601. package/dist/theme/ThemeFew.svelte.d.ts +8 -0
  602. package/dist/theme/ThemeFivethirtyeight.svelte +14 -0
  603. package/dist/theme/ThemeFivethirtyeight.svelte.d.ts +9 -0
  604. package/dist/theme/ThemeGgplot2.svelte +13 -0
  605. package/dist/theme/ThemeGgplot2.svelte.d.ts +8 -0
  606. package/dist/theme/ThemeGray.svelte +13 -0
  607. package/dist/theme/ThemeGray.svelte.d.ts +8 -0
  608. package/dist/theme/ThemeGrey.svelte +13 -0
  609. package/dist/theme/ThemeGrey.svelte.d.ts +8 -0
  610. package/dist/theme/ThemeHc.svelte +13 -0
  611. package/dist/theme/ThemeHc.svelte.d.ts +8 -0
  612. package/dist/theme/ThemeHcdark.svelte +13 -0
  613. package/dist/theme/ThemeHcdark.svelte.d.ts +8 -0
  614. package/dist/theme/ThemeHrbr.svelte +13 -0
  615. package/dist/theme/ThemeHrbr.svelte.d.ts +8 -0
  616. package/dist/theme/ThemeIgray.svelte +13 -0
  617. package/dist/theme/ThemeIgray.svelte.d.ts +8 -0
  618. package/dist/theme/ThemeLight.svelte +13 -0
  619. package/dist/theme/ThemeLight.svelte.d.ts +8 -0
  620. package/dist/theme/ThemeLinedraw.svelte +13 -0
  621. package/dist/theme/ThemeLinedraw.svelte.d.ts +8 -0
  622. package/dist/theme/ThemeMap.svelte +13 -0
  623. package/dist/theme/ThemeMap.svelte.d.ts +8 -0
  624. package/dist/theme/ThemeMinimal.svelte +13 -0
  625. package/dist/theme/ThemeMinimal.svelte.d.ts +8 -0
  626. package/dist/theme/ThemePander.svelte +13 -0
  627. package/dist/theme/ThemePander.svelte.d.ts +8 -0
  628. package/dist/theme/ThemeSolarized.svelte +13 -0
  629. package/dist/theme/ThemeSolarized.svelte.d.ts +8 -0
  630. package/dist/theme/ThemeSolarized2.svelte +13 -0
  631. package/dist/theme/ThemeSolarized2.svelte.d.ts +8 -0
  632. package/dist/theme/ThemeSolarized2dark.svelte +13 -0
  633. package/dist/theme/ThemeSolarized2dark.svelte.d.ts +8 -0
  634. package/dist/theme/ThemeSolarizeddark.svelte +14 -0
  635. package/dist/theme/ThemeSolarizeddark.svelte.d.ts +9 -0
  636. package/dist/theme/ThemeSolid.svelte +13 -0
  637. package/dist/theme/ThemeSolid.svelte.d.ts +8 -0
  638. package/dist/theme/ThemeStata.svelte +13 -0
  639. package/dist/theme/ThemeStata.svelte.d.ts +8 -0
  640. package/dist/theme/ThemeStatas1color.svelte +13 -0
  641. package/dist/theme/ThemeStatas1color.svelte.d.ts +8 -0
  642. package/dist/theme/ThemeTest.svelte +14 -0
  643. package/dist/theme/ThemeTest.svelte.d.ts +9 -0
  644. package/dist/theme/ThemeTufte.svelte +13 -0
  645. package/dist/theme/ThemeTufte.svelte.d.ts +8 -0
  646. package/dist/theme/ThemeVoid.svelte +14 -0
  647. package/dist/theme/ThemeVoid.svelte.d.ts +9 -0
  648. package/dist/theme/ThemeWsj.svelte +13 -0
  649. package/dist/theme/ThemeWsj.svelte.d.ts +8 -0
  650. package/dist/theme/factory.svelte.d.ts +36 -0
  651. package/dist/theme/factory.svelte.js +100 -0
  652. package/dist/zoom/zoom-state.svelte.d.ts +44 -0
  653. package/dist/zoom/zoom-state.svelte.js +121 -0
  654. package/dist/zoom/zoom.d.ts +1 -0
  655. package/dist/zoom/zoom.js +2 -0
  656. package/package.json +83 -0
@@ -0,0 +1,284 @@
1
+ import { encodeKey } from "@ggts-sh/core";
2
+ import { isLegendValueKeyVisible, isLegendValueVisible, legendFilterValueKeys, nextLegendFilterValues, reconcileLegendFilterValues, } from "./filter.js";
3
+ // ---------------------------------------------------------------------------
4
+ // Public types
5
+ // ---------------------------------------------------------------------------
6
+ const FILTERABLE_LEGEND_SCALES = [
7
+ "color",
8
+ "fill",
9
+ "size",
10
+ "linewidth",
11
+ "alpha",
12
+ "shape",
13
+ "linetype",
14
+ ];
15
+ // ---------------------------------------------------------------------------
16
+ // Factory
17
+ // ---------------------------------------------------------------------------
18
+ /**
19
+ * Create the legend-filter controller. Construction registers capability-reset,
20
+ * mode-reset, and catalog-reconcile effects (#627).
21
+ */
22
+ export function createLegendFilterState(deps) {
23
+ const legendFilterOptions = $derived.by(() => {
24
+ const legendFilter = deps.legendFilterProp();
25
+ if (legendFilter === false)
26
+ return null;
27
+ return {
28
+ mode: typeof legendFilter === "object" ? (legendFilter.mode ?? "exclude") : "exclude",
29
+ multiple: typeof legendFilter === "object" ? (legendFilter.multiple ?? true) : true,
30
+ };
31
+ });
32
+ let localLegendFilters = $state([]);
33
+ let appliedLegendFilterMode = $state(null);
34
+ const legendCatalogFingerprints = new Map();
35
+ const activeLegendFilterBindings = $derived.by(() => {
36
+ const bindings = new Set();
37
+ const effectiveSpec = deps.effectiveSpec();
38
+ if (effectiveSpec === null)
39
+ return bindings;
40
+ for (const layer of effectiveSpec.layers) {
41
+ for (const scale of FILTERABLE_LEGEND_SCALES) {
42
+ const own = layer.aes?.[scale];
43
+ // Explicit null is an unset (normalize's null-unset semantics): the
44
+ // layer deliberately removed the plot-level binding — never inherit.
45
+ if (own === null)
46
+ continue;
47
+ const channel = own ?? effectiveSpec.aes?.[scale];
48
+ if (channel !== null && channel !== undefined && "field" in channel)
49
+ bindings.add(`${scale}:${channel.field}`);
50
+ }
51
+ }
52
+ return bindings;
53
+ });
54
+ const effectiveLegendFilters = $derived(legendFilterOptions === null
55
+ ? []
56
+ : localLegendFilters.filter((clause) => activeLegendFilterBindings.has(`${clause.scale}:${clause.field}`)));
57
+ let legendFilterPointerType = null;
58
+ function emitLegendFilter(event) {
59
+ deps.onlegendfilter()?.(event);
60
+ deps.oninteraction()?.(event);
61
+ }
62
+ // A disabled capability or a remapped spec must never leave an invisible
63
+ // filter active. Reset the chart-local filter set atomically so the public
64
+ // `clear` event always describes the actual resulting state.
65
+ $effect(() => {
66
+ if (effectiveLegendFilters.length === localLegendFilters.length)
67
+ return;
68
+ localLegendFilters = [];
69
+ emitLegendFilter({
70
+ type: "legend-filter",
71
+ phase: "clear",
72
+ source: "programmatic",
73
+ clause: null,
74
+ });
75
+ deps.announce("Legend filters reset after the filter capability changed.");
76
+ });
77
+ // Mode changes are controlled API changes, not reinterpretations of old
78
+ // state. Reset active clauses so an exclude set can never become a stale
79
+ // include set (or vice versa).
80
+ $effect(() => {
81
+ const mode = legendFilterOptions?.mode ?? null;
82
+ if (appliedLegendFilterMode === null) {
83
+ appliedLegendFilterMode = mode;
84
+ return;
85
+ }
86
+ if (mode === appliedLegendFilterMode)
87
+ return;
88
+ appliedLegendFilterMode = mode;
89
+ if (localLegendFilters.length === 0)
90
+ return;
91
+ localLegendFilters = [];
92
+ emitLegendFilter({
93
+ type: "legend-filter",
94
+ phase: "clear",
95
+ source: "programmatic",
96
+ clause: null,
97
+ });
98
+ deps.announce("Legend filters reset after the filter mode changed.");
99
+ });
100
+ function computeEntries(model) {
101
+ if (model === null || legendFilterOptions === null)
102
+ return [];
103
+ return model.scene.legends.flatMap((sceneLegend) => {
104
+ if (sceneLegend.type !== "discrete" || sceneLegend.interactive === false)
105
+ return [];
106
+ if (!FILTERABLE_LEGEND_SCALES.some((scale) => scale === sceneLegend.scale))
107
+ return [];
108
+ const fields = new Set(model.layerFields
109
+ .flat()
110
+ .filter((mapped) => mapped.channel === sceneLegend.scale && mapped.source !== "stat")
111
+ .map((mapped) => mapped.field));
112
+ const field = fields.values().next().value;
113
+ // One combined scale fed by unlike fields has no honest one-toggle
114
+ // filtering semantics. Keep the static legend rather than filtering
115
+ // only whichever field happened to be encountered first.
116
+ if (field === undefined || fields.size !== 1)
117
+ return [];
118
+ // A scaled constant (aes { value, scale: true }) feeds this legend
119
+ // without a field: toggling its entry would filter an unrelated field
120
+ // while the constant-colored layer stays rendered. Keep it static —
121
+ // but only when that constant is actually a *visible* legend entry.
122
+ // Rowless annotation constants train the scale and appear on
123
+ // layerScaledConstants for focus/index, yet are excluded from the
124
+ // interactive legend domain (#598); those must not disable filters.
125
+ const scaledConstantKeys = new Set(model.layerScaledConstants
126
+ .map((constants) => constants[sceneLegend.scale])
127
+ .filter((value) => value !== undefined)
128
+ .map((value) => encodeKey(value)));
129
+ if (scaledConstantKeys.size > 0 &&
130
+ sceneLegend.entries.some((entry) => scaledConstantKeys.has(encodeKey(entry.value))))
131
+ return [];
132
+ const current = localLegendFilters.find((clause) => clause.scale === sceneLegend.scale && clause.field === field);
133
+ if (current === undefined) {
134
+ return sceneLegend.entries.map((entry) => ({
135
+ legend: sceneLegend,
136
+ entry,
137
+ field,
138
+ visible: true,
139
+ }));
140
+ }
141
+ // One Set per clause, then O(1) membership per entry (O(E+V) not O(E×V)).
142
+ const valueKeys = legendFilterValueKeys(current.values);
143
+ const mode = current.mode;
144
+ return sceneLegend.entries.map((entry) => ({
145
+ legend: sceneLegend,
146
+ entry,
147
+ field,
148
+ visible: isLegendValueKeyVisible(valueKeys, entry.value, mode),
149
+ }));
150
+ });
151
+ }
152
+ function legendFilterSource(event) {
153
+ if (event.detail === 0)
154
+ return "keyboard";
155
+ return legendFilterPointerType === "touch" ? "touch" : "pointer";
156
+ }
157
+ function toggle(target, event) {
158
+ if (legendFilterOptions === null)
159
+ return target.visible;
160
+ // Controlled checkbox: cancel the UA toggle when this still runs inside
161
+ // the click event. Delegated/async handlers can miss that window — the
162
+ // host forces input.checked from the returned visibility.
163
+ event.preventDefault();
164
+ const catalog = target.legend.entries.map((entry) => entry.value);
165
+ const index = localLegendFilters.findIndex((clause) => clause.scale === target.legend.scale && clause.field === target.field);
166
+ const current = localLegendFilters[index];
167
+ const baseline = current?.values ?? (legendFilterOptions.mode === "include" ? catalog : []);
168
+ const values = nextLegendFilterValues(baseline, target.entry.value, catalog, legendFilterOptions.mode, legendFilterOptions.multiple);
169
+ const clause = Object.freeze({
170
+ scale: target.legend.scale,
171
+ field: target.field,
172
+ values,
173
+ mode: legendFilterOptions.mode,
174
+ });
175
+ localLegendFilters =
176
+ index < 0
177
+ ? [...localLegendFilters, clause]
178
+ : localLegendFilters.map((candidate, candidateIndex) => candidateIndex === index ? clause : candidate);
179
+ const source = legendFilterSource(event);
180
+ legendFilterPointerType = null;
181
+ const visible = isLegendValueVisible(values, target.entry.value, legendFilterOptions.mode);
182
+ const filterEvent = Object.freeze({
183
+ type: "legend-filter",
184
+ phase: "change",
185
+ source,
186
+ clause,
187
+ });
188
+ emitLegendFilter(filterEvent);
189
+ deps.announce(`${target.entry.label} ${visible ? "shown" : "hidden"}.`);
190
+ return visible;
191
+ }
192
+ function reset(event) {
193
+ if (localLegendFilters.length === 0)
194
+ return;
195
+ // Focus restoration is owned by the child component (zero DOM here).
196
+ const source = legendFilterSource(event);
197
+ localLegendFilters = [];
198
+ legendFilterPointerType = null;
199
+ emitLegendFilter(Object.freeze({
200
+ type: "legend-filter",
201
+ phase: "clear",
202
+ source,
203
+ clause: null,
204
+ }));
205
+ }
206
+ function setPointerType(type) {
207
+ legendFilterPointerType = type;
208
+ }
209
+ // Catalog changes prune values that no longer exist. An emptied clause is
210
+ // removed, so a category that disappears and later returns is visible by
211
+ // default. resetScales() deliberately does not alter this filter state.
212
+ $effect(() => {
213
+ const catalogs = new Map();
214
+ for (const target of deps.catalogEntries()) {
215
+ const key = `${target.legend.scale}:${target.field}`;
216
+ const catalog = catalogs.get(key) ?? [];
217
+ catalog.push(target.entry.value);
218
+ catalogs.set(key, catalog);
219
+ }
220
+ let next = localLegendFilters;
221
+ const reconciled = [];
222
+ // A clause whose field is still mapped but whose legend stopped being
223
+ // filterable (second unlike field on the scale, a scaled constant, a
224
+ // non-discrete legend) has no checkbox or reset control left — remove it
225
+ // rather than filtering rows invisibly. Unmapped fields are handled by
226
+ // the capability reset above.
227
+ if (deps.model() !== null && legendFilterOptions !== null) {
228
+ for (const clause of next.filter((candidate) => activeLegendFilterBindings.has(`${candidate.scale}:${candidate.field}`) &&
229
+ !catalogs.has(`${candidate.scale}:${candidate.field}`))) {
230
+ next = next.filter((candidate) => candidate !== clause);
231
+ reconciled.push({ clause, removed: true });
232
+ }
233
+ }
234
+ for (const [key, catalog] of catalogs) {
235
+ const fingerprint = JSON.stringify(catalog.map((value) => encodeKey(value)));
236
+ const priorFingerprint = legendCatalogFingerprints.get(key);
237
+ legendCatalogFingerprints.set(key, fingerprint);
238
+ if (priorFingerprint === undefined || priorFingerprint === fingerprint)
239
+ continue;
240
+ const index = next.findIndex((clause) => `${clause.scale}:${clause.field}` === key);
241
+ if (index < 0)
242
+ continue;
243
+ const clause = next[index];
244
+ const values = reconcileLegendFilterValues(clause.values, catalog);
245
+ reconciled.push({
246
+ clause: Object.freeze({ ...clause, values }),
247
+ removed: values.length === 0,
248
+ });
249
+ next =
250
+ values.length === 0
251
+ ? next.filter((_, candidateIndex) => candidateIndex !== index)
252
+ : next.map((candidate, candidateIndex) => candidateIndex === index ? Object.freeze({ ...candidate, values }) : candidate);
253
+ }
254
+ for (const key of legendCatalogFingerprints.keys())
255
+ if (!catalogs.has(key))
256
+ legendCatalogFingerprints.delete(key);
257
+ if (next === localLegendFilters)
258
+ return;
259
+ localLegendFilters = [...next];
260
+ for (const { clause, removed } of reconciled)
261
+ emitLegendFilter({
262
+ type: "legend-filter",
263
+ phase: removed ? "remove" : "change",
264
+ source: "programmatic",
265
+ clause,
266
+ });
267
+ deps.announce("Legend filters reconciled with the available groups.");
268
+ });
269
+ return {
270
+ get options() {
271
+ return legendFilterOptions;
272
+ },
273
+ get filters() {
274
+ return effectiveLegendFilters;
275
+ },
276
+ get hasActiveFilters() {
277
+ return localLegendFilters.length > 0;
278
+ },
279
+ computeEntries,
280
+ toggle,
281
+ reset,
282
+ setPointerType,
283
+ };
284
+ }
@@ -0,0 +1 @@
1
+ export { type LegendFilterClause, type LegendFilterOptions, type LegendFilterInput, type LegendFilterEvent, legendFilterValueKeys, isLegendValueKeyVisible, isLegendValueVisible, reconcileLegendFilterValues, nextLegendFilterValues, } from "@ggts-sh/core/interaction";
@@ -0,0 +1,2 @@
1
+ // Shared pure behavior used by React and Svelte.
2
+ export { legendFilterValueKeys, isLegendValueKeyVisible, isLegendValueVisible, reconcileLegendFilterValues, nextLegendFilterValues, } from "@ggts-sh/core/interaction";
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Pure legend emphasis helpers: pressed-identity, preview decisions, and
3
+ * effective emphasis key precedence (preview / controller / local).
4
+ *
5
+ * Identity/roving: `focus.ts`. Host `$effect` plans: `focus-plans.ts`.
6
+ */
7
+ import type { InteractionSource } from "../interaction/interaction.js";
8
+ import { type InteractiveLegendEntry, type LegendEntryIdentity, type LegendInteractionSource } from "./focus.js";
9
+ export type FindLegendPressedIdentityInput = {
10
+ readonly keys: readonly PropertyKey[];
11
+ readonly entries: readonly InteractiveLegendEntry[];
12
+ readonly keyIndex: ReadonlyMap<string, readonly PropertyKey[]>;
13
+ readonly committed: {
14
+ readonly identity: LegendEntryIdentity;
15
+ readonly keys: readonly PropertyKey[];
16
+ } | null;
17
+ };
18
+ /**
19
+ * Resolve which legend entry should appear pressed.
20
+ * Committed identity wins when its key set still matches (even if multiple
21
+ * entries share the same keys). Otherwise require exactly one matching entry.
22
+ *
23
+ * Complexity: O(K + E) — one Set for the emphasis keys, then per-entry size
24
+ * short-circuit + membership (no Set rebuild per entry). Multi-match returns
25
+ * null as soon as a second hit is found. Empty keys, or empty entries with no
26
+ * committed identity, return before allocating the Set.
27
+ */
28
+ export declare function findLegendPressedIdentity(input: FindLegendPressedIdentityInput): LegendEntryIdentity | null;
29
+ /**
30
+ * Decide what a legend preview attempt should do with resolved keys.
31
+ * Empty key sets clear any active preview (empty domain entry / stale target)
32
+ * rather than leaving the previous entry highlighted.
33
+ *
34
+ * Non-empty `set` carries mapped InteractionSource via `legendInteractionSource`
35
+ * so the host does not re-map `action.source` after the pure decision.
36
+ */
37
+ export declare function resolveLegendPreviewKeysDecision(input: {
38
+ readonly keys: readonly PropertyKey[];
39
+ /** Host: `action.source` (legend entry interaction source). */
40
+ readonly entrySource: LegendInteractionSource;
41
+ }): {
42
+ readonly type: "clear";
43
+ } | {
44
+ readonly type: "set";
45
+ readonly keys: readonly PropertyKey[];
46
+ readonly source: InteractionSource;
47
+ };
48
+ /**
49
+ * Emphasis keys shown while legend focus is enabled vs disabled.
50
+ * When disabled, chart-local preview and local commits must not mute the plot
51
+ * (controls are gone). Controller emphasis still flows through when present.
52
+ */
53
+ export declare function resolveLegendEmphasisKeys(input: {
54
+ readonly legendFocusEnabled: boolean;
55
+ readonly previewKeys: readonly PropertyKey[] | null;
56
+ readonly controllerKeys: readonly PropertyKey[] | null;
57
+ readonly localKeys: readonly PropertyKey[];
58
+ }): readonly PropertyKey[];
59
+ export type LegendPreviewState = {
60
+ readonly identity: LegendEntryIdentity;
61
+ readonly keys: readonly PropertyKey[];
62
+ };
63
+ /**
64
+ * Reconcile a transient preview against the current entry list / key index.
65
+ * Clears when the identity disappears or its keys empty; refreshes keys when
66
+ * membership changes for the same identity.
67
+ */
68
+ export declare function reconcileLegendPreview(input: {
69
+ readonly preview: LegendPreviewState | null;
70
+ readonly entries: readonly InteractiveLegendEntry[];
71
+ readonly keyIndex: ReadonlyMap<string, readonly PropertyKey[]>;
72
+ }): LegendPreviewState | null;
@@ -0,0 +1,91 @@
1
+ import { keysForLegendEntry, legendInteractionSource, samePropertyKeySet, } from "./focus.js";
2
+ /**
3
+ * Whether a first-seen-unique key array matches a Set's membership.
4
+ * Used by pressed-identity resolution so entry compares stay O(K) without
5
+ * allocating a Set per legend entry. Entry-key index values and committed
6
+ * keys are frozen unique arrays from `buildLegendEntryKeyIndex`.
7
+ */
8
+ function uniqueKeysMatchSet(keys, keySet) {
9
+ if (keys.length !== keySet.size)
10
+ return false;
11
+ for (const key of keys)
12
+ if (!keySet.has(key))
13
+ return false;
14
+ return true;
15
+ }
16
+ /**
17
+ * Resolve which legend entry should appear pressed.
18
+ * Committed identity wins when its key set still matches (even if multiple
19
+ * entries share the same keys). Otherwise require exactly one matching entry.
20
+ *
21
+ * Complexity: O(K + E) — one Set for the emphasis keys, then per-entry size
22
+ * short-circuit + membership (no Set rebuild per entry). Multi-match returns
23
+ * null as soon as a second hit is found. Empty keys, or empty entries with no
24
+ * committed identity, return before allocating the Set.
25
+ */
26
+ export function findLegendPressedIdentity(input) {
27
+ if (input.keys.length === 0)
28
+ return null;
29
+ // Ramp-only / no discrete legends and no commit: nothing to match (issue #209).
30
+ if (input.entries.length === 0 && input.committed === null)
31
+ return null;
32
+ const inputSet = new Set(input.keys);
33
+ if (input.committed !== null && uniqueKeysMatchSet(input.committed.keys, inputSet))
34
+ return input.committed.identity;
35
+ let match = null;
36
+ for (const entry of input.entries) {
37
+ const entryKeys = keysForLegendEntry(input.keyIndex, entry.identity);
38
+ if (!uniqueKeysMatchSet(entryKeys, inputSet))
39
+ continue;
40
+ if (match !== null)
41
+ return null;
42
+ match = entry.identity;
43
+ }
44
+ return match;
45
+ }
46
+ /**
47
+ * Decide what a legend preview attempt should do with resolved keys.
48
+ * Empty key sets clear any active preview (empty domain entry / stale target)
49
+ * rather than leaving the previous entry highlighted.
50
+ *
51
+ * Non-empty `set` carries mapped InteractionSource via `legendInteractionSource`
52
+ * so the host does not re-map `action.source` after the pure decision.
53
+ */
54
+ export function resolveLegendPreviewKeysDecision(input) {
55
+ if (input.keys.length === 0)
56
+ return { type: "clear" };
57
+ return {
58
+ type: "set",
59
+ keys: input.keys,
60
+ source: legendInteractionSource(input.entrySource),
61
+ };
62
+ }
63
+ /**
64
+ * Emphasis keys shown while legend focus is enabled vs disabled.
65
+ * When disabled, chart-local preview and local commits must not mute the plot
66
+ * (controls are gone). Controller emphasis still flows through when present.
67
+ */
68
+ export function resolveLegendEmphasisKeys(input) {
69
+ if (!input.legendFocusEnabled)
70
+ return input.controllerKeys ?? [];
71
+ return input.previewKeys ?? input.controllerKeys ?? input.localKeys;
72
+ }
73
+ /**
74
+ * Reconcile a transient preview against the current entry list / key index.
75
+ * Clears when the identity disappears or its keys empty; refreshes keys when
76
+ * membership changes for the same identity.
77
+ */
78
+ export function reconcileLegendPreview(input) {
79
+ if (input.preview === null)
80
+ return null;
81
+ const current = input.entries.find(({ identity }) => identity.scale === input.preview.identity.scale &&
82
+ identity.entryIndex === input.preview.identity.entryIndex);
83
+ if (current === undefined)
84
+ return null;
85
+ const keys = keysForLegendEntry(input.keyIndex, current.identity);
86
+ if (keys.length === 0)
87
+ return null;
88
+ if (samePropertyKeySet(keys, input.preview.keys))
89
+ return input.preview;
90
+ return { identity: current.identity, keys };
91
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Pure host `$effect` plans for legend focus (committed reconcile, disable
3
+ * clear, roving focus sync). Controllers own DOM / emission side effects.
4
+ *
5
+ * Identity/roving: `focus.ts`. Emphasis/preview: `focus-emphasis.ts`.
6
+ */
7
+ import { type InteractiveLegendEntry, type LegendEntryIdentity } from "./focus.js";
8
+ export type LegendCommittedState = {
9
+ readonly identity: LegendEntryIdentity;
10
+ readonly keys: readonly PropertyKey[];
11
+ };
12
+ export type LegendCommittedReconcilePlan = {
13
+ readonly type: "noop";
14
+ } | {
15
+ readonly type: "clear-committed";
16
+ } | {
17
+ readonly type: "clear-committed-local-emit";
18
+ };
19
+ /**
20
+ * Pure plan for the committed-legend reconcile effect after data reshuffle.
21
+ *
22
+ * Owns entry lookup + key compare (same shape as `reconcileLegendPreview`).
23
+ * Host on non-noop: always nulls `legendCommitted`. On local-emit also clears
24
+ * chart-local emphasis keys and emits legend-focus clear.
25
+ *
26
+ * 1. no commit → noop
27
+ * 2. live keys still match → noop
28
+ * 3. mismatch + local emphasis active → clear-committed-local-emit
29
+ * 4. mismatch otherwise → clear-committed
30
+ */
31
+ export declare function planLegendCommittedReconcile(input: {
32
+ readonly committed: LegendCommittedState | null;
33
+ readonly entries: readonly InteractiveLegendEntry[];
34
+ readonly keyIndex: ReadonlyMap<string, readonly PropertyKey[]>;
35
+ /** Host: `interaction === undefined`. */
36
+ readonly usesLocalEmphasis: boolean;
37
+ readonly localEmphasisCount: number;
38
+ }): LegendCommittedReconcilePlan;
39
+ export type LegendFocusDisabledClearPlan = {
40
+ readonly type: "noop";
41
+ } | {
42
+ readonly type: "clear-host";
43
+ } | {
44
+ readonly type: "clear-host-local";
45
+ };
46
+ /**
47
+ * Pure plan when legend focus is turned off at runtime.
48
+ *
49
+ * 1. still enabled → noop
50
+ * 2. host legend state already empty → noop
51
+ * 3. chart-local mode → clear preview+committed+localEmphasisKeys
52
+ * 4. controller mode → clear preview+committed only (controller emphasis stays)
53
+ */
54
+ export declare function planLegendFocusDisabledClear(input: {
55
+ readonly legendFocusEnabled: boolean;
56
+ readonly hasPreview: boolean;
57
+ readonly hasCommitted: boolean;
58
+ readonly hasLocalEmphasis: boolean;
59
+ /** Host: `interaction === undefined`. */
60
+ readonly usesLocalEmphasis: boolean;
61
+ }): LegendFocusDisabledClearPlan;
62
+ export type LegendRovingFocusSyncPlan = {
63
+ readonly type: "noop";
64
+ readonly nextIndex: number;
65
+ } | {
66
+ readonly type: "clamp-roving";
67
+ readonly nextIndex: number;
68
+ } | {
69
+ readonly type: "refocus";
70
+ readonly nextIndex: number;
71
+ readonly returnIndex: number;
72
+ };
73
+ /**
74
+ * Pure plan for the legend roving-index `$effect.pre`.
75
+ *
76
+ * Host owns `document.activeElement` / dataset parse for `focusedIndex`.
77
+ * `Number(dataset.index)` yields NaN when missing — pass that through so
78
+ * `clampLegendRovingIndex` maps non-finite → 0 (refocus first entry).
79
+ *
80
+ * - focusedIndex === null OR entryCount === 0 → no DOM refocus
81
+ * (clamp-roving when nextIndex differs from current, else noop)
82
+ * - otherwise → refocus with returnIndex = clamp(focusedIndex, count)
83
+ */
84
+ export declare function planLegendRovingFocusSync(input: {
85
+ readonly currentRoving: number;
86
+ readonly entryCount: number;
87
+ /** null = focus not on a legend target inside root; may be NaN. */
88
+ readonly focusedIndex: number | null;
89
+ }): LegendRovingFocusSyncPlan;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Pure host `$effect` plans for legend focus (committed reconcile, disable
3
+ * clear, roving focus sync). Controllers own DOM / emission side effects.
4
+ *
5
+ * Identity/roving: `focus.ts`. Emphasis/preview: `focus-emphasis.ts`.
6
+ */
7
+ import { clampLegendRovingIndex, keysForLegendEntry, samePropertyKeySet, } from "./focus.js";
8
+ /**
9
+ * Pure plan for the committed-legend reconcile effect after data reshuffle.
10
+ *
11
+ * Owns entry lookup + key compare (same shape as `reconcileLegendPreview`).
12
+ * Host on non-noop: always nulls `legendCommitted`. On local-emit also clears
13
+ * chart-local emphasis keys and emits legend-focus clear.
14
+ *
15
+ * 1. no commit → noop
16
+ * 2. live keys still match → noop
17
+ * 3. mismatch + local emphasis active → clear-committed-local-emit
18
+ * 4. mismatch otherwise → clear-committed
19
+ */
20
+ export function planLegendCommittedReconcile(input) {
21
+ if (input.committed === null)
22
+ return { type: "noop" };
23
+ const current = input.entries.find(({ identity }) => identity.scale === input.committed.identity.scale &&
24
+ identity.entryIndex === input.committed.identity.entryIndex);
25
+ const currentKeys = current === undefined ? [] : keysForLegendEntry(input.keyIndex, current.identity);
26
+ if (samePropertyKeySet(currentKeys, input.committed.keys))
27
+ return { type: "noop" };
28
+ if (input.usesLocalEmphasis && input.localEmphasisCount > 0) {
29
+ return { type: "clear-committed-local-emit" };
30
+ }
31
+ return { type: "clear-committed" };
32
+ }
33
+ /**
34
+ * Pure plan when legend focus is turned off at runtime.
35
+ *
36
+ * 1. still enabled → noop
37
+ * 2. host legend state already empty → noop
38
+ * 3. chart-local mode → clear preview+committed+localEmphasisKeys
39
+ * 4. controller mode → clear preview+committed only (controller emphasis stays)
40
+ */
41
+ export function planLegendFocusDisabledClear(input) {
42
+ if (input.legendFocusEnabled)
43
+ return { type: "noop" };
44
+ if (!input.hasPreview && !input.hasCommitted && !input.hasLocalEmphasis) {
45
+ return { type: "noop" };
46
+ }
47
+ return input.usesLocalEmphasis ? { type: "clear-host-local" } : { type: "clear-host" };
48
+ }
49
+ /**
50
+ * Pure plan for the legend roving-index `$effect.pre`.
51
+ *
52
+ * Host owns `document.activeElement` / dataset parse for `focusedIndex`.
53
+ * `Number(dataset.index)` yields NaN when missing — pass that through so
54
+ * `clampLegendRovingIndex` maps non-finite → 0 (refocus first entry).
55
+ *
56
+ * - focusedIndex === null OR entryCount === 0 → no DOM refocus
57
+ * (clamp-roving when nextIndex differs from current, else noop)
58
+ * - otherwise → refocus with returnIndex = clamp(focusedIndex, count)
59
+ */
60
+ export function planLegendRovingFocusSync(input) {
61
+ const nextIndex = clampLegendRovingIndex(input.currentRoving, input.entryCount);
62
+ if (input.focusedIndex === null || input.entryCount === 0) {
63
+ return nextIndex === input.currentRoving
64
+ ? { type: "noop", nextIndex }
65
+ : { type: "clamp-roving", nextIndex };
66
+ }
67
+ return {
68
+ type: "refocus",
69
+ nextIndex,
70
+ returnIndex: clampLegendRovingIndex(input.focusedIndex, input.entryCount),
71
+ };
72
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Host-derived reconcile effects for the legend-focus controller (S5).
3
+ *
4
+ * Hosts the four reconcile effects previously registered inside
5
+ * focus-state.installHostDerivedEffects: roving-index sync ($effect.pre),
6
+ * committed reconcile, preview reconcile, and focus-disabled clear.
7
+ *
8
+ * Registration happens synchronously inside installHostDerivedEffects — the
9
+ * late-hook ordering is intentional: these effects must not register before
10
+ * the host declares the entry/pressed deriveds that the controller's compute*
11
+ * methods feed (#627).
12
+ *
13
+ * Ports are LIVE getters/setters over the controller's rune state — never
14
+ * snapshots. Shared controller emphasis survives disable while local emphasis
15
+ * clears (planLegendFocusDisabledClear "clear-host" vs "clear-host-local").
16
+ */
17
+ import type { PlotInteractionController } from "../interaction/controller.svelte.js";
18
+ import type { LegendFocusEvent } from "../interaction/interaction.js";
19
+ import type { ScopedStore } from "../interaction/scoped-store.svelte.js";
20
+ import { type InteractiveLegendEntry, type LegendEntryAction, type LegendEntryIdentity } from "./focus.js";
21
+ import type { LegendEntryKeyAccess } from "./entry-key-index.svelte.js";
22
+ export type LegendFocusPreviewState = {
23
+ action: LegendEntryAction;
24
+ keys: readonly PropertyKey[];
25
+ } | null;
26
+ export type LegendFocusCommittedState = {
27
+ identity: LegendEntryIdentity;
28
+ keys: readonly PropertyKey[];
29
+ } | null;
30
+ export type LegendFocusReconcilePorts = {
31
+ readonly entries: () => readonly InteractiveLegendEntry[];
32
+ readonly entryKeys: () => LegendEntryKeyAccess;
33
+ readonly root: () => HTMLElement | null;
34
+ readonly interaction: () => PlotInteractionController | undefined;
35
+ readonly legendFocusEnabled: () => boolean;
36
+ /** Emphasis store — local shadow when controller-driven, source of truth local. */
37
+ readonly emphasisKeys: ScopedStore<readonly PropertyKey[]>;
38
+ /** Live accessors over the controller's rune state (never snapshotted). */
39
+ readonly rovingIndex: () => number;
40
+ readonly setRovingIndex: (next: number) => void;
41
+ readonly committed: () => LegendFocusCommittedState;
42
+ readonly setCommitted: (next: LegendFocusCommittedState) => void;
43
+ readonly preview: () => LegendFocusPreviewState;
44
+ readonly setPreview: (next: LegendFocusPreviewState) => void;
45
+ readonly emitLegendFocus: (event: LegendFocusEvent) => void;
46
+ readonly previewLegend: (action: LegendEntryAction | null) => void;
47
+ };
48
+ /**
49
+ * Register the four reconcile effects. Called synchronously from
50
+ * `installHostDerivedEffects` while the component initializes — never from a
51
+ * callback or after init.
52
+ */
53
+ export declare function installLegendFocusReconcileEffects(ports: LegendFocusReconcilePorts): void;