@genome-spy/core 0.70.0 → 0.71.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 (259) hide show
  1. package/dist/bundle/index.es.js +3865 -3631
  2. package/dist/bundle/index.js +80 -80
  3. package/dist/schema.json +0 -48
  4. package/dist/src/genomeSpy/containerUi.d.ts.map +1 -1
  5. package/dist/src/genomeSpy/containerUi.js +0 -1
  6. package/dist/src/genomeSpy/viewHighlight.js +2 -2
  7. package/dist/src/genomeSpy.d.ts +3 -3
  8. package/dist/src/genomeSpy.d.ts.map +1 -1
  9. package/dist/src/genomeSpy.js +27 -3
  10. package/dist/src/marks/mark.d.ts +1 -1
  11. package/dist/src/marks/mark.d.ts.map +1 -1
  12. package/dist/src/spec/view.d.ts +0 -10
  13. package/dist/src/utils/keyboardZoomMotion.d.ts +93 -0
  14. package/dist/src/utils/keyboardZoomMotion.d.ts.map +1 -0
  15. package/dist/src/utils/keyboardZoomMotion.js +285 -0
  16. package/dist/src/view/axisGridView.d.ts +1 -1
  17. package/dist/src/view/axisGridView.js +0 -1
  18. package/dist/src/view/axisView.d.ts +1 -1
  19. package/dist/src/view/concatView.d.ts +6 -3
  20. package/dist/src/view/concatView.d.ts.map +1 -1
  21. package/dist/src/view/concatView.js +9 -2
  22. package/dist/src/view/containerMutationHelper.d.ts +6 -6
  23. package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
  24. package/dist/src/view/containerView.d.ts +7 -5
  25. package/dist/src/view/containerView.d.ts.map +1 -1
  26. package/dist/src/view/containerView.js +4 -1
  27. package/dist/src/view/facetView.d.ts +1 -1
  28. package/dist/src/view/flowBuilder.d.ts +1 -1
  29. package/dist/src/view/flowBuilder.d.ts.map +1 -1
  30. package/dist/src/view/gridView/gridChild.d.ts +3 -3
  31. package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
  32. package/dist/src/view/gridView/gridChild.js +0 -2
  33. package/dist/src/view/gridView/gridView.d.ts +13 -11
  34. package/dist/src/view/gridView/gridView.d.ts.map +1 -1
  35. package/dist/src/view/gridView/gridView.js +17 -26
  36. package/dist/src/view/gridView/keyboardZoomController.d.ts +21 -0
  37. package/dist/src/view/gridView/keyboardZoomController.d.ts.map +1 -0
  38. package/dist/src/view/gridView/keyboardZoomController.js +202 -0
  39. package/dist/src/view/gridView/scrollbar.d.ts +1 -1
  40. package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
  41. package/dist/src/view/gridView/scrollbar.js +0 -1
  42. package/dist/src/view/gridView/selectionRect.d.ts +1 -1
  43. package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
  44. package/dist/src/view/gridView/selectionRect.js +0 -1
  45. package/dist/src/view/gridView/separatorView.js +0 -1
  46. package/dist/src/view/gridView/zoomNavigationUtils.d.ts +19 -0
  47. package/dist/src/view/gridView/zoomNavigationUtils.d.ts.map +1 -0
  48. package/dist/src/view/gridView/zoomNavigationUtils.js +51 -0
  49. package/dist/src/view/layerView.d.ts +8 -5
  50. package/dist/src/view/layerView.d.ts.map +1 -1
  51. package/dist/src/view/layerView.js +6 -2
  52. package/dist/src/view/title.d.ts.map +1 -1
  53. package/dist/src/view/title.js +0 -1
  54. package/dist/src/view/unitView.d.ts +7 -4
  55. package/dist/src/view/unitView.d.ts.map +1 -1
  56. package/dist/src/view/unitView.js +5 -1
  57. package/dist/src/view/view.d.ts +13 -9
  58. package/dist/src/view/view.d.ts.map +1 -1
  59. package/dist/src/view/view.js +7 -1
  60. package/dist/src/view/viewError.d.ts +1 -1
  61. package/dist/src/view/viewError.d.ts.map +1 -1
  62. package/dist/src/view/viewFactory.d.ts +3 -44
  63. package/dist/src/view/viewFactory.d.ts.map +1 -1
  64. package/dist/src/view/viewFactory.js +28 -69
  65. package/dist/src/view/viewSelectors.d.ts.map +1 -1
  66. package/dist/src/view/viewSelectors.js +123 -160
  67. package/dist/src/view/viewSpecGuards.d.ts +43 -0
  68. package/dist/src/view/viewSpecGuards.d.ts.map +1 -0
  69. package/dist/src/view/viewSpecGuards.js +69 -0
  70. package/dist/src/view/viewUtils.d.ts +1 -1
  71. package/dist/src/view/viewUtils.d.ts.map +1 -1
  72. package/dist/src/view/zoom.d.ts +1 -0
  73. package/dist/src/view/zoom.d.ts.map +1 -1
  74. package/dist/src/view/zoom.js +5 -1
  75. package/package.json +3 -3
  76. package/dist/src/data/collector.test.d.ts +0 -2
  77. package/dist/src/data/collector.test.d.ts.map +0 -1
  78. package/dist/src/data/dataFlow.test.d.ts +0 -2
  79. package/dist/src/data/dataFlow.test.d.ts.map +0 -1
  80. package/dist/src/data/flow.test.d.ts +0 -2
  81. package/dist/src/data/flow.test.d.ts.map +0 -1
  82. package/dist/src/data/flowInit.test.d.ts +0 -2
  83. package/dist/src/data/flowInit.test.d.ts.map +0 -1
  84. package/dist/src/data/flowNode.test.d.ts +0 -2
  85. package/dist/src/data/flowNode.test.d.ts.map +0 -1
  86. package/dist/src/data/flowOptimizer.test.d.ts +0 -2
  87. package/dist/src/data/flowOptimizer.test.d.ts.map +0 -1
  88. package/dist/src/data/formats/fasta.test.d.ts +0 -2
  89. package/dist/src/data/formats/fasta.test.d.ts.map +0 -1
  90. package/dist/src/data/keyIndex.test.d.ts +0 -2
  91. package/dist/src/data/keyIndex.test.d.ts.map +0 -1
  92. package/dist/src/data/sources/inlineSource.test.d.ts +0 -2
  93. package/dist/src/data/sources/inlineSource.test.d.ts.map +0 -1
  94. package/dist/src/data/sources/sequenceSource.test.d.ts +0 -2
  95. package/dist/src/data/sources/sequenceSource.test.d.ts.map +0 -1
  96. package/dist/src/data/transforms/aggregate.test.d.ts +0 -2
  97. package/dist/src/data/transforms/aggregate.test.d.ts.map +0 -1
  98. package/dist/src/data/transforms/clone.test.d.ts +0 -2
  99. package/dist/src/data/transforms/clone.test.d.ts.map +0 -1
  100. package/dist/src/data/transforms/coverage.test.d.ts +0 -2
  101. package/dist/src/data/transforms/coverage.test.d.ts.map +0 -1
  102. package/dist/src/data/transforms/filter.test.d.ts +0 -2
  103. package/dist/src/data/transforms/filter.test.d.ts.map +0 -1
  104. package/dist/src/data/transforms/filterScoredLabels.test.d.ts +0 -2
  105. package/dist/src/data/transforms/filterScoredLabels.test.d.ts.map +0 -1
  106. package/dist/src/data/transforms/flatten.test.d.ts +0 -2
  107. package/dist/src/data/transforms/flatten.test.d.ts.map +0 -1
  108. package/dist/src/data/transforms/flattenDelimited.test.d.ts +0 -2
  109. package/dist/src/data/transforms/flattenDelimited.test.d.ts.map +0 -1
  110. package/dist/src/data/transforms/flattenSequence.test.d.ts +0 -2
  111. package/dist/src/data/transforms/flattenSequence.test.d.ts.map +0 -1
  112. package/dist/src/data/transforms/formula.test.d.ts +0 -2
  113. package/dist/src/data/transforms/formula.test.d.ts.map +0 -1
  114. package/dist/src/data/transforms/identifier.test.d.ts +0 -2
  115. package/dist/src/data/transforms/identifier.test.d.ts.map +0 -1
  116. package/dist/src/data/transforms/pileup.test.d.ts +0 -2
  117. package/dist/src/data/transforms/pileup.test.d.ts.map +0 -1
  118. package/dist/src/data/transforms/project.test.d.ts +0 -2
  119. package/dist/src/data/transforms/project.test.d.ts.map +0 -1
  120. package/dist/src/data/transforms/regexExtract.test.d.ts +0 -2
  121. package/dist/src/data/transforms/regexExtract.test.d.ts.map +0 -1
  122. package/dist/src/data/transforms/regexFold.test.d.ts +0 -2
  123. package/dist/src/data/transforms/regexFold.test.d.ts.map +0 -1
  124. package/dist/src/data/transforms/sample.test.d.ts +0 -2
  125. package/dist/src/data/transforms/sample.test.d.ts.map +0 -1
  126. package/dist/src/data/transforms/stack.test.d.ts +0 -2
  127. package/dist/src/data/transforms/stack.test.d.ts.map +0 -1
  128. package/dist/src/encoder/accessor.test.d.ts +0 -2
  129. package/dist/src/encoder/accessor.test.d.ts.map +0 -1
  130. package/dist/src/encoder/encoder.test.d.ts +0 -2
  131. package/dist/src/encoder/encoder.test.d.ts.map +0 -1
  132. package/dist/src/encoder/metadataChannels.test.d.ts +0 -2
  133. package/dist/src/encoder/metadataChannels.test.d.ts.map +0 -1
  134. package/dist/src/genome/genome.test.d.ts +0 -2
  135. package/dist/src/genome/genome.test.d.ts.map +0 -1
  136. package/dist/src/genome/genomes.test.d.ts +0 -2
  137. package/dist/src/genome/genomes.test.d.ts.map +0 -1
  138. package/dist/src/genome/scaleIndex.test.d.ts +0 -2
  139. package/dist/src/genome/scaleIndex.test.d.ts.map +0 -1
  140. package/dist/src/genome/scaleLocus.test.d.ts +0 -2
  141. package/dist/src/genome/scaleLocus.test.d.ts.map +0 -1
  142. package/dist/src/genomeSpy/viewDataInit.test.d.ts +0 -2
  143. package/dist/src/genomeSpy/viewDataInit.test.d.ts.map +0 -1
  144. package/dist/src/gl/colorUtils.test.d.ts +0 -2
  145. package/dist/src/gl/colorUtils.test.d.ts.map +0 -1
  146. package/dist/src/paramRuntime/expressionRef.test.d.ts +0 -2
  147. package/dist/src/paramRuntime/expressionRef.test.d.ts.map +0 -1
  148. package/dist/src/paramRuntime/graphRuntime.test.d.ts +0 -2
  149. package/dist/src/paramRuntime/graphRuntime.test.d.ts.map +0 -1
  150. package/dist/src/paramRuntime/paramRuntime.test.d.ts +0 -2
  151. package/dist/src/paramRuntime/paramRuntime.test.d.ts.map +0 -1
  152. package/dist/src/paramRuntime/paramStore.test.d.ts +0 -2
  153. package/dist/src/paramRuntime/paramStore.test.d.ts.map +0 -1
  154. package/dist/src/scale/scale.test.d.ts +0 -2
  155. package/dist/src/scale/scale.test.d.ts.map +0 -1
  156. package/dist/src/scale/ticks.test.d.ts +0 -2
  157. package/dist/src/scale/ticks.test.d.ts.map +0 -1
  158. package/dist/src/scales/axisResolution.test.d.ts +0 -2
  159. package/dist/src/scales/axisResolution.test.d.ts.map +0 -1
  160. package/dist/src/scales/domainPlanner.test.d.ts +0 -2
  161. package/dist/src/scales/domainPlanner.test.d.ts.map +0 -1
  162. package/dist/src/scales/scaleInstanceManager.test.d.ts +0 -2
  163. package/dist/src/scales/scaleInstanceManager.test.d.ts.map +0 -1
  164. package/dist/src/scales/scaleInteractionController.test.d.ts +0 -2
  165. package/dist/src/scales/scaleInteractionController.test.d.ts.map +0 -1
  166. package/dist/src/scales/scaleResolution.test.d.ts +0 -2
  167. package/dist/src/scales/scaleResolution.test.d.ts.map +0 -1
  168. package/dist/src/scales/scaleRules.test.d.ts +0 -2
  169. package/dist/src/scales/scaleRules.test.d.ts.map +0 -1
  170. package/dist/src/selection/selection.test.d.ts +0 -2
  171. package/dist/src/selection/selection.test.d.ts.map +0 -1
  172. package/dist/src/tooltip/dataTooltipHandler.test.d.ts +0 -2
  173. package/dist/src/tooltip/dataTooltipHandler.test.d.ts.map +0 -1
  174. package/dist/src/tooltip/flattenDatumRows.test.d.ts +0 -2
  175. package/dist/src/tooltip/flattenDatumRows.test.d.ts.map +0 -1
  176. package/dist/src/tooltip/tooltipContext.test.d.ts +0 -2
  177. package/dist/src/tooltip/tooltipContext.test.d.ts.map +0 -1
  178. package/dist/src/utils/addBaseUrl.test.d.ts +0 -2
  179. package/dist/src/utils/addBaseUrl.test.d.ts.map +0 -1
  180. package/dist/src/utils/binnedIndex.test.d.ts +0 -2
  181. package/dist/src/utils/binnedIndex.test.d.ts.map +0 -1
  182. package/dist/src/utils/cloner.test.d.ts +0 -2
  183. package/dist/src/utils/cloner.test.d.ts.map +0 -1
  184. package/dist/src/utils/coalesce.test.d.ts +0 -2
  185. package/dist/src/utils/coalesce.test.d.ts.map +0 -1
  186. package/dist/src/utils/concatIterables.test.d.ts +0 -2
  187. package/dist/src/utils/concatIterables.test.d.ts.map +0 -1
  188. package/dist/src/utils/deepEqual.test.d.ts +0 -2
  189. package/dist/src/utils/deepEqual.test.d.ts.map +0 -1
  190. package/dist/src/utils/domainArray.test.d.ts +0 -2
  191. package/dist/src/utils/domainArray.test.d.ts.map +0 -1
  192. package/dist/src/utils/fetchUtils.test.d.ts +0 -2
  193. package/dist/src/utils/fetchUtils.test.d.ts.map +0 -1
  194. package/dist/src/utils/indexer.test.d.ts +0 -2
  195. package/dist/src/utils/indexer.test.d.ts.map +0 -1
  196. package/dist/src/utils/interactionEvent.test.d.ts +0 -2
  197. package/dist/src/utils/interactionEvent.test.d.ts.map +0 -1
  198. package/dist/src/utils/iterateNestedMaps.test.d.ts +0 -2
  199. package/dist/src/utils/iterateNestedMaps.test.d.ts.map +0 -1
  200. package/dist/src/utils/kWayMerge.test.d.ts +0 -2
  201. package/dist/src/utils/kWayMerge.test.d.ts.map +0 -1
  202. package/dist/src/utils/mergeObjects.test.d.ts +0 -2
  203. package/dist/src/utils/mergeObjects.test.d.ts.map +0 -1
  204. package/dist/src/utils/numberExtractor.test.d.ts +0 -2
  205. package/dist/src/utils/numberExtractor.test.d.ts.map +0 -1
  206. package/dist/src/utils/propertyCacher.test.d.ts +0 -2
  207. package/dist/src/utils/propertyCacher.test.d.ts.map +0 -1
  208. package/dist/src/utils/propertyCoalescer.test.d.ts +0 -2
  209. package/dist/src/utils/propertyCoalescer.test.d.ts.map +0 -1
  210. package/dist/src/utils/radixSort.test.d.ts +0 -2
  211. package/dist/src/utils/radixSort.test.d.ts.map +0 -1
  212. package/dist/src/utils/reservationMap.test.d.ts +0 -2
  213. package/dist/src/utils/reservationMap.test.d.ts.map +0 -1
  214. package/dist/src/utils/ringBuffer.test.d.ts +0 -2
  215. package/dist/src/utils/ringBuffer.test.d.ts.map +0 -1
  216. package/dist/src/utils/throttle.test.d.ts +0 -2
  217. package/dist/src/utils/throttle.test.d.ts.map +0 -1
  218. package/dist/src/utils/topK.test.d.ts +0 -2
  219. package/dist/src/utils/topK.test.d.ts.map +0 -1
  220. package/dist/src/utils/trees.test.d.ts +0 -2
  221. package/dist/src/utils/trees.test.d.ts.map +0 -1
  222. package/dist/src/utils/ui/tooltip.test.d.ts +0 -2
  223. package/dist/src/utils/ui/tooltip.test.d.ts.map +0 -1
  224. package/dist/src/utils/url.test.d.ts +0 -2
  225. package/dist/src/utils/url.test.d.ts.map +0 -1
  226. package/dist/src/utils/variableTools.test.d.ts +0 -2
  227. package/dist/src/utils/variableTools.test.d.ts.map +0 -1
  228. package/dist/src/view/concatView.test.d.ts +0 -2
  229. package/dist/src/view/concatView.test.d.ts.map +0 -1
  230. package/dist/src/view/dataReadiness.test.d.ts +0 -2
  231. package/dist/src/view/dataReadiness.test.d.ts.map +0 -1
  232. package/dist/src/view/flowBuilder.test.d.ts +0 -2
  233. package/dist/src/view/flowBuilder.test.d.ts.map +0 -1
  234. package/dist/src/view/gridView/gridView.test.d.ts +0 -2
  235. package/dist/src/view/gridView/gridView.test.d.ts.map +0 -1
  236. package/dist/src/view/gridView/selectionRect.test.d.ts +0 -2
  237. package/dist/src/view/gridView/selectionRect.test.d.ts.map +0 -1
  238. package/dist/src/view/layerView.test.d.ts +0 -2
  239. package/dist/src/view/layerView.test.d.ts.map +0 -1
  240. package/dist/src/view/layout/flexLayout.test.d.ts +0 -2
  241. package/dist/src/view/layout/flexLayout.test.d.ts.map +0 -1
  242. package/dist/src/view/layout/grid.test.d.ts +0 -2
  243. package/dist/src/view/layout/grid.test.d.ts.map +0 -1
  244. package/dist/src/view/layout/rectangle.test.d.ts +0 -2
  245. package/dist/src/view/layout/rectangle.test.d.ts.map +0 -1
  246. package/dist/src/view/multiscale.test.d.ts +0 -2
  247. package/dist/src/view/multiscale.test.d.ts.map +0 -1
  248. package/dist/src/view/view.test.d.ts +0 -2
  249. package/dist/src/view/view.test.d.ts.map +0 -1
  250. package/dist/src/view/viewDispose.test.d.ts +0 -2
  251. package/dist/src/view/viewDispose.test.d.ts.map +0 -1
  252. package/dist/src/view/viewFactory.test.d.ts +0 -2
  253. package/dist/src/view/viewFactory.test.d.ts.map +0 -1
  254. package/dist/src/view/viewParamRuntime.test.d.ts +0 -2
  255. package/dist/src/view/viewParamRuntime.test.d.ts.map +0 -1
  256. package/dist/src/view/viewSelectors.test.d.ts +0 -2
  257. package/dist/src/view/viewSelectors.test.d.ts.map +0 -1
  258. package/dist/src/view/viewUtils.test.d.ts +0 -2
  259. package/dist/src/view/viewUtils.test.d.ts.map +0 -1
