@d3-maps/vue 0.8.0 → 0.9.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.
package/README.md CHANGED
@@ -1,8 +1,18 @@
1
1
  # @d3-maps/vue
2
2
 
3
- Reactive SVG maps, powered by D3.
3
+ Reactive SVG maps, powered by D3
4
4
 
5
- [docs](https://souljorje.github.io/d3-maps)
5
+ [**Docs**](https://souljorje.github.io/d3-maps/guide) · [**Examples**](https://souljorje.github.io/d3-maps/examples)
6
+
7
+ ## Features
8
+
9
+ - Drop-in components, powerful defaults
10
+ - Zoom, drag, lines, markers, and more
11
+ - Reactive rerender
12
+ - Responsive by default
13
+ - Lightweight and tree-shakable
14
+ - SSR friendly
15
+ - Supports TopoJSON and GeoJSON
6
16
 
7
17
  ## Installation
8
18
 
@@ -26,6 +36,27 @@ bun add @d3-maps/vue
26
36
 
27
37
  ## Usage
28
38
 
39
+ ```html
40
+ <script setup lang="ts">
41
+ import type { MapData } from '@d3-maps/core'
42
+
43
+ import { MapBase, MapFeatures } from '@d3-maps/vue'
44
+ defineProps<{
45
+ data: MapData
46
+ }>()
47
+ </script>
48
+
49
+ <template>
50
+ <MapBase :data="data">
51
+ <MapFeatures />
52
+ </MapBase>
53
+ </template>
54
+ ```
55
+
56
+ ### Plugin
57
+
58
+ Registers all components in the app
59
+
29
60
  ```js
30
61
  import { createApp } from 'vue'
31
62
  import { plugin as D3MapsVue } from '@d3-maps/vue'
@@ -47,12 +78,6 @@ export default defineNuxtPlugin((nuxtApp) => {
47
78
  })
48
79
  ```
49
80
 
50
- ## Styling
51
-
52
- Importing `@d3-maps/vue` automatically includes `@d3-maps/core/index.css`
53
-
54
- If you need strict stylesheet ordering, load your global reset/theme styles before importing the adapter entry
55
-
56
81
  ## License
57
82
 
58
83
  MIT licensed. Copyright © 2020 Georgii Bukharov. See [LICENSE](./LICENSE) for more details.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import "@d3-maps/core/index.css";
2
- import * as vue6 from "vue";
3
- import { App, ComputedRef, InjectionKey, MaybeRef, StyleValue } from "vue";
2
+ import * as vue0 from "vue";
3
+ import { App, ComputedRef, InjectionKey, MaybeRef, Ref, StyleValue } from "vue";
4
4
  import { CurveFactory, CurveFactoryLineOnly } from "d3-shape";
5
- import { ExtendedFeature, ExtendedFeatureCollection, GeoGraticuleGenerator, GeoPath, GeoProjection } from "d3-geo";
5
+ import { ExtendedFeature, ExtendedFeatureCollection, GeoGraticuleGenerator, GeoPath, GeoPermissibleObjects, GeoProjection } from "d3-geo";
6
6
  import { Topology } from "topojson-specification";
7
7
  import "topojson-client";
8
8
  import { D3ZoomEvent, ZoomBehavior } from "d3-zoom";
@@ -11,7 +11,7 @@ import { D3ZoomEvent, ZoomBehavior } from "d3-zoom";
11
11
  /**
12
12
  * Supported interaction states for map objects.
13
13
  */
14
- declare const mapObjectState: readonly ["default", "hover", "active"];
14
+ declare const mapObjectState: readonly ["default", "hover", "active", "focus"];
15
15
  type MapObjectState = typeof mapObjectState[number];
16
16
  interface MapObjectProps<TStyle = unknown> {
17
17
  styles?: Partial<Record<MapObjectState, TStyle>>;
@@ -110,8 +110,8 @@ type MapData = ExtendedFeatureCollection | Topology;
110
110
  type DataTransformer = (features: MapFeature[]) => MapFeature[];
111
111
  /**
112
112
  * Extra projection method calls to apply before rendering.
113
- *
114
113
  * Use projection method names as keys and method arguments as values.
114
+ *
115
115
  * Example: `{ center: [[0, 20]], rotate: [[0, 0, 0]], scale: 160 }`
116
116
  *
117
117
  * @see https://d3js.org/d3-geo/projection
@@ -153,12 +153,30 @@ interface MapProps {
153
153
  * Adapters provide this context to child layers (features, markers, custom SVG).
154
154
  */
155
155
  interface MapContext {
156
+ /**
157
+ * Resolved SVG width used by the map.
158
+ */
156
159
  width: number;
160
+ /**
161
+ * Resolved SVG height used by the map.
162
+ */
157
163
  height: number;
164
+ /**
165
+ * Configured projection instance shared by map layers.
166
+ */
158
167
  projection: GeoProjection;
168
+ /**
169
+ * Normalized feature list after optional transformation.
170
+ */
159
171
  features: MapFeature[];
172
+ /**
173
+ * Shared path generator bound to the map projection.
174
+ */
160
175
  path: GeoPath;
161
- renderMesh: () => ReturnType<GeoPath>;
176
+ /**
177
+ * Renders a TopoJSON mesh path when one is available.
178
+ */
179
+ renderMesh: () => string | null;
162
180
  }
163
181
  //#endregion
164
182
  //#region ../core/src/lib/line.d.ts
@@ -177,6 +195,20 @@ type MapLineCurve = CurveFactory | CurveFactoryLineOnly;
177
195
  * - second value: moves the generated midpoint perpendicular to the segment direction
178
196
  */
179
197
  type MapLineMidpoint = [number, number];
198
+ /**
199
+ * Core line rendering options shared by framework adapters
200
+ */
201
+ interface MapLineOptions {
202
+ coordinates: MapLineCoordinates;
203
+ cartesian?: boolean;
204
+ custom?: boolean;
205
+ curve?: MapLineCurve;
206
+ midpoint?: MapLineMidpoint;
207
+ }
208
+ /**
209
+ * Public map line props including map object styling and interaction support
210
+ */
211
+ interface MapLineProps<TStyle = unknown> extends MapObjectProps<TStyle>, MapLineOptions {}
180
212
  //#endregion
181
213
  //#region ../core/src/lib/annotation.d.ts
182
214
  /**
@@ -225,6 +257,7 @@ interface MapMarkerProps<TStyle = unknown> extends MapObjectProps<TStyle> {
225
257
  //#endregion
226
258
  //#region ../core/src/lib/zoom.d.ts
227
259
  interface DefaultZoomBehavior extends ZoomBehavior<SVGSVGElement, unknown> {}
260
+ type ZoomObject = GeoPermissibleObjects;
228
261
  /**
229
262
  * Extra zoom method calls to apply before rendering.
230
263
  *
@@ -235,21 +268,61 @@ interface DefaultZoomBehavior extends ZoomBehavior<SVGSVGElement, unknown> {}
235
268
  */
236
269
  interface ZoomModifiers extends MethodsToModifiers<DefaultZoomBehavior> {}
237
270
  interface ZoomProps {
271
+ /**
272
+ * Projected map-space point to keep centered in the viewport.
273
+ *
274
+ * If omitted, changing `zoom` alone preserves the current viewport center.
275
+ */
238
276
  center?: [number, number];
239
277
  zoom?: number;
240
278
  minZoom?: number;
241
279
  maxZoom?: number;
280
+ transition?: ZoomTransition;
242
281
  config?: ZoomModifiers;
243
282
  }
283
+ /**
284
+ * D3 zoom event used by adapter components and hooks.
285
+ */
244
286
  interface ZoomEvent extends D3ZoomEvent<SVGSVGElement, unknown> {}
287
+ /**
288
+ * Zoom lifecycle callbacks forwarded from the underlying D3 zoom behavior.
289
+ */
290
+ interface ZoomEvents {
291
+ onZoomStart?: (event: ZoomEvent) => void;
292
+ onZoom?: (event: ZoomEvent) => void;
293
+ onZoomEnd?: (event: ZoomEvent) => void;
294
+ }
295
+ /**
296
+ * Full zoom behavior configuration, including view props and event callbacks.
297
+ */
298
+ interface ZoomBehaviorOptions extends ZoomProps, ZoomEvents {}
299
+ /**
300
+ * Transition settings for programmatic zoom updates.
301
+ */
302
+ interface ZoomTransition {
303
+ duration?: number;
304
+ delay?: number;
305
+ ease?: (normalizedTime: number) => number;
306
+ }
307
+ /**
308
+ * Computed zoom target for an object fit operation.
309
+ */
310
+ interface ObjectZoomView {
311
+ center: [number, number];
312
+ zoom: number;
313
+ }
314
+ /**
315
+ * Creates a D3 zoom behavior configured for the current map viewport.
316
+ */
317
+ declare function createZoomBehavior(context?: Pick<MapContext, 'width' | 'height'>, options?: ZoomBehaviorOptions): DefaultZoomBehavior;
245
318
  //#endregion
246
319
  //#region src/components/MapAnnotation.vue.d.ts
247
- type __VLS_Props$4 = MapAnnotationProps<StyleValue>;
320
+ type __VLS_Props$5 = MapAnnotationProps<StyleValue>;
248
321
  declare var __VLS_13: {};
249
322
  type __VLS_Slots$4 = {} & {
250
323
  default?: (props: typeof __VLS_13) => any;
251
324
  };
252
- declare const __VLS_base$4: vue6.DefineComponent<__VLS_Props$4, {}, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<__VLS_Props$4> & Readonly<{}>, {}, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
325
+ declare const __VLS_base$4: vue0.DefineComponent<__VLS_Props$5, {}, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<__VLS_Props$5> & Readonly<{}>, {}, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
253
326
  declare const __VLS_export$8: __VLS_WithSlots$4<typeof __VLS_base$4, __VLS_Slots$4>;
254
327
  declare const _default: typeof __VLS_export$8;
255
328
  type __VLS_WithSlots$4<T, S> = T & {
@@ -259,10 +332,16 @@ type __VLS_WithSlots$4<T, S> = T & {
259
332
  };
260
333
  //#endregion
261
334
  //#region src/components/MapBase.vue.d.ts
335
+ type MapConfigProps = MapProps & {
336
+ context?: undefined;
337
+ };
338
+ type MapContextProps = Partial<MapProps> & {
339
+ context: MapContext;
340
+ };
262
341
  type __VLS_Slots$3 = {
263
342
  default?: (props: MapContext) => unknown;
264
343
  };
265
- declare const __VLS_base$3: vue6.DefineComponent<MapProps, {}, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<MapProps> & Readonly<{}>, {}, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
344
+ declare const __VLS_base$3: vue0.DefineComponent<MapConfigProps | MapContextProps, {}, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<MapConfigProps | MapContextProps> & Readonly<{}>, {}, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
266
345
  declare const __VLS_export$7: __VLS_WithSlots$3<typeof __VLS_base$3, __VLS_Slots$3>;
267
346
  declare const _default$1: typeof __VLS_export$7;
268
347
  type __VLS_WithSlots$3<T, S> = T & {
@@ -272,21 +351,21 @@ type __VLS_WithSlots$3<T, S> = T & {
272
351
  };
273
352
  //#endregion
274
353
  //#region src/components/MapFeature.vue.d.ts
275
- type __VLS_Props$3 = MapFeatureProps<StyleValue>;
276
- declare const __VLS_export$6: vue6.DefineComponent<__VLS_Props$3, {}, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<__VLS_Props$3> & Readonly<{}>, {}, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
354
+ type __VLS_Props$4 = MapFeatureProps<StyleValue>;
355
+ declare const __VLS_export$6: vue0.DefineComponent<__VLS_Props$4, {}, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<__VLS_Props$4> & Readonly<{}>, {}, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
277
356
  declare const _default$2: typeof __VLS_export$6;
278
357
  //#endregion
279
358
  //#region src/components/MapFeatures.vue.d.ts
280
- type __VLS_Props$2 = MapFeaturesProps<StyleValue>;
359
+ type __VLS_Props$3 = MapFeaturesProps<StyleValue>;
281
360
  declare var __VLS_1$2: {
282
361
  features: MapFeature[];
283
362
  };
284
363
  type __VLS_Slots$2 = {} & {
285
364
  default?: (props: typeof __VLS_1$2) => any;
286
365
  };
287
- declare const __VLS_base$2: vue6.DefineComponent<__VLS_Props$2, {}, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<__VLS_Props$2> & Readonly<{}>, {
366
+ declare const __VLS_base$2: vue0.DefineComponent<__VLS_Props$3, {}, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<__VLS_Props$3> & Readonly<{}>, {
288
367
  idKey: string;
289
- }, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
368
+ }, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
290
369
  declare const __VLS_export$5: __VLS_WithSlots$2<typeof __VLS_base$2, __VLS_Slots$2>;
291
370
  declare const _default$3: typeof __VLS_export$5;
292
371
  type __VLS_WithSlots$2<T, S> = T & {
@@ -296,22 +375,16 @@ type __VLS_WithSlots$2<T, S> = T & {
296
375
  };
297
376
  //#endregion
298
377
  //#region src/components/MapGraticule.vue.d.ts
299
- type __VLS_Props$1 = MapGraticuleProps<StyleValue>;
300
- declare const __VLS_export$4: vue6.DefineComponent<__VLS_Props$1, {}, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<__VLS_Props$1> & Readonly<{}>, {}, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
378
+ type __VLS_Props$2 = MapGraticuleProps<StyleValue>;
379
+ declare const __VLS_export$4: vue0.DefineComponent<__VLS_Props$2, {}, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<__VLS_Props$2> & Readonly<{}>, {}, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
301
380
  declare const _default$4: typeof __VLS_export$4;
302
381
  //#endregion
303
382
  //#region src/components/MapLine.vue.d.ts
304
- interface Props$1 extends MapObjectProps<StyleValue> {
305
- coordinates: MapLineCoordinates;
306
- cartesian?: boolean;
307
- custom?: boolean;
308
- curve?: MapLineCurve;
309
- midpoint?: [number, number];
310
- }
311
- declare const __VLS_export$3: vue6.DefineComponent<Props$1, {}, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<Props$1> & Readonly<{}>, {
383
+ type __VLS_Props$1 = MapLineProps<StyleValue>;
384
+ declare const __VLS_export$3: vue0.DefineComponent<__VLS_Props$1, {}, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<__VLS_Props$1> & Readonly<{}>, {
312
385
  cartesian: boolean;
313
386
  custom: boolean;
314
- }, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
387
+ }, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
315
388
  declare const _default$5: typeof __VLS_export$3;
316
389
  //#endregion
317
390
  //#region src/components/MapMarker.vue.d.ts
@@ -322,9 +395,9 @@ declare var __VLS_1$1: {};
322
395
  type __VLS_Slots$1 = {} & {
323
396
  default?: (props: typeof __VLS_1$1) => any;
324
397
  };
325
- declare const __VLS_base$1: vue6.DefineComponent<Props, {}, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<Props> & Readonly<{}>, {
398
+ declare const __VLS_base$1: vue0.DefineComponent<Props, {}, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<Props> & Readonly<{}>, {
326
399
  name: string;
327
- }, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
400
+ }, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
328
401
  declare const __VLS_export$2: __VLS_WithSlots$1<typeof __VLS_base$1, __VLS_Slots$1>;
329
402
  declare const _default$6: typeof __VLS_export$2;
330
403
  type __VLS_WithSlots$1<T, S> = T & {
@@ -335,7 +408,7 @@ type __VLS_WithSlots$1<T, S> = T & {
335
408
  //#endregion
336
409
  //#region src/components/MapMesh.vue.d.ts
337
410
  type __VLS_Props = MapObjectProps<StyleValue>;
338
- declare const __VLS_export$1: vue6.DefineComponent<__VLS_Props, {}, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {}, string, vue6.PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
411
+ declare const __VLS_export$1: vue0.DefineComponent<__VLS_Props, {}, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
339
412
  declare const _default$7: typeof __VLS_export$1;
340
413
  //#endregion
341
414
  //#region src/components/MapZoom.vue.d.ts
@@ -343,23 +416,26 @@ declare var __VLS_1: {};
343
416
  type __VLS_Slots = {} & {
344
417
  default?: (props: typeof __VLS_1) => any;
345
418
  };
346
- declare const __VLS_base: vue6.DefineComponent<ZoomProps, {
347
- container: vue6.Ref<SVGGElement | null, SVGGElement | null>;
348
- zoomBehavior: vue6.ComputedRef<DefaultZoomBehavior>;
349
- }, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {} & {
419
+ declare const __VLS_base: vue0.DefineComponent<ZoomProps, {
420
+ container: vue0.Ref<SVGGElement | null, SVGGElement | null>;
421
+ zoomBehavior: vue0.ComputedRef<DefaultZoomBehavior>;
422
+ }, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {} & {
350
423
  zoom: (payload: ZoomEvent) => any;
351
- zoomstart: (payload: ZoomEvent) => any;
352
- zoomend: (payload: ZoomEvent) => any;
353
- }, string, vue6.PublicProps, Readonly<ZoomProps> & Readonly<{
424
+ zoomStart: (payload: ZoomEvent) => any;
425
+ zoomEnd: (payload: ZoomEvent) => any;
426
+ "update:center": (payload: [number, number]) => any;
427
+ "update:zoom": (payload: number) => any;
428
+ }, string, vue0.PublicProps, Readonly<ZoomProps> & Readonly<{
354
429
  onZoom?: ((payload: ZoomEvent) => any) | undefined;
355
- onZoomstart?: ((payload: ZoomEvent) => any) | undefined;
356
- onZoomend?: ((payload: ZoomEvent) => any) | undefined;
430
+ onZoomStart?: ((payload: ZoomEvent) => any) | undefined;
431
+ onZoomEnd?: ((payload: ZoomEvent) => any) | undefined;
432
+ "onUpdate:center"?: ((payload: [number, number]) => any) | undefined;
433
+ "onUpdate:zoom"?: ((payload: number) => any) | undefined;
357
434
  }>, {
358
- center: [number, number];
359
435
  zoom: number;
360
436
  minZoom: number;
361
437
  maxZoom: number;
362
- }, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
438
+ }, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
363
439
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
364
440
  declare const _default$8: typeof __VLS_export;
365
441
  type __VLS_WithSlots<T, S> = T & {
@@ -368,20 +444,52 @@ type __VLS_WithSlots<T, S> = T & {
368
444
  };
369
445
  };
370
446
  //#endregion
447
+ //#region src/hooks/useCreateMapContext.d.ts
448
+ declare function useCreateMapContext(config?: MaybeRef<Partial<MapProps> | undefined>, context?: MaybeRef<MapContext | undefined>): ComputedRef<MapContext | undefined>;
449
+ //#endregion
371
450
  //#region src/hooks/useMapContext.d.ts
372
451
  declare const mapContextKey: InjectionKey<ComputedRef<MapContext>>;
373
- declare function useMapContext(): ComputedRef<MapContext> | undefined;
452
+ declare function useMapContext(): ComputedRef<MapContext>;
374
453
  //#endregion
375
454
  //#region src/hooks/useMapObject.d.ts
376
455
  interface UseMapObjectResult {
377
456
  style: ComputedRef<StyleValue | undefined>;
378
- onMouseenter: (event: MouseEvent) => void;
379
- onMouseleave: (event: MouseEvent) => void;
457
+ onMouseenter: () => void;
458
+ onMouseleave: () => void;
380
459
  onMousedown: (event: MouseEvent) => void;
381
- onMouseup: (event: MouseEvent) => void;
460
+ onMouseup: () => void;
461
+ onFocus: () => void;
462
+ onBlur: () => void;
382
463
  }
383
464
  declare function useMapObject(styles: MaybeRef<Partial<Record<MapObjectState, StyleValue>> | undefined>): UseMapObjectResult;
384
465
  //#endregion
466
+ //#region src/hooks/useMapZoom.d.ts
467
+ type ZoomToObjectCallback = (view: ObjectZoomView) => void;
468
+ interface UseMapZoomResult {
469
+ center: ComputedRef<[number, number] | undefined>;
470
+ zoom: ComputedRef<number>;
471
+ minZoom: ComputedRef<number>;
472
+ maxZoom: ComputedRef<number>;
473
+ zoomToObject: (object: ZoomObject, callback: ZoomToObjectCallback) => void;
474
+ }
475
+ declare const mapZoomKey: InjectionKey<UseMapZoomResult>;
476
+ interface MapZoomEventCallbacks {
477
+ onZoomStart?: (event: ZoomEvent) => void;
478
+ onZoom?: (event: ZoomEvent) => void;
479
+ onZoomEnd?: (event: ZoomEvent) => void;
480
+ }
481
+ interface ZoomPropsWithDefaults extends ZoomProps {
482
+ zoom: number;
483
+ minZoom: number;
484
+ maxZoom: number;
485
+ }
486
+ interface CreateMapZoomResult {
487
+ zoomBehavior: ComputedRef<ReturnType<typeof createZoomBehavior>>;
488
+ zoomContext: UseMapZoomResult;
489
+ }
490
+ declare function useCreateMapZoom(container: Ref<SVGGElement | null>, props: Readonly<ZoomPropsWithDefaults>, eventCallbacks: MapZoomEventCallbacks): CreateMapZoomResult;
491
+ declare function useMapZoom(): UseMapZoomResult | undefined;
492
+ //#endregion
385
493
  //#region src/plugin.d.ts
386
494
  /**
387
495
  * Vue plugin that registers all d3-maps components globally.
@@ -390,4 +498,4 @@ declare const plugin: {
390
498
  install(app: App): void;
391
499
  };
392
500
  //#endregion
393
- export { _default as MapAnnotation, _default$1 as MapBase, _default$2 as MapFeature, _default$3 as MapFeatures, _default$4 as MapGraticule, _default$5 as MapLine, _default$6 as MapMarker, _default$7 as MapMesh, _default$8 as MapZoom, UseMapObjectResult, mapContextKey, plugin, useMapContext, useMapObject };
501
+ export { CreateMapZoomResult, _default as MapAnnotation, _default$1 as MapBase, _default$2 as MapFeature, _default$3 as MapFeatures, _default$4 as MapGraticule, _default$5 as MapLine, _default$6 as MapMarker, _default$7 as MapMesh, _default$8 as MapZoom, MapZoomEventCallbacks, UseMapObjectResult, UseMapZoomResult, ZoomPropsWithDefaults, ZoomToObjectCallback, mapContextKey, mapZoomKey, plugin, useCreateMapContext, useCreateMapZoom, useMapContext, useMapObject, useMapZoom };
@@ -1 +1 @@
1
- (function(e,t,n,r){var i=Object.defineProperty,a=(e,t)=>{let n={};for(var r in e)i(n,r,{get:e[r],enumerable:!0});return t&&i(n,Symbol.toStringTag,{value:`Module`}),n};let o=Symbol(`MapContext`);function s(){return(0,n.inject)(o)}let c=Symbol(`InsideZoom`);function l(){return(0,n.inject)(c,!1)}function u(e){let t=(0,n.ref)(`default`),{onMouseenter:i,onMouseleave:a,onMouseup:o,onMousedown:s,dispose:c}=(0,r.useMapObjectEvents)(e=>{t.value=e},l());return(0,n.onBeforeUnmount)(()=>{c()}),{style:(0,n.computed)(()=>(0,r.resolveObjectStyle)(t.value,(0,n.unref)(e))),onMouseenter:i,onMouseleave:a,onMousedown:s,onMouseup:o}}let d=[`d`];var f=(0,n.defineComponent)({inheritAttrs:!1,__name:`MapLine`,props:{coordinates:{},cartesian:{type:Boolean,default:!1},custom:{type:Boolean,default:!1},curve:{},midpoint:{},styles:{}},setup(e){let t=e,i=(0,n.useAttrs)(),a=s(),o=(0,n.computed)(()=>(0,r.getLinePath)(a?.value,{coordinates:t.coordinates,custom:t.custom,curve:t.curve,cartesian:t.cartesian,midpoint:t.midpoint})),c=(0,n.computed)(()=>i.name??`line`),{style:l,...f}=u((0,n.toRef)(t,`styles`)),p=(0,n.computed)(()=>({...i,...f,name:c.value}));return(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`path`,(0,n.mergeProps)(p.value,{d:o.value,fill:`none`,style:(0,n.unref)(l)}),null,16,d))}});let p=[`transform`,`name`];var m=(0,n.defineComponent)({__name:`MapMarker`,props:{name:{default:`marker`},coordinates:{},styles:{}},setup(e){let t=e,i=s(),a=(0,n.computed)(()=>(0,r.getMarkerTransform)(i?.value,t.coordinates)),{style:o,...c}=u((0,n.toRef)(t,`styles`));return(t,r)=>a.value?((0,n.openBlock)(),(0,n.createElementBlock)(`g`,(0,n.mergeProps)({key:0,transform:a.value,style:(0,n.unref)(o),name:e.name},c),[(0,n.renderSlot)(t.$slots,`default`)],16,p)):(0,n.createCommentVNode)(`v-if`,!0)}});let h=[`transform`],g=[`transform`];var _=(0,n.defineComponent)({inheritAttrs:!1,__name:`MapAnnotation`,props:{coordinates:{},length:{},angle:{},margin:{},curve:{type:Function},midpoint:{},styles:{}},setup(e){let t=e,i=(0,n.computed)(()=>(0,r.getAnnotationGeometry)({length:t.length,angle:t.angle,margin:t.margin}));return(t,r)=>((0,n.openBlock)(),(0,n.createBlock)(m,{coordinates:e.coordinates,name:`annotation`},{default:(0,n.withCtx)(()=>[(0,n.createElementVNode)(`g`,{transform:i.value.lineTransform},[(0,n.createVNode)(f,(0,n.mergeProps)(t.$attrs,{coordinates:i.value.lineCoordinates,cartesian:``,curve:e.curve,midpoint:e.midpoint,styles:e.styles,fill:`none`,name:`annotation-line`}),null,16,[`coordinates`,`curve`,`midpoint`,`styles`])],8,h),(0,n.createElementVNode)(`g`,{transform:i.value.contentTransform,name:`annotation-content`},[(0,n.renderSlot)(t.$slots,`default`)],8,g)]),_:3},8,[`coordinates`]))}});let v=[`viewBox`];var y=(0,n.defineComponent)({__name:`MapBase`,props:{width:{},height:{},aspectRatio:{},projection:{type:Function},projectionConfig:{},data:{},dataTransformer:{type:Function}},setup(e){let t=e,i=(0,n.computed)(()=>(0,r.makeMapContext)({width:t.width,height:t.height,aspectRatio:t.aspectRatio,projection:t.projection,projectionConfig:t.projectionConfig,data:t.data,dataTransformer:t.dataTransformer}));return(0,n.provide)(o,i),(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`svg`,(0,n.mergeProps)({viewBox:`0 0 ${i.value.width} ${i.value.height}`},e.$attrs,{class:`d3-map`}),[(0,n.renderSlot)(e.$slots,`default`,(0,n.normalizeProps)((0,n.guardReactiveProps)(i.value)))],16,v))}});let b=[`d`];var x=(0,n.defineComponent)({__name:`MapFeature`,props:{data:{},styles:{}},setup(e){let t=e,{style:r,...i}=u((0,n.toRef)(t,`styles`)),a=s(),o=(0,n.computed)(()=>a?.value.path(t.data)??void 0);return(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`path`,(0,n.mergeProps)({d:o.value,style:(0,n.unref)(r)},i,{name:`feature`}),null,16,b))}});let S={name:`features`};var C=(0,n.defineComponent)({__name:`MapFeatures`,props:{idKey:{default:`id`},styles:{}},setup(e){let t=s(),i=(0,n.computed)(()=>t?.value.features??[]);return(t,a)=>((0,n.openBlock)(),(0,n.createElementBlock)(`g`,S,[(0,n.renderSlot)(t.$slots,`default`,{features:i.value},()=>[((0,n.openBlock)(!0),(0,n.createElementBlock)(n.Fragment,null,(0,n.renderList)(i.value,(t,i)=>((0,n.openBlock)(),(0,n.createBlock)(x,{key:(0,n.unref)(r.getFeatureKey)(t,e.idKey,i),data:t,styles:e.styles},null,8,[`data`,`styles`]))),128))])]))}});let w=[`d`,`fill`],T=[`d`],E=[`d`,`stroke`];var D=(0,n.defineComponent)({inheritAttrs:!1,__name:`MapGraticule`,props:{config:{},background:{type:[Boolean,String]},border:{type:[Boolean,String]},styles:{}},setup(e){let t=e,i=s(),a=(0,n.useAttrs)(),o=(0,n.computed)(()=>{if(i?.value)return(0,r.renderGraticule)(i.value,t.config)??void 0}),c=(0,n.computed)(()=>{if(i?.value)return(0,r.renderOutline)(i.value)??void 0}),l=(0,n.computed)(()=>(0,r.isString)(t.background)?t.background:void 0),d=(0,n.computed)(()=>(0,r.isString)(t.border)?t.border:void 0),{style:f,...p}=u((0,n.toRef)(t,`styles`));return(t,r)=>((0,n.openBlock)(),(0,n.createElementBlock)(`g`,null,[e.background?((0,n.openBlock)(),(0,n.createElementBlock)(`path`,{key:0,d:c.value,fill:l.value,"pointer-events":`none`,name:`background`},null,8,w)):(0,n.createCommentVNode)(`v-if`,!0),(0,n.createElementVNode)(`path`,(0,n.mergeProps)({d:o.value,fill:`none`,style:(0,n.unref)(f)},(0,n.mergeProps)(p,(0,n.unref)(a)),{name:`graticule`}),null,16,T),e.border?((0,n.openBlock)(),(0,n.createElementBlock)(`path`,{key:1,d:c.value,fill:`none`,stroke:d.value,"pointer-events":`none`,name:`border`},null,8,E)):(0,n.createCommentVNode)(`v-if`,!0)]))}});let O=[`d`];var k=(0,n.defineComponent)({__name:`MapMesh`,props:{styles:{}},setup(e){let t=e,r=s(),i=(0,n.computed)(()=>r?.value.renderMesh()??void 0),{style:a,...o}=u((0,n.toRef)(t,`styles`));return(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`path`,(0,n.mergeProps)({d:i.value,fill:`none`,style:(0,n.unref)(a)},o,{name:`mesh`}),null,16,O))}}),A=(0,n.defineComponent)({__name:`MapZoom`,props:{center:{default:()=>[0,0]},zoom:{default:1},minZoom:{default:1},maxZoom:{default:8},config:{}},emits:[`zoomstart`,`zoom`,`zoomend`],setup(e,{expose:t,emit:i}){let a=e,o=i,l=(0,n.ref)(null),u=s();(0,n.provide)(c,!0);let d=(0,n.computed)(()=>(0,r.createZoomBehavior)(u?.value,{minZoom:a.minZoom,maxZoom:a.maxZoom,config:a.config,onZoomStart:e=>o(`zoomstart`,e),onZoom:e=>{(0,r.applyZoomGroupTransform)(l.value,e.transform),o(`zoom`,e)},onZoomEnd:e=>o(`zoomend`,e)}));return(0,n.onMounted)(()=>{(0,n.watch)(d,e=>{l.value&&(0,r.setupZoom)({element:l.value,behavior:e,center:a.center,zoom:a.zoom})},{immediate:!0}),(0,n.watch)(()=>[d.value,a.center[0],a.center[1],a.zoom],()=>{l.value&&(0,r.applyZoomTransform)({element:l.value,behavior:d.value,center:a.center,zoom:a.zoom})})}),t({container:l,zoomBehavior:d}),(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`g`,{ref_key:`container`,ref:l,name:`zoom`},[(0,n.renderSlot)(e.$slots,`default`)],512))}}),j=a({MapAnnotation:()=>_,MapBase:()=>y,MapFeature:()=>x,MapFeatures:()=>C,MapGraticule:()=>D,MapLine:()=>f,MapMarker:()=>m,MapMesh:()=>k,MapZoom:()=>A});e.MapAnnotation=_,e.MapBase=y,e.MapFeature=x,e.MapFeatures=C,e.MapGraticule=D,e.MapLine=f,e.MapMarker=m,e.MapMesh=k,e.MapZoom=A,e.mapContextKey=o,e.plugin={install(e){Object.entries(j).forEach(([t,n])=>{e.component(t,n)})}},e.useMapContext=s,e.useMapObject=u})(this.D3Maps=this.D3Maps||{},_d3_maps_core_index_css,Vue,D3Maps);
1
+ (function(e,t,n,r){var i=Object.defineProperty,a=(e,t)=>{let n={};for(var r in e)i(n,r,{get:e[r],enumerable:!0});return t&&i(n,Symbol.toStringTag,{value:`Module`}),n};let o=Symbol(`MapContext`);function s(){let e=(0,n.inject)(o);if(!e)throw Error(`useMapContext must be used inside Map`);return e}let c=Symbol(`MapZoom`);function l(e,t,i){let a=s(),o=(0,n.computed)(()=>t.center?.[0]),l=(0,n.computed)(()=>t.center?.[1]),u=(0,n.computed)(()=>(0,r.createZoomBehavior)(a.value,{minZoom:t.minZoom,maxZoom:t.maxZoom,config:t.config,onZoomStart:e=>i.onZoomStart?.(e),onZoom:t=>{(0,r.applyZoomGroupTransform)(e.value,t.transform),i.onZoom?.(t)},onZoomEnd:e=>i.onZoomEnd?.(e)})),d={center:(0,n.computed)(()=>t.center),zoom:(0,n.computed)(()=>t.zoom),minZoom:(0,n.computed)(()=>t.minZoom),maxZoom:(0,n.computed)(()=>t.maxZoom),zoomToObject:(e,n)=>{let i=(0,r.getObjectZoomView)(a.value,e,{minZoom:t.minZoom,maxZoom:t.maxZoom});i&&n(i)}};(0,n.provide)(c,d);let f,p;return(0,n.onMounted)(()=>{f=(0,n.watch)(u,t=>{e.value&&(0,r.setupZoom)({element:e.value,behavior:t})},{immediate:!0}),p=(0,n.watch)([o,l,()=>t.zoom,()=>t.transition,u],()=>{e.value&&(0,r.applyZoom)({element:e.value,behavior:u.value,center:t.center,zoom:t.zoom,transition:t.transition})},{immediate:!0})}),(0,n.onUnmounted)(()=>{f?.(),p?.()}),{zoomBehavior:u,zoomContext:d}}function u(){let e=(0,n.inject)(c,void 0),t=(0,n.inject)(o,void 0);if(e)return{...e,zoomToObject:(n,i)=>{if(!t?.value)return;let a=(0,r.getObjectZoomView)(t.value,n,{minZoom:e.minZoom.value,maxZoom:e.maxZoom.value});a&&i(a)}}}function d(e){let t=(0,n.ref)(`default`),{onMouseenter:i,onMouseleave:a,onMouseup:o,onMousedown:s,onFocus:c,onBlur:l,dispose:d}=(0,r.useMapObjectEvents)(e=>{t.value=e},!!u());return(0,n.onBeforeUnmount)(()=>{d()}),{style:(0,n.computed)(()=>(0,r.resolveObjectStyle)(t.value,(0,n.unref)(e))),onMouseenter:i,onMouseleave:a,onMousedown:s,onMouseup:o,onFocus:c,onBlur:l}}let f=[`d`,`fill`];var p=(0,n.defineComponent)({inheritAttrs:!1,__name:`MapLine`,props:{styles:{},coordinates:{},cartesian:{type:Boolean,default:!1},custom:{type:Boolean,default:!1},curve:{},midpoint:{}},setup(e){let t=e,i=(0,n.useAttrs)(),a=s(),o=(0,n.computed)(()=>(0,r.getLinePath)(a.value,{coordinates:t.coordinates,custom:t.custom,curve:t.curve,cartesian:t.cartesian,midpoint:t.midpoint})),c=(0,n.computed)(()=>i.name??`line`),l=(0,n.computed)(()=>i.fill??`none`),{style:u,...p}=d((0,n.toRef)(t,`styles`)),m=(0,n.computed)(()=>({...i,...p,name:c.value}));return(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`path`,(0,n.mergeProps)(m.value,{d:o.value,fill:l.value,style:(0,n.unref)(u)}),null,16,f))}});let m=[`transform`,`name`];var h=(0,n.defineComponent)({__name:`MapMarker`,props:{name:{default:`marker`},coordinates:{},styles:{}},setup(e){let t=e,i=s(),a=(0,n.computed)(()=>(0,r.getMarkerTransform)(i.value,t.coordinates)),{style:o,...c}=d((0,n.toRef)(t,`styles`));return(t,r)=>a.value?((0,n.openBlock)(),(0,n.createElementBlock)(`g`,(0,n.mergeProps)({key:0,transform:a.value,style:(0,n.unref)(o),name:e.name},c),[(0,n.renderSlot)(t.$slots,`default`)],16,m)):(0,n.createCommentVNode)(`v-if`,!0)}});let g=[`transform`],_=[`transform`];var v=(0,n.defineComponent)({inheritAttrs:!1,__name:`MapAnnotation`,props:{coordinates:{},length:{},angle:{},margin:{},curve:{type:Function},midpoint:{},styles:{}},setup(e){let t=e,i=(0,n.computed)(()=>(0,r.getAnnotationGeometry)({length:t.length,angle:t.angle,margin:t.margin}));return(t,r)=>((0,n.openBlock)(),(0,n.createBlock)(h,{coordinates:e.coordinates,name:`annotation`},{default:(0,n.withCtx)(()=>[(0,n.createElementVNode)(`g`,{transform:i.value.lineTransform},[(0,n.createVNode)(p,(0,n.mergeProps)(t.$attrs,{coordinates:i.value.lineCoordinates,cartesian:``,curve:e.curve,midpoint:e.midpoint,styles:e.styles,fill:`none`,name:`annotation-line`}),null,16,[`coordinates`,`curve`,`midpoint`,`styles`])],8,g),(0,n.createElementVNode)(`g`,{transform:i.value.contentTransform,name:`annotation-content`},[(0,n.renderSlot)(t.$slots,`default`)],8,_)]),_:3},8,[`coordinates`]))}});function y(e,t){return(0,n.computed)(()=>{let i=(0,n.unref)(t);if(i)return i;let a=(0,n.unref)(e);if(a?.data)return(0,r.makeMapContext)(a)})}let b=[`viewBox`];var x=(0,n.defineComponent)({__name:`MapBase`,props:{width:{},height:{},aspectRatio:{},projection:{type:Function},projectionConfig:{},data:{},dataTransformer:{type:Function},context:{}},setup(e){let t=e,r=y(t,(0,n.toRef)(t,`context`)),i=(0,n.computed)(()=>{if(!r.value)throw Error(`Map requires data or context`);return r.value});return(0,n.provide)(o,i),(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`svg`,(0,n.mergeProps)({viewBox:`0 0 ${i.value.width} ${i.value.height}`},e.$attrs,{class:`d3-map`}),[(0,n.renderSlot)(e.$slots,`default`,(0,n.normalizeProps)((0,n.guardReactiveProps)(i.value)))],16,b))}});let S=[`d`];var C=(0,n.defineComponent)({__name:`MapFeature`,props:{data:{},styles:{}},setup(e){let t=e,{style:r,...i}=d((0,n.toRef)(t,`styles`)),a=s(),o=(0,n.computed)(()=>a.value.path(t.data)??void 0);return(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`path`,(0,n.mergeProps)({d:o.value,style:(0,n.unref)(r)},i,{name:`feature`}),null,16,S))}});let w={name:`features`};var T=(0,n.defineComponent)({__name:`MapFeatures`,props:{idKey:{default:`id`},styles:{}},setup(e){let t=s(),i=(0,n.computed)(()=>t.value.features);return(t,a)=>((0,n.openBlock)(),(0,n.createElementBlock)(`g`,w,[(0,n.renderSlot)(t.$slots,`default`,{features:i.value},()=>[((0,n.openBlock)(!0),(0,n.createElementBlock)(n.Fragment,null,(0,n.renderList)(i.value,(t,i)=>((0,n.openBlock)(),(0,n.createBlock)(C,{key:(0,n.unref)(r.getFeatureKey)(t,e.idKey,i),data:t,styles:e.styles},null,8,[`data`,`styles`]))),128))])]))}});let E=[`d`,`fill`],D=[`d`],O=[`d`,`stroke`];var k=(0,n.defineComponent)({inheritAttrs:!1,__name:`MapGraticule`,props:{config:{},background:{type:[Boolean,String]},border:{type:[Boolean,String]},styles:{}},setup(e){let t=e,i=s(),a=(0,n.useAttrs)(),o=(0,n.computed)(()=>(0,r.renderGraticule)(i.value,t.config)??void 0),c=(0,n.computed)(()=>(0,r.renderOutline)(i.value)??void 0),l=(0,n.computed)(()=>(0,r.isString)(t.background)?t.background:void 0),u=(0,n.computed)(()=>(0,r.isString)(t.border)?t.border:void 0),{style:f,...p}=d((0,n.toRef)(t,`styles`));return(t,r)=>((0,n.openBlock)(),(0,n.createElementBlock)(`g`,null,[e.background?((0,n.openBlock)(),(0,n.createElementBlock)(`path`,{key:0,d:c.value,fill:l.value,"pointer-events":`none`,name:`background`},null,8,E)):(0,n.createCommentVNode)(`v-if`,!0),(0,n.createElementVNode)(`path`,(0,n.mergeProps)({d:o.value,fill:`none`,style:(0,n.unref)(f)},(0,n.mergeProps)(p,(0,n.unref)(a)),{name:`graticule`}),null,16,D),e.border?((0,n.openBlock)(),(0,n.createElementBlock)(`path`,{key:1,d:c.value,fill:`none`,stroke:u.value,"pointer-events":`none`,name:`border`},null,8,O)):(0,n.createCommentVNode)(`v-if`,!0)]))}});let A=[`d`];var j=(0,n.defineComponent)({__name:`MapMesh`,props:{styles:{}},setup(e){let t=e,r=s(),i=(0,n.computed)(()=>r.value.renderMesh()??void 0),{style:a,...o}=d((0,n.toRef)(t,`styles`));return(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`path`,(0,n.mergeProps)({d:i.value,fill:`none`,style:(0,n.unref)(a)},o,{name:`mesh`}),null,16,A))}}),M=(0,n.defineComponent)({__name:`MapZoom`,props:{center:{},zoom:{default:1},minZoom:{default:1},maxZoom:{default:8},transition:{},config:{}},emits:[`zoomStart`,`zoom`,`zoomEnd`,`update:center`,`update:zoom`],setup(e,{expose:t,emit:i}){let a=e,o=i,c=(0,n.ref)(null),u=s();function d(e,t){return!!(t&&e[0]===t[0]&&e[1]===t[1])}let{zoomBehavior:f}=l(c,a,{onZoomStart:e=>o(`zoomStart`,e),onZoom:e=>{let t=(0,r.getZoomViewportCenter)(u.value,e.transform),n=e.transform.k;d(t,a.center)||o(`update:center`,t),n!==a.zoom&&o(`update:zoom`,n),o(`zoom`,e)},onZoomEnd:e=>o(`zoomEnd`,e)});return t({container:c,zoomBehavior:f}),(e,t)=>((0,n.openBlock)(),(0,n.createElementBlock)(`g`,{ref_key:`container`,ref:c,name:`zoom`},[(0,n.renderSlot)(e.$slots,`default`)],512))}}),N=a({MapAnnotation:()=>v,MapBase:()=>x,MapFeature:()=>C,MapFeatures:()=>T,MapGraticule:()=>k,MapLine:()=>p,MapMarker:()=>h,MapMesh:()=>j,MapZoom:()=>M});e.MapAnnotation=v,e.MapBase=x,e.MapFeature=C,e.MapFeatures=T,e.MapGraticule=k,e.MapLine=p,e.MapMarker=h,e.MapMesh=j,e.MapZoom=M,e.mapContextKey=o,e.mapZoomKey=c,e.plugin={install(e){Object.entries(N).forEach(([t,n])=>{e.component(t,n)})}},e.useCreateMapContext=y,e.useCreateMapZoom=l,e.useMapContext=s,e.useMapObject=d,e.useMapZoom=u})(this.D3Maps=this.D3Maps||{},_d3_maps_core_index_css,Vue,D3Maps);
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "@d3-maps/core/index.css";
2
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, guardReactiveProps, inject, mergeProps, normalizeProps, onBeforeUnmount, onMounted, openBlock, provide, ref, renderList, renderSlot, toRef, unref, useAttrs, watch, withCtx } from "vue";
3
- import { applyZoomGroupTransform, applyZoomTransform, createZoomBehavior, getAnnotationGeometry, getFeatureKey, getLinePath, getMarkerTransform, isString, makeMapContext, renderGraticule, renderOutline, resolveObjectStyle, setupZoom, useMapObjectEvents } from "@d3-maps/core";
2
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, guardReactiveProps, inject, mergeProps, normalizeProps, onBeforeUnmount, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, toRef, unref, useAttrs, watch, withCtx } from "vue";
3
+ import { applyZoom, applyZoomGroupTransform, createZoomBehavior, getAnnotationGeometry, getFeatureKey, getLinePath, getMarkerTransform, getObjectZoomView, getZoomViewportCenter, isString, makeMapContext, renderGraticule, renderOutline, resolveObjectStyle, setupZoom, useMapObjectEvents } from "@d3-maps/core";
4
4
 
5
5
  //#region rolldown:runtime
6
6
  var __defProp = Object.defineProperty;
@@ -22,23 +22,107 @@ var __exportAll = (all, symbols) => {
22
22
  //#region src/hooks/useMapContext.ts
23
23
  const mapContextKey = Symbol("MapContext");
24
24
  function useMapContext() {
25
- return inject(mapContextKey);
25
+ const context = inject(mapContextKey);
26
+ if (!context) throw new Error("useMapContext must be used inside Map");
27
+ return context;
26
28
  }
27
29
 
28
30
  //#endregion
29
- //#region src/hooks/useInsideZoom.ts
30
- const insideZoomKey = Symbol("InsideZoom");
31
- function useInsideZoom() {
32
- return inject(insideZoomKey, false);
31
+ //#region src/hooks/useMapZoom.ts
32
+ const mapZoomKey = Symbol("MapZoom");
33
+ function useCreateMapZoom(container, props, eventCallbacks) {
34
+ const context = useMapContext();
35
+ const centerX = computed(() => props.center?.[0]);
36
+ const centerY = computed(() => props.center?.[1]);
37
+ const zoomBehavior = computed(() => {
38
+ return createZoomBehavior(context.value, {
39
+ minZoom: props.minZoom,
40
+ maxZoom: props.maxZoom,
41
+ config: props.config,
42
+ onZoomStart: (event) => eventCallbacks.onZoomStart?.(event),
43
+ onZoom: (event) => {
44
+ applyZoomGroupTransform(container.value, event.transform);
45
+ eventCallbacks.onZoom?.(event);
46
+ },
47
+ onZoomEnd: (event) => eventCallbacks.onZoomEnd?.(event)
48
+ });
49
+ });
50
+ const zoomContext = {
51
+ center: computed(() => props.center),
52
+ zoom: computed(() => props.zoom),
53
+ minZoom: computed(() => props.minZoom),
54
+ maxZoom: computed(() => props.maxZoom),
55
+ zoomToObject: (object, callback) => {
56
+ const view = getObjectZoomView(context.value, object, {
57
+ minZoom: props.minZoom,
58
+ maxZoom: props.maxZoom
59
+ });
60
+ if (!view) return;
61
+ callback(view);
62
+ }
63
+ };
64
+ provide(mapZoomKey, zoomContext);
65
+ let stopBehaviorWatch;
66
+ let stopViewWatch;
67
+ onMounted(() => {
68
+ stopBehaviorWatch = watch(zoomBehavior, (behavior) => {
69
+ if (!container.value) return;
70
+ setupZoom({
71
+ element: container.value,
72
+ behavior
73
+ });
74
+ }, { immediate: true });
75
+ stopViewWatch = watch([
76
+ centerX,
77
+ centerY,
78
+ () => props.zoom,
79
+ () => props.transition,
80
+ zoomBehavior
81
+ ], () => {
82
+ if (!container.value) return;
83
+ applyZoom({
84
+ element: container.value,
85
+ behavior: zoomBehavior.value,
86
+ center: props.center,
87
+ zoom: props.zoom,
88
+ transition: props.transition
89
+ });
90
+ }, { immediate: true });
91
+ });
92
+ onUnmounted(() => {
93
+ stopBehaviorWatch?.();
94
+ stopViewWatch?.();
95
+ });
96
+ return {
97
+ zoomBehavior,
98
+ zoomContext
99
+ };
100
+ }
101
+ function useMapZoom() {
102
+ const zoomContext = inject(mapZoomKey, void 0);
103
+ const mapContext = inject(mapContextKey, void 0);
104
+ if (!zoomContext) return void 0;
105
+ return {
106
+ ...zoomContext,
107
+ zoomToObject: (object, callback) => {
108
+ if (!mapContext?.value) return;
109
+ const view = getObjectZoomView(mapContext.value, object, {
110
+ minZoom: zoomContext.minZoom.value,
111
+ maxZoom: zoomContext.maxZoom.value
112
+ });
113
+ if (!view) return;
114
+ callback(view);
115
+ }
116
+ };
33
117
  }
34
118
 
35
119
  //#endregion
36
120
  //#region src/hooks/useMapObject.ts
37
121
  function useMapObject(styles) {
38
122
  const state = ref("default");
39
- const { onMouseenter, onMouseleave, onMouseup, onMousedown, dispose } = useMapObjectEvents((nextState) => {
123
+ const { onMouseenter, onMouseleave, onMouseup, onMousedown, onFocus, onBlur, dispose } = useMapObjectEvents((nextState) => {
40
124
  state.value = nextState;
41
- }, useInsideZoom());
125
+ }, Boolean(useMapZoom()));
42
126
  onBeforeUnmount(() => {
43
127
  dispose();
44
128
  });
@@ -47,17 +131,20 @@ function useMapObject(styles) {
47
131
  onMouseenter,
48
132
  onMouseleave,
49
133
  onMousedown,
50
- onMouseup
134
+ onMouseup,
135
+ onFocus,
136
+ onBlur
51
137
  };
52
138
  }
53
139
 
54
140
  //#endregion
55
141
  //#region src/components/MapLine.vue?vue&type=script&setup=true&lang.ts
56
- const _hoisted_1$7 = ["d"];
142
+ const _hoisted_1$7 = ["d", "fill"];
57
143
  var MapLine_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
58
144
  inheritAttrs: false,
59
145
  __name: "MapLine",
60
146
  props: {
147
+ styles: {},
61
148
  coordinates: {},
62
149
  cartesian: {
63
150
  type: Boolean,
@@ -68,15 +155,14 @@ var MapLine_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
68
155
  default: false
69
156
  },
70
157
  curve: {},
71
- midpoint: {},
72
- styles: {}
158
+ midpoint: {}
73
159
  },
74
160
  setup(__props) {
75
161
  const props = __props;
76
162
  const attrs = useAttrs();
77
163
  const context = useMapContext();
78
164
  const path = computed(() => {
79
- return getLinePath(context?.value, {
165
+ return getLinePath(context.value, {
80
166
  coordinates: props.coordinates,
81
167
  custom: props.custom,
82
168
  curve: props.curve,
@@ -85,6 +171,7 @@ var MapLine_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
85
171
  });
86
172
  });
87
173
  const pathName = computed(() => attrs.name ?? "line");
174
+ const fill = computed(() => attrs.fill ?? "none");
88
175
  const { style, ...events } = useMapObject(toRef(props, "styles"));
89
176
  const pathAttrs = computed(() => ({
90
177
  ...attrs,
@@ -94,7 +181,7 @@ var MapLine_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
94
181
  return (_ctx, _cache) => {
95
182
  return openBlock(), createElementBlock("path", mergeProps(pathAttrs.value, {
96
183
  d: path.value,
97
- fill: "none",
184
+ fill: fill.value,
98
185
  style: unref(style)
99
186
  }), null, 16, _hoisted_1$7);
100
187
  };
@@ -118,7 +205,9 @@ var MapMarker_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
118
205
  setup(__props) {
119
206
  const props = __props;
120
207
  const context = useMapContext();
121
- const transform = computed(() => getMarkerTransform(context?.value, props.coordinates));
208
+ const transform = computed(() => {
209
+ return getMarkerTransform(context.value, props.coordinates);
210
+ });
122
211
  const { style, ...events } = useMapObject(toRef(props, "styles"));
123
212
  return (_ctx, _cache) => {
124
213
  return transform.value ? (openBlock(), createElementBlock("g", mergeProps({
@@ -190,6 +279,18 @@ var MapAnnotation_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
190
279
  //#region src/components/MapAnnotation.vue
191
280
  var MapAnnotation_default = MapAnnotation_vue_vue_type_script_setup_true_lang_default;
192
281
 
282
+ //#endregion
283
+ //#region src/hooks/useCreateMapContext.ts
284
+ function useCreateMapContext(config, context) {
285
+ return computed(() => {
286
+ const resolvedContext = unref(context);
287
+ if (resolvedContext) return resolvedContext;
288
+ const resolvedConfig = unref(config);
289
+ if (!resolvedConfig?.data) return void 0;
290
+ return makeMapContext(resolvedConfig);
291
+ });
292
+ }
293
+
193
294
  //#endregion
194
295
  //#region src/components/MapBase.vue?vue&type=script&setup=true&lang.ts
195
296
  const _hoisted_1$4 = ["viewBox"];
@@ -202,19 +303,16 @@ var MapBase_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
202
303
  projection: { type: Function },
203
304
  projectionConfig: {},
204
305
  data: {},
205
- dataTransformer: { type: Function }
306
+ dataTransformer: { type: Function },
307
+ context: {}
206
308
  },
207
309
  setup(__props) {
208
310
  const props = __props;
209
- const context = computed(() => makeMapContext({
210
- width: props.width,
211
- height: props.height,
212
- aspectRatio: props.aspectRatio,
213
- projection: props.projection,
214
- projectionConfig: props.projectionConfig,
215
- data: props.data,
216
- dataTransformer: props.dataTransformer
217
- }));
311
+ const unresolvedContext = useCreateMapContext(props, toRef(props, "context"));
312
+ const context = computed(() => {
313
+ if (!unresolvedContext.value) throw new Error("Map requires data or context");
314
+ return unresolvedContext.value;
315
+ });
218
316
  provide(mapContextKey, context);
219
317
  return (_ctx, _cache) => {
220
318
  return openBlock(), createElementBlock("svg", mergeProps({ viewBox: `0 0 ${context.value.width} ${context.value.height}` }, _ctx.$attrs, { class: "d3-map" }), [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(context.value)))], 16, _hoisted_1$4);
@@ -239,7 +337,7 @@ var MapFeature_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
239
337
  const props = __props;
240
338
  const { style, ...events } = useMapObject(toRef(props, "styles"));
241
339
  const context = useMapContext();
242
- const path = computed(() => context?.value.path(props.data) ?? void 0);
340
+ const path = computed(() => context.value.path(props.data) ?? void 0);
243
341
  return (_ctx, _cache) => {
244
342
  return openBlock(), createElementBlock("path", mergeProps({
245
343
  d: path.value,
@@ -264,7 +362,7 @@ var MapFeatures_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ de
264
362
  },
265
363
  setup(__props) {
266
364
  const context = useMapContext();
267
- const features = computed(() => context?.value.features ?? []);
365
+ const features = computed(() => context.value.features);
268
366
  return (_ctx, _cache) => {
269
367
  return openBlock(), createElementBlock("g", _hoisted_1$2, [renderSlot(_ctx.$slots, "default", { features: features.value }, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(features.value, (feature, index) => {
270
368
  return openBlock(), createBlock(MapFeature_default, {
@@ -300,11 +398,9 @@ var MapGraticule_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
300
398
  const context = useMapContext();
301
399
  const attrs = useAttrs();
302
400
  const graticulePath = computed(() => {
303
- if (!context?.value) return void 0;
304
401
  return renderGraticule(context.value, props.config) ?? void 0;
305
402
  });
306
403
  const outlinePath = computed(() => {
307
- if (!context?.value) return void 0;
308
404
  return renderOutline(context.value) ?? void 0;
309
405
  });
310
406
  const backgroundColor = computed(() => isString(props.background) ? props.background : void 0);
@@ -350,7 +446,7 @@ var MapMesh_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
350
446
  setup(__props) {
351
447
  const props = __props;
352
448
  const context = useMapContext();
353
- const path = computed(() => context?.value.renderMesh() ?? void 0);
449
+ const path = computed(() => context.value.renderMesh() ?? void 0);
354
450
  const { style, ...events } = useMapObject(toRef(props, "styles"));
355
451
  return (_ctx, _cache) => {
356
452
  return openBlock(), createElementBlock("path", mergeProps({
@@ -371,60 +467,38 @@ var MapMesh_default = MapMesh_vue_vue_type_script_setup_true_lang_default;
371
467
  var MapZoom_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
372
468
  __name: "MapZoom",
373
469
  props: {
374
- center: { default: () => [0, 0] },
470
+ center: {},
375
471
  zoom: { default: 1 },
376
472
  minZoom: { default: 1 },
377
473
  maxZoom: { default: 8 },
474
+ transition: {},
378
475
  config: {}
379
476
  },
380
477
  emits: [
381
- "zoomstart",
478
+ "zoomStart",
382
479
  "zoom",
383
- "zoomend"
480
+ "zoomEnd",
481
+ "update:center",
482
+ "update:zoom"
384
483
  ],
385
484
  setup(__props, { expose: __expose, emit: __emit }) {
386
485
  const props = __props;
387
486
  const emit = __emit;
388
487
  const container = ref(null);
389
488
  const context = useMapContext();
390
- provide(insideZoomKey, true);
391
- const zoomBehavior = computed(() => {
392
- return createZoomBehavior(context?.value, {
393
- minZoom: props.minZoom,
394
- maxZoom: props.maxZoom,
395
- config: props.config,
396
- onZoomStart: (event) => emit("zoomstart", event),
397
- onZoom: (event) => {
398
- applyZoomGroupTransform(container.value, event.transform);
399
- emit("zoom", event);
400
- },
401
- onZoomEnd: (event) => emit("zoomend", event)
402
- });
403
- });
404
- onMounted(() => {
405
- watch(zoomBehavior, (behavior) => {
406
- if (!container.value) return;
407
- setupZoom({
408
- element: container.value,
409
- behavior,
410
- center: props.center,
411
- zoom: props.zoom
412
- });
413
- }, { immediate: true });
414
- watch(() => [
415
- zoomBehavior.value,
416
- props.center[0],
417
- props.center[1],
418
- props.zoom
419
- ], () => {
420
- if (!container.value) return;
421
- applyZoomTransform({
422
- element: container.value,
423
- behavior: zoomBehavior.value,
424
- center: props.center,
425
- zoom: props.zoom
426
- });
427
- });
489
+ function isSameCenter(nextCenter, currentCenter) {
490
+ return Boolean(currentCenter && nextCenter[0] === currentCenter[0] && nextCenter[1] === currentCenter[1]);
491
+ }
492
+ const { zoomBehavior } = useCreateMapZoom(container, props, {
493
+ onZoomStart: (event) => emit("zoomStart", event),
494
+ onZoom: (event) => {
495
+ const nextCenter = getZoomViewportCenter(context.value, event.transform);
496
+ const nextZoom = event.transform.k;
497
+ if (!isSameCenter(nextCenter, props.center)) emit("update:center", nextCenter);
498
+ if (nextZoom !== props.zoom) emit("update:zoom", nextZoom);
499
+ emit("zoom", event);
500
+ },
501
+ onZoomEnd: (event) => emit("zoomEnd", event)
428
502
  });
429
503
  __expose({
430
504
  container,
@@ -470,4 +544,4 @@ const plugin = { install(app) {
470
544
  } };
471
545
 
472
546
  //#endregion
473
- export { MapAnnotation_default as MapAnnotation, MapBase_default as MapBase, MapFeature_default as MapFeature, MapFeatures_default as MapFeatures, MapGraticule_default as MapGraticule, MapLine_default as MapLine, MapMarker_default as MapMarker, MapMesh_default as MapMesh, MapZoom_default as MapZoom, mapContextKey, plugin, useMapContext, useMapObject };
547
+ export { MapAnnotation_default as MapAnnotation, MapBase_default as MapBase, MapFeature_default as MapFeature, MapFeatures_default as MapFeatures, MapGraticule_default as MapGraticule, MapLine_default as MapLine, MapMarker_default as MapMarker, MapMesh_default as MapMesh, MapZoom_default as MapZoom, mapContextKey, mapZoomKey, plugin, useCreateMapContext, useCreateMapZoom, useMapContext, useMapObject, useMapZoom };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@d3-maps/vue",
3
3
  "type": "module",
4
- "version": "0.8.0",
4
+ "version": "0.9.0",
5
5
  "private": false,
6
6
  "description": "Vue bindings for @d3-maps/core to build reactive D3 SVG maps",
7
7
  "author": "Georgii Bukharov <souljorje@gmail.com>",
@@ -44,7 +44,7 @@
44
44
  "vue": "3.5.25"
45
45
  },
46
46
  "dependencies": {
47
- "@d3-maps/core": "0.8.0"
47
+ "@d3-maps/core": "0.9.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/geojson": "^7946.0.16",