@@ -16,7 +16,9 @@ import LayerView from "../layerView.js";
16
16
  import UnitView from "../unitView.js";
17
17
  import { interactionToZoom } from "../zoom.js";
18
18
  import GridChild from "./gridChild.js";
19
+ import KeyboardZoomController from "./keyboardZoomController.js";
19
20
  import SeparatorView, { resolveSeparatorProps } from "./separatorView.js";
21
+ import { getZoomableResolutions } from "./zoomNavigationUtils.js";
20
22
 
21
23
  /**
22
24
  * Modeled after: https://vega.github.io/vega/docs/layout/
@@ -33,6 +35,9 @@ import SeparatorView, { resolveSeparatorProps } from "./separatorView.js";
33
35
  * - Zoom / pan
34
36
  * - Scrollable viewports (with scrollbars)
35
37
  * - And later on, brushing, legend(?)
38
+ *
39
+ * @template {import("../../spec/view.js").AnyConcatSpec} [TSpec=import("../../spec/view.js").AnyConcatSpec]
40
+ * @extends {ContainerView<TSpec>}
36
41
  */
37
42
  export default class GridView extends ContainerView {
38
43
  /**
@@ -73,9 +78,12 @@ export default class GridView extends ContainerView {
73
78
  /** @type {Partial<Record<"horizontal" | "vertical", SeparatorView>>} */
74
79
  #separatorViews = {};
75
80
 
81
+ /** @type {KeyboardZoomController | null} */
82
+ #keyboardZoomController = null;
83
+
76
84
  /**
77
85
  *
78
- * @param {import("../../spec/view.js").AnyConcatSpec} spec
86
+ * @param {TSpec} spec
79
87
  * @param {import("../../types/viewContext.js").default} context
80
88
  * @param {ContainerView} layoutParent
81
89
  * @param {View} dataParent
@@ -115,6 +123,13 @@ export default class GridView extends ContainerView {
115
123
  });
116
124
  }
117
125
  }
126
+
127
+ if (!this.layoutParent) {
128
+ this.#keyboardZoomController = new KeyboardZoomController({
129
+ context: this.context,
130
+ viewRoot: this,
131
+ });
132
+ }
118
133
  }
119
134
 
120
135
  /**
@@ -856,6 +871,7 @@ export default class GridView extends ContainerView {
856
871
  const pointedChild = this.#visibleChildren.find((gridChild) =>
857
872
  gridChild.coords.containsPoint(event.point.x, event.point.y)
858
873
  );
874
+ this.#keyboardZoomController?.handlePointerEvent(pointedChild, event);
859
875
 
860
876
  for (const scrollbar of Object.values(pointedChild?.scrollbars ?? {})) {
861
877
  if (scrollbar.coords.containsPoint(event.point.x, event.point.y)) {
@@ -949,31 +965,6 @@ export default class GridView extends ContainerView {
949
965
  }
950
966
  }
951
967
 
952
- /**
953
- *
954
- * @param {View} view
955
- * @returns
956
- */
957
- function getZoomableResolutions(view) {
958
- /** @type {Record<import("../../spec/channel.js").PrimaryPositionalChannel, Set<import("../../scales/scaleResolution.js").default>>} */
959
- const resolutions = {
960
- x: new Set(),
961
- y: new Set(),
962
- };
963
-
964
- // Find all resolutions (scales) that are candidates for zooming
965
- view.visit((v) => {
966
- for (const [channel, resolutionSet] of Object.entries(resolutions)) {
967
- const resolution = v.getScaleResolution(channel);
968
- if (resolution && resolution.isZoomable()) {
969
- resolutionSet.add(resolution);
970
- }
971
- }
972
- });
973
-
974
- return resolutions;
975
- }
976
-
977
968
  /**
978
969
  * @param {View} view
979
970
  */
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Handles WASD keyboard navigation for the root grid view.
3
+ */
4
+ export default class KeyboardZoomController {
5
+ /**
6
+ * @param {object} params
7
+ * @param {import("../../types/viewContext.js").default} params.context
8
+ * @param {import("../view.js").default} params.viewRoot
9
+ */
10
+ constructor({ context, viewRoot }: {
11
+ context: import("../../types/viewContext.js").default;
12
+ viewRoot: import("../view.js").default;
13
+ });
14
+ /**
15
+ * @param {import("./gridChild.js").default | undefined} pointedChild
16
+ * @param {import("../../utils/interactionEvent.js").default} event
17
+ */
18
+ handlePointerEvent(pointedChild: import("./gridChild.js").default | undefined, event: import("../../utils/interactionEvent.js").default): void;
19
+ #private;
20
+ }
21
+ //# sourceMappingURL=keyboardZoomController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboardZoomController.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/keyboardZoomController.js"],"names":[],"mappings":"AAIA;;GAEG;AACH;IAuDI;;;;OAIG;IACH,mCAHG;QAA6D,OAAO,EAA5D,OAAO,4BAA4B,EAAE,OAAO;QACP,QAAQ,EAA7C,OAAO,YAAY,EAAE,OAAO;KACtC,EAKA;IAED;;;OAGG;IACH,iCAHW,OAAO,gBAAgB,EAAE,OAAO,GAAG,SAAS,SAC5C,OAAO,iCAAiC,EAAE,OAAO,QA0B3D;;CA4DJ"}
@@ -0,0 +1,202 @@
1
+ import KeyboardZoomMotion from "../../utils/keyboardZoomMotion.js";
2
+ import { markZoomActivity } from "../zoom.js";
3
+ import { getKeyboardZoomTarget } from "./zoomNavigationUtils.js";
4
+
5
+ /**
6
+ * Handles WASD keyboard navigation for the root grid view.
7
+ */
8
+ export default class KeyboardZoomController {
9
+ /** @type {import("../../types/viewContext.js").default} */
10
+ #context;
11
+
12
+ /** @type {import("../view.js").default} */
13
+ #viewRoot;
14
+
15
+ #zoomAnchorX = 0.5;
16
+
17
+ #keyboardZoomMotion = new KeyboardZoomMotion();
18
+
19
+ #keyboardNavigationActive = false;
20
+
21
+ #keyboardNavigationTimestamp = 0;
22
+
23
+ #keyboardNavigationStep = (/** @type {number} */ timestamp) => {
24
+ if (!this.#keyboardNavigationActive) {
25
+ return;
26
+ }
27
+
28
+ const resolution = getKeyboardZoomTarget(this.#viewRoot);
29
+ if (!resolution) {
30
+ this.#keyboardZoomMotion.reset();
31
+ this.#keyboardNavigationActive = false;
32
+ this.#keyboardNavigationTimestamp = 0;
33
+ return;
34
+ }
35
+
36
+ const dtMs = Math.max(0, timestamp - this.#keyboardNavigationTimestamp);
37
+ this.#keyboardNavigationTimestamp = timestamp;
38
+
39
+ const motion = this.#keyboardZoomMotion.step(dtMs);
40
+
41
+ if (motion.panDelta !== 0 || motion.zoomDelta !== 0) {
42
+ const changed = resolution.zoom(
43
+ 2 ** motion.zoomDelta,
44
+ this.#zoomAnchorX,
45
+ motion.panDelta
46
+ );
47
+ if (changed) {
48
+ markZoomActivity();
49
+ this.#context.animator.requestRender();
50
+ }
51
+ }
52
+
53
+ if (motion.active) {
54
+ this.#context.animator.requestTransition(
55
+ this.#keyboardNavigationStep
56
+ );
57
+ } else {
58
+ this.#keyboardNavigationActive = false;
59
+ this.#keyboardNavigationTimestamp = 0;
60
+ }
61
+ };
62
+
63
+ /**
64
+ * @param {object} params
65
+ * @param {import("../../types/viewContext.js").default} params.context
66
+ * @param {import("../view.js").default} params.viewRoot
67
+ */
68
+ constructor({ context, viewRoot }) {
69
+ this.#context = context;
70
+ this.#viewRoot = viewRoot;
71
+ this.#setupKeyboardNavigation();
72
+ }
73
+
74
+ /**
75
+ * @param {import("./gridChild.js").default | undefined} pointedChild
76
+ * @param {import("../../utils/interactionEvent.js").default} event
77
+ */
78
+ handlePointerEvent(pointedChild, event) {
79
+ if (!pointedChild) {
80
+ return;
81
+ } else {
82
+ const viewWithAnchor =
83
+ /** @type {{getKeyboardZoomAnchorX?: (point: {x: number, y: number}) => number | undefined}} */ (
84
+ pointedChild.view
85
+ );
86
+
87
+ if (typeof viewWithAnchor.getKeyboardZoomAnchorX === "function") {
88
+ const anchor = viewWithAnchor.getKeyboardZoomAnchorX(
89
+ event.point
90
+ );
91
+ if (Number.isFinite(anchor)) {
92
+ this.#zoomAnchorX = Math.max(0, Math.min(1, anchor));
93
+ }
94
+ } else {
95
+ const normalizedPoint = pointedChild.coords.normalizePoint(
96
+ event.point.x,
97
+ event.point.y
98
+ );
99
+ this.#zoomAnchorX = normalizedPoint.x;
100
+ }
101
+ }
102
+ }
103
+
104
+ #setupKeyboardNavigation() {
105
+ const addKeyboardListener = this.#context.addKeyboardListener;
106
+ if (typeof addKeyboardListener !== "function") {
107
+ return;
108
+ }
109
+
110
+ addKeyboardListener("keydown", (event) => {
111
+ if (shouldIgnoreKeyboardNavigation(event)) {
112
+ return;
113
+ }
114
+
115
+ if (!this.#keyboardZoomMotion.isNavigationKey(event.code)) {
116
+ return;
117
+ }
118
+
119
+ const resolution = getKeyboardZoomTarget(this.#viewRoot);
120
+ if (!resolution) {
121
+ return;
122
+ }
123
+
124
+ const changed = this.#keyboardZoomMotion.handleKeyDown(event.code);
125
+ if (!changed) {
126
+ return;
127
+ }
128
+
129
+ event.preventDefault();
130
+ this.#activateKeyboardNavigation();
131
+ });
132
+
133
+ addKeyboardListener("keyup", (event) => {
134
+ if (!this.#keyboardZoomMotion.isNavigationKey(event.code)) {
135
+ return;
136
+ }
137
+
138
+ const changed = this.#keyboardZoomMotion.handleKeyUp(event.code);
139
+ if (!changed) {
140
+ return;
141
+ }
142
+
143
+ const resolution = getKeyboardZoomTarget(this.#viewRoot);
144
+ if (!resolution) {
145
+ return;
146
+ }
147
+
148
+ event.preventDefault();
149
+ this.#activateKeyboardNavigation();
150
+ });
151
+ }
152
+
153
+ #activateKeyboardNavigation() {
154
+ if (this.#keyboardNavigationActive) {
155
+ return;
156
+ }
157
+
158
+ this.#keyboardNavigationActive = true;
159
+ this.#keyboardNavigationTimestamp = performance.now();
160
+ this.#context.animator.requestTransition(this.#keyboardNavigationStep);
161
+ }
162
+ }
163
+
164
+ /**
165
+ * @param {KeyboardEvent} event
166
+ */
167
+ function shouldIgnoreKeyboardNavigation(event) {
168
+ if (event.altKey || event.ctrlKey || event.metaKey) {
169
+ return true;
170
+ }
171
+
172
+ if (isEditableTarget(event.target)) {
173
+ return true;
174
+ }
175
+
176
+ return false;
177
+ }
178
+
179
+ /**
180
+ * @param {EventTarget | null} target
181
+ */
182
+ function isEditableTarget(target) {
183
+ if (!target || typeof target !== "object") {
184
+ return false;
185
+ }
186
+
187
+ const candidate =
188
+ /** @type {{isContentEditable?: boolean, nodeName?: string}} */ (
189
+ target
190
+ );
191
+
192
+ if (candidate.isContentEditable) {
193
+ return true;
194
+ }
195
+
196
+ if (typeof candidate.nodeName === "string") {
197
+ const name = candidate.nodeName.toLowerCase();
198
+ return name === "input" || name === "textarea" || name === "select";
199
+ }
200
+
201
+ return false;
202
+ }
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * @typedef {"horizontal" | "vertical"} ScrollDirection
6
6
  */
7
- export default class Scrollbar extends UnitView {
7
+ export default class Scrollbar extends UnitView<import("../../spec/view.js").UnitSpec> {
8
8
  /**
9
9
  * @param {import("./gridChild.js").default} gridChild
10
10
  * @param {ScrollDirection} scrollDirection
@@ -1 +1 @@
1
- {"version":3,"file":"scrollbar.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/scrollbar.js"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH;IAwBI;;;;OAIG;IACH,uBAJW,OAAO,gBAAgB,EAAE,OAAO,mBAChC,eAAe,YACf;QAAE,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,EA0H/D;IAzID;;;;;;OAMG;IACH,uBAAmB;IAmDf;;;;MAAoB;IAiFxB,2BAEC;IAED;;;OAGG;IACH,yBAHW,MAAM,6BACN;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,QAYtD;IAqFD;;;;;;;;;OASG;IACH,gCAHW,SAAS,iBACT,SAAS,QASnB;IAMG;;;;MAWC;;CAER;;;;;8BApSY,YAAY,GAAG,UAAU;qBAPjB,gBAAgB;sBADf,wBAAwB"}
1
+ {"version":3,"file":"scrollbar.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/scrollbar.js"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH;IAwBI;;;;OAIG;IACH,uBAJW,OAAO,gBAAgB,EAAE,OAAO,mBAChC,eAAe,YACf;QAAE,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,EAyH/D;IAxID;;;;;;OAMG;IACH,uBAAmB;IAkDf;;;;MAAoB;IAiFxB,2BAEC;IAED;;;OAGG;IACH,yBAHW,MAAM,6BACN;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,QAYtD;IAqFD;;;;;;;;;OASG;IACH,gCAHW,SAAS,iBACT,SAAS,QASnB;IAMG;;;;MAWC;;CAER;;;;;8BAnSY,YAAY,GAAG,UAAU;qBAPjB,gBAAgB;sBADf,wBAAwB"}
@@ -67,7 +67,6 @@ export default class Scrollbar extends UnitView {
67
67
  cornerRadius: 5,
68
68
  clip: false,
69
69
  },
70
- configurableVisibility: false,
71
70
  },
72
71
  gridChild.layoutParent.context,
73
72
  gridChild.layoutParent,
@@ -1,4 +1,4 @@
1
- export default class SelectionRect extends LayerView {
1
+ export default class SelectionRect extends LayerView<import("../../spec/view.js").LayerSpec> {
2
2
  /**
3
3
  * @typedef {import("../../spec/channel.js").PrimaryPositionalChannel} PrimaryPositionalChannel
4
4
  * @typedef {import("../../types/selectionTypes.js").IntervalSelection} IntervalSelection
@@ -1 +1 @@
1
- {"version":3,"file":"selectionRect.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/selectionRect.js"],"names":[],"mappings":"AAIA;IACI;;;OAGG;IAEH;;;;OAIG;IACH,uBAJW,OAAO,gBAAgB,EAAE,OAAO,iBAChC,OAAO,6BAA6B,EAAE,eAAe,gBACrD,OAAO,yBAAyB,EAAE,WAAW,EAgKvD;CACJ;sBA7KqB,iBAAiB"}
1
+ {"version":3,"file":"selectionRect.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/selectionRect.js"],"names":[],"mappings":"AAIA;IACI;;;OAGG;IAEH;;;;OAIG;IACH,uBAJW,OAAO,gBAAgB,EAAE,OAAO,iBAChC,OAAO,6BAA6B,EAAE,eAAe,gBACrD,OAAO,yBAAyB,EAAE,WAAW,EA+JvD;CACJ;sBA5KqB,iBAAiB"}
@@ -28,7 +28,6 @@ export default class SelectionRect extends LayerView {
28
28
  /** @type {import("../../spec/view.js").LayerSpec} */
29
29
  const layerSpec = {
30
30
  name: "selectionRect",
31
- configurableVisibility: false,
32
31
  domainInert: true,
33
32
  resolve: {
34
33
  scale: {
@@ -244,7 +244,6 @@ export function resolveSeparatorProps(separator) {
244
244
  */
245
245
  function createSeparatorSpec(props) {
246
246
  return {
247
- configurableVisibility: false,
248
247
  domainInert: true,
249
248
  data: { values: [] },
250
249
  resolve: {
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @typedef {import("../view.js").default} View
3
+ */
4
+ /**
5
+ * Finds all zoomable positional resolutions in a subtree.
6
+ *
7
+ * @param {View} view
8
+ * @returns {Record<import("../../spec/channel.js").PrimaryPositionalChannel, Set<import("../../scales/scaleResolution.js").default>>}
9
+ */
10
+ export function getZoomableResolutions(view: View): Record<import("../../spec/channel.js").PrimaryPositionalChannel, Set<import("../../scales/scaleResolution.js").default>>;
11
+ /**
12
+ * Returns the keyboard zoom target when exactly one zoomable x-resolution is
13
+ * present in the hierarchy and it is resolved to the root view.
14
+ *
15
+ * @param {View} viewRoot
16
+ */
17
+ export function getKeyboardZoomTarget(viewRoot: View): any;
18
+ export type View = import("../view.js").default;
19
+ //# sourceMappingURL=zoomNavigationUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zoomNavigationUtils.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/zoomNavigationUtils.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,6CAHW,IAAI,GACF,MAAM,CAAC,OAAO,uBAAuB,EAAE,wBAAwB,EAAE,GAAG,CAAC,OAAO,iCAAiC,EAAE,OAAO,CAAC,CAAC,CAoBpI;AAED;;;;;GAKG;AACH,gDAFW,IAAI,OAgBd;mBAjDY,OAAO,YAAY,EAAE,OAAO"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @typedef {import("../view.js").default} View
3
+ */
4
+
5
+ /**
6
+ * Finds all zoomable positional resolutions in a subtree.
7
+ *
8
+ * @param {View} view
9
+ * @returns {Record<import("../../spec/channel.js").PrimaryPositionalChannel, Set<import("../../scales/scaleResolution.js").default>>}
10
+ */
11
+ export function getZoomableResolutions(view) {
12
+ /** @type {Record<import("../../spec/channel.js").PrimaryPositionalChannel, Set<import("../../scales/scaleResolution.js").default>>} */
13
+ const resolutions = {
14
+ x: new Set(),
15
+ y: new Set(),
16
+ };
17
+
18
+ // Find all resolutions (scales) that are candidates for zooming
19
+ view.visit((v) => {
20
+ for (const [channel, resolutionSet] of Object.entries(resolutions)) {
21
+ const resolution = v.getScaleResolution(channel);
22
+ if (resolution && resolution.isZoomable()) {
23
+ resolutionSet.add(resolution);
24
+ }
25
+ }
26
+ });
27
+
28
+ return resolutions;
29
+ }
30
+
31
+ /**
32
+ * Returns the keyboard zoom target when exactly one zoomable x-resolution is
33
+ * present in the hierarchy and it is resolved to the root view.
34
+ *
35
+ * @param {View} viewRoot
36
+ */
37
+ export function getKeyboardZoomTarget(viewRoot) {
38
+ const xResolutions = getZoomableResolutions(viewRoot).x;
39
+ if (xResolutions.size !== 1) {
40
+ return;
41
+ } else {
42
+ const target = xResolutions.values().next().value;
43
+ const rootXResolution = viewRoot.getScaleResolution("x");
44
+
45
+ if (!rootXResolution || rootXResolution !== target) {
46
+ return;
47
+ } else {
48
+ return target;
49
+ }
50
+ }
51
+ }
@@ -1,15 +1,18 @@
1
- export default class LayerView extends ContainerView {
1
+ /**
2
+ * @template {import("../spec/view.js").LayerSpec} [TSpec=import("../spec/view.js").LayerSpec]
3
+ * @extends {ContainerView<TSpec>}
4
+ */
5
+ export default class LayerView<TSpec extends import("../spec/view.js").LayerSpec = import("../spec/view.js").LayerSpec> extends ContainerView<TSpec> {
2
6
  /**
3
7
  *
4
- * @param {import("../spec/view.js").LayerSpec} spec
8
+ * @param {TSpec} spec
5
9
  * @param {import("../types/viewContext.js").default} context
6
10
  * @param {ContainerView} layoutParent
7
11
  * @param {import("./view.js").default} dataParent
8
12
  * @param {string} name
9
13
  * @param {import("./view.js").ViewOptions} [options]
10
14
  */
11
- constructor(spec: import("../spec/view.js").LayerSpec, context: import("../types/viewContext.js").default, layoutParent: ContainerView, dataParent: import("./view.js").default, name: string, options?: import("./view.js").ViewOptions);
12
- spec: import("../spec/view.js").LayerSpec;
15
+ constructor(spec: TSpec, context: import("../types/viewContext.js").default, layoutParent: ContainerView, dataParent: import("./view.js").default, name: string, options?: import("./view.js").ViewOptions);
13
16
  /**
14
17
  * Adds a child spec dynamically. Intended for post-initialization updates.
15
18
  *
@@ -24,7 +27,7 @@ export default class LayerView extends ContainerView {
24
27
  * @param {number} index
25
28
  */
26
29
  removeChildAt(index: number): Promise<void>;
27
- get children(): (import("./unitView.js").default | LayerView)[];
30
+ get children(): (import("./unitView.js").default<import("../spec/view.js").UnitSpec> | LayerView<import("../spec/view.js").LayerSpec>)[];
28
31
  #private;
29
32
  }
30
33
  import ContainerView from "./containerView.js";
@@ -1 +1 @@
1
- {"version":3,"file":"layerView.d.ts","sourceRoot":"","sources":["../../../src/view/layerView.js"],"names":[],"mappings":"AAMA;IAQI;;;;;;;;OAQG;IACH,kBAPW,OAAO,iBAAiB,EAAE,SAAS,WACnC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,aAAa,cACb,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAWzC;IAHG,0CAAgB;IAqCpB;;;;;;OAMG;IACH,wBAJW,OAAO,iBAAiB,EAAE,SAAS,GAAG,OAAO,iBAAiB,EAAE,QAAQ,GAAG,OAAO,iBAAiB,EAAE,UAAU,UAC/G,MAAM,GACJ,OAAO,CAAC,SAAS,GAAG,OAAO,eAAe,EAAE,OAAO,CAAC,CAMhE;IAED;;;;OAIG;IACH,qBAFW,MAAM,iBAIhB;IA6CD,gEAEC;;CA6CJ;0BAjLyB,oBAAoB"}
1
+ {"version":3,"file":"layerView.d.ts","sourceRoot":"","sources":["../../../src/view/layerView.js"],"names":[],"mappings":"AAMA;;;GAGG;AACH,+BAHoD,KAAK,SAA5C,OAAQ,iBAAiB,EAAE,SAAU;IAW9C;;;;;;;;OAQG;IACH,kBAPW,KAAK,WACL,OAAO,yBAAyB,EAAE,OAAO,gBACzC,aAAa,cACb,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAWzC;IAkCD;;;;;;OAMG;IACH,wBAJW,OAAO,iBAAiB,EAAE,SAAS,GAAG,OAAO,iBAAiB,EAAE,QAAQ,GAAG,OAAO,iBAAiB,EAAE,UAAU,UAC/G,MAAM,GACJ,OAAO,CAAC,SAAS,GAAG,OAAO,eAAe,EAAE,OAAO,CAAC,CAMhE;IAED;;;;OAIG;IACH,qBAFW,MAAM,iBAIhB;IA6CD,yIAEC;;CA6CJ;0BAtLyB,oBAAoB"}
@@ -1,9 +1,13 @@
1
- import { isLayerSpec, isUnitSpec } from "./viewFactory.js";
2
1
  import ContainerView from "./containerView.js";
3
2
  import ViewError from "./viewError.js";
4
3
  import ContainerMutationHelper from "./containerMutationHelper.js";
5
4
  import { isMultiscaleSpec } from "./multiscale.js";
5
+ import { isLayerSpec, isUnitSpec } from "./viewSpecGuards.js";
6
6
 
7
+ /**
8
+ * @template {import("../spec/view.js").LayerSpec} [TSpec=import("../spec/view.js").LayerSpec]
9
+ * @extends {ContainerView<TSpec>}
10
+ */
7
11
  export default class LayerView extends ContainerView {
8
12
  /**
9
13
  * @typedef {import("./view.js").default} View
@@ -14,7 +18,7 @@ export default class LayerView extends ContainerView {
14
18
 
15
19
  /**
16
20
  *
17
- * @param {import("../spec/view.js").LayerSpec} spec
21
+ * @param {TSpec} spec
18
22
  * @param {import("../types/viewContext.js").default} context
19
23
  * @param {ContainerView} layoutParent
20
24
  * @param {import("./view.js").default} dataParent
@@ -1 +1 @@
1
- {"version":3,"file":"title.d.ts","sourceRoot":"","sources":["../../../src/view/title.js"],"names":[],"mappings":"AAuDA;;;GAGG;AACH,2CAHW,MAAM,GAAG,OAAO,kBAAkB,EAAE,KAAK,GACvC,OAAO,iBAAiB,EAAE,QAAQ,CA2G9C"}
1
+ {"version":3,"file":"title.d.ts","sourceRoot":"","sources":["../../../src/view/title.js"],"names":[],"mappings":"AAuDA;;;GAGG;AACH,2CAHW,MAAM,GAAG,OAAO,kBAAkB,EAAE,KAAK,GACvC,OAAO,iBAAiB,EAAE,QAAQ,CA0G9C"}
@@ -138,7 +138,6 @@ export default function createTitle(title) {
138
138
  }
139
139
 
140
140
  return {
141
- configurableVisibility: false,
142
141
  data: { values: [{}] },
143
142
  mark: {
144
143
  type: "text",
@@ -4,18 +4,21 @@
4
4
  * TODO: Find a proper place, make extendible
5
5
  */
6
6
  export const markTypes: Record<import("../spec/mark.js").MarkType, typeof import("../marks/mark.js").default>;
7
- export default class UnitView extends View {
7
+ /**
8
+ * @template {import("../spec/view.js").UnitSpec} [TSpec=import("../spec/view.js").UnitSpec]
9
+ * @extends {View<TSpec>}
10
+ */
11
+ export default class UnitView<TSpec extends import("../spec/view.js").UnitSpec = import("../spec/view.js").UnitSpec> extends View<TSpec> {
8
12
  /**
9
13
  *
10
- * @param {import("../spec/view.js").UnitSpec} spec
14
+ * @param {TSpec} spec
11
15
  * @param {import("../types/viewContext.js").default} context
12
16
  * @param {import("./containerView.js").default} layoutParent
13
17
  * @param {import("./view.js").default} dataParent
14
18
  * @param {string} name
15
19
  * @param {import("./view.js").ViewOptions} [options]
16
20
  */
17
- constructor(spec: import("../spec/view.js").UnitSpec, context: import("../types/viewContext.js").default, layoutParent: import("./containerView.js").default, dataParent: import("./view.js").default, name: string, options?: import("./view.js").ViewOptions);
18
- spec: import("../spec/view.js").UnitSpec;
21
+ constructor(spec: TSpec, context: import("../types/viewContext.js").default, layoutParent: import("./containerView.js").default, dataParent: import("./view.js").default, name: string, options?: import("./view.js").ViewOptions);
19
22
  /** @type {import("../marks/mark.js").default} */
20
23
  mark: import("../marks/mark.js").default;
21
24
  getMarkType(): "link" | "rect" | "text" | "point" | "rule";
@@ -1 +1 @@
1
- {"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AA+BA;;;;GAIG;AACH,wBAHU,MAAM,CAAC,OAAO,iBAAiB,EAAE,QAAQ,EAAE,cAAc,kBAAkB,EAAE,OAAO,CAAC,CAc7F;AAEF;IAwBI;;;;;;;;OAQG;IACH,kBAPW,OAAO,iBAAiB,EAAE,QAAQ,WAClC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAyCzC;IApCG,yCAAgB;IAIZ,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAyKlC,2DAIC;IAoBD;;;;;OAKG;IAEH,iEAqJC;IAUD;;;;;OAKG;IACH,4IAMC;IAED;;;;OAIG;IACH,sBAFa,OAAO,WAAW,EAAE,UAAU,EAAE,CAS5C;IAkBD;;OAEG;IACH,uDAEC;IAED;;OAEG;IACH,oCA0EC;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;;CACJ;iBAllBgB,WAAW"}
1
+ {"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AA+BA;;;;GAIG;AACH,wBAHU,MAAM,CAAC,OAAO,iBAAiB,EAAE,QAAQ,EAAE,cAAc,kBAAkB,EAAE,OAAO,CAAC,CAc7F;AAEF;;;GAGG;AACH,8BAHmD,KAAK,SAA3C,OAAQ,iBAAiB,EAAE,QAAS;IA2B7C;;;;;;;;OAQG;IACH,kBAPW,KAAK,WACL,OAAO,yBAAyB,EAAE,OAAO,gBACzC,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAyCzC;IAhCO,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAyKlC,2DAIC;IAoBD;;;;;OAKG;IAEH,iEAqJC;IAUD;;;;;OAKG;IACH,4IAMC;IAED;;;;OAIG;IACH,sBAFa,OAAO,WAAW,EAAE,UAAU,EAAE,CAS5C;IAkBD;;OAEG;IACH,uDAEC;IAED;;OAEG;IACH,oCA0EC;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;;CACJ;iBAtlBgB,WAAW"}
@@ -47,6 +47,10 @@ export const markTypes = {
47
47
  text: TextMark,
48
48
  };
49
49
 
50
+ /**
51
+ * @template {import("../spec/view.js").UnitSpec} [TSpec=import("../spec/view.js").UnitSpec]
52
+ * @extends {View<TSpec>}
53
+ */
50
54
  export default class UnitView extends View {
51
55
  /**
52
56
  * @typedef {import("../spec/channel.js").Channel} Channel
@@ -73,7 +77,7 @@ export default class UnitView extends View {
73
77
 
74
78
  /**
75
79
  *
76
- * @param {import("../spec/view.js").UnitSpec} spec
80
+ * @param {TSpec} spec
77
81
  * @param {import("../types/viewContext.js").default} context
78
82
  * @param {import("./containerView.js").default} layoutParent
79
83
  * @param {import("./view.js").default} dataParent
@@ -31,10 +31,13 @@ export const VISIT_STOP: "VISIT_STOP";
31
31
  * View's children are layered on top of each other and they have the same
32
32
  * coordinates as their parent.
33
33
  */
34
- export default class View {
34
+ /**
35
+ * @template {import("../spec/view.js").ViewSpec} [TSpec=import("../spec/view.js").ViewSpec]
36
+ */
37
+ export default class View<TSpec extends import("../spec/view.js").ViewSpec = import("../spec/view.js").ViewSpec> {
35
38
  /**
36
39
  *
37
- * @param {import("../spec/view.js").ViewSpec} spec
40
+ * @param {TSpec} spec
38
41
  * @param {import("../types/viewContext.js").default} context
39
42
  * @param {import("./containerView.js").default} layoutParent Parent that handles rendering of this view
40
43
  * @param {import("./view.js").default} dataParent Parent that provides data, encodings, and is used in scale resolution
@@ -42,7 +45,9 @@ export default class View {
42
45
  * @param {ViewOptions} [options]
43
46
  *
44
47
  */
45
- constructor(spec: import("../spec/view.js").ViewSpec, context: import("../types/viewContext.js").default, layoutParent: import("./containerView.js").default, dataParent: import("./view.js").default, name: string, options?: ViewOptions);
48
+ constructor(spec: TSpec, context: import("../types/viewContext.js").default, layoutParent: import("./containerView.js").default, dataParent: import("./view.js").default, name: string, options?: ViewOptions);
49
+ /** @type {TSpec} */
50
+ spec: TSpec;
46
51
  /**
47
52
  * @type {function(number):number}
48
53
  */
@@ -55,9 +60,8 @@ export default class View {
55
60
  */
56
61
  facetCoords: Map<any, import("./layout/rectangle.js").default>;
57
62
  context: import("../types/viewContext.js").default;
58
- layoutParent: import("./containerView.js").default;
59
- dataParent: View;
60
- spec: import("../spec/view.js").ViewSpec;
63
+ layoutParent: import("./containerView.js").default<import("../spec/view.js").ContainerSpec>;
64
+ dataParent: View<import("../spec/view.js").ViewSpec>;
61
65
  resolutions: {
62
66
  /**
63
67
  * Channel-specific scale resolutions
@@ -183,11 +187,11 @@ export default class View {
183
187
  /**
184
188
  * Returns the ancestor views, starting with this view.
185
189
  */
186
- getLayoutAncestors(): View[];
190
+ getLayoutAncestors(): View<import("../spec/view.js").ViewSpec>[];
187
191
  /**
188
192
  * Returns the ancestor views, starting with this view.
189
193
  */
190
- getDataAncestors(): View[];
194
+ getDataAncestors(): View<import("../spec/view.js").ViewSpec>[];
191
195
  /**
192
196
  * Handles a broadcast message that is intended for the whole view hierarchy.
193
197
  *
@@ -241,7 +245,7 @@ export default class View {
241
245
  /**
242
246
  * Get this view and all descendants in depth-first order.
243
247
  */
244
- getDescendants(): View[];
248
+ getDescendants(): View<import("../spec/view.js").ViewSpec>[];
245
249
  /**
246
250
  * Release resources owned by this view.
247
251
  */