@d3-maps/react 0.1.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 ADDED
@@ -0,0 +1,54 @@
1
+ # @d3-maps/react
2
+
3
+ `@d3-maps/react` provides React bindings for `@d3-maps/core` to build SVG maps with React, [d3](https://github.com/d3/d3) and [TopoJSON-client](https://github.com/TopoJSON/TopoJSON-client).
4
+
5
+ [docs](https://souljorje.github.io/d3-maps)
6
+
7
+ ## Installation
8
+
9
+ Requires React 19+
10
+
11
+ Next.js App Router: `@d3-maps/react` entrypoints are client-only (`'use client'`), so import them from Client Components
12
+ React Server Components entrypoints are planned
13
+
14
+ npm
15
+
16
+ ```bash
17
+ npm install @d3-maps/react
18
+ ```
19
+
20
+ pnpm
21
+
22
+ ```bash
23
+ pnpm add @d3-maps/react
24
+ ```
25
+
26
+ bun
27
+
28
+ ```bash
29
+ bun add @d3-maps/react
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ```tsx
35
+ import { Map, MapFeatures } from '@d3-maps/react'
36
+
37
+ export function App({ mapData }: { mapData: unknown }) {
38
+ return (
39
+ <Map data={mapData}>
40
+ <MapFeatures />
41
+ </Map>
42
+ )
43
+ }
44
+ ```
45
+
46
+ ## Styling
47
+
48
+ Importing `@d3-maps/react` automatically includes `@d3-maps/core/index.css`
49
+
50
+ If you need strict stylesheet ordering, load your global reset/theme styles before importing the adapter entry
51
+
52
+ ## License
53
+
54
+ MIT licensed. Copyright © 2020 Georgii Bukharov. See [LICENCE](../../LICENCE) for more details.
@@ -0,0 +1,599 @@
1
+ import "@d3-maps/core/index.css";
2
+ import * as react0 from "react";
3
+ import { CSSProperties, FocusEventHandler, MouseEventHandler, ReactElement, ReactNode, SVGProps } from "react";
4
+ import { ExtendedFeature, ExtendedFeatureCollection, GeoPath, GeoProjection } from "d3-geo";
5
+ import { mesh } from "topojson-client";
6
+ import { D3ZoomEvent, ZoomBehavior } from "d3-zoom";
7
+
8
+ //#region ../core/src/lib/mapObject.d.ts
9
+
10
+ /**
11
+ * Supported interaction states for map objects.
12
+ */
13
+ declare const mapObjectState: readonly ["default", "hover", "active"];
14
+ type MapObjectState = typeof mapObjectState[number];
15
+ type MapObjectStyles$1<TStyle> = Partial<Record<MapObjectState, TStyle>>;
16
+ //#endregion
17
+ //#region ../core/src/lib/feature.d.ts
18
+ /**
19
+ * A GeoJSON Feature used by d3-maps.
20
+ *
21
+ * This type allows extra top-level fields to be attached in `dataTransformer` (e.g. choropleth colors).
22
+ */
23
+ type MapFeature$1 = (ExtendedFeature & Record<string, unknown>) | ExtendedFeature;
24
+ /**
25
+ * Shared props contract for a single rendered feature.
26
+ */
27
+ interface MapFeatureProps$1<TStyle = unknown> {
28
+ data: MapFeature$1;
29
+ styles?: MapObjectStyles$1<TStyle>;
30
+ fill?: string;
31
+ stroke?: string;
32
+ }
33
+ //#endregion
34
+ //#region ../../node_modules/.pnpm/@types+geojson@7946.0.16/node_modules/@types/geojson/index.d.ts
35
+ /**
36
+ * The valid values for the "type" property of GeoJSON geometry objects.
37
+ * https://tools.ietf.org/html/rfc7946#section-1.4
38
+ */
39
+ type GeoJsonGeometryTypes = Geometry["type"];
40
+ /**
41
+ * The value values for the "type" property of GeoJSON Objects.
42
+ * https://tools.ietf.org/html/rfc7946#section-1.4
43
+ */
44
+ type GeoJsonTypes = GeoJSON["type"];
45
+ /**
46
+ * Bounding box
47
+ * https://tools.ietf.org/html/rfc7946#section-5
48
+ */
49
+ type BBox = [number, number, number, number] | [number, number, number, number, number, number];
50
+ /**
51
+ * A Position is an array of coordinates.
52
+ * https://tools.ietf.org/html/rfc7946#section-3.1.1
53
+ * Array should contain between two and three elements.
54
+ * The previous GeoJSON specification allowed more elements (e.g., which could be used to represent M values),
55
+ * but the current specification only allows X, Y, and (optionally) Z to be defined.
56
+ *
57
+ * Note: the type will not be narrowed down to `[number, number] | [number, number, number]` due to
58
+ * marginal benefits and the large impact of breaking change.
59
+ *
60
+ * See previous discussions on the type narrowing:
61
+ * - {@link https://github.com/DefinitelyTyped/DefinitelyTyped/pull/21590|Nov 2017}
62
+ * - {@link https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/67773|Dec 2023}
63
+ * - {@link https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/71441| Dec 2024}
64
+ *
65
+ * One can use a
66
+ * {@link https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates|user-defined type guard that returns a type predicate}
67
+ * to determine if a position is a 2D or 3D position.
68
+ *
69
+ * @example
70
+ * import type { Position } from 'geojson';
71
+ *
72
+ * type StrictPosition = [x: number, y: number] | [x: number, y: number, z: number]
73
+ *
74
+ * function isStrictPosition(position: Position): position is StrictPosition {
75
+ * return position.length === 2 || position.length === 3
76
+ * };
77
+ *
78
+ * let position: Position = [-116.91, 45.54];
79
+ *
80
+ * let x: number;
81
+ * let y: number;
82
+ * let z: number | undefined;
83
+ *
84
+ * if (isStrictPosition(position)) {
85
+ * // `tsc` would throw an error if we tried to destructure a fourth parameter
86
+ * [x, y, z] = position;
87
+ * } else {
88
+ * throw new TypeError("Position is not a 2D or 3D point");
89
+ * }
90
+ */
91
+ type Position = number[];
92
+ /**
93
+ * The base GeoJSON object.
94
+ * https://tools.ietf.org/html/rfc7946#section-3
95
+ * The GeoJSON specification also allows foreign members
96
+ * (https://tools.ietf.org/html/rfc7946#section-6.1)
97
+ * Developers should use "&" type in TypeScript or extend the interface
98
+ * to add these foreign members.
99
+ */
100
+ interface GeoJsonObject {
101
+ // Don't include foreign members directly into this type def.
102
+ // in order to preserve type safety.
103
+ // [key: string]: any;
104
+ /**
105
+ * Specifies the type of GeoJSON object.
106
+ */
107
+ type: GeoJsonTypes;
108
+ /**
109
+ * Bounding box of the coordinate range of the object's Geometries, Features, or Feature Collections.
110
+ * The value of the bbox member is an array of length 2*n where n is the number of dimensions
111
+ * represented in the contained geometries, with all axes of the most southwesterly point
112
+ * followed by all axes of the more northeasterly point.
113
+ * The axes order of a bbox follows the axes order of geometries.
114
+ * https://tools.ietf.org/html/rfc7946#section-5
115
+ */
116
+ bbox?: BBox | undefined;
117
+ }
118
+ /**
119
+ * Union of GeoJSON objects.
120
+ */
121
+ type GeoJSON<G extends Geometry | null = Geometry, P$1 = GeoJsonProperties> = G | Feature<G, P$1> | FeatureCollection<G, P$1>;
122
+ /**
123
+ * Geometry object.
124
+ * https://tools.ietf.org/html/rfc7946#section-3
125
+ */
126
+ type Geometry = Point$1 | MultiPoint$1 | LineString$1 | MultiLineString$1 | Polygon$1 | MultiPolygon$1 | GeometryCollection$1;
127
+ /**
128
+ * Point geometry object.
129
+ * https://tools.ietf.org/html/rfc7946#section-3.1.2
130
+ */
131
+ interface Point$1 extends GeoJsonObject {
132
+ type: "Point";
133
+ coordinates: Position;
134
+ }
135
+ /**
136
+ * MultiPoint geometry object.
137
+ * https://tools.ietf.org/html/rfc7946#section-3.1.3
138
+ */
139
+ interface MultiPoint$1 extends GeoJsonObject {
140
+ type: "MultiPoint";
141
+ coordinates: Position[];
142
+ }
143
+ /**
144
+ * LineString geometry object.
145
+ * https://tools.ietf.org/html/rfc7946#section-3.1.4
146
+ */
147
+ interface LineString$1 extends GeoJsonObject {
148
+ type: "LineString";
149
+ coordinates: Position[];
150
+ }
151
+ /**
152
+ * MultiLineString geometry object.
153
+ * https://tools.ietf.org/html/rfc7946#section-3.1.5
154
+ */
155
+ interface MultiLineString$1 extends GeoJsonObject {
156
+ type: "MultiLineString";
157
+ coordinates: Position[][];
158
+ }
159
+ /**
160
+ * Polygon geometry object.
161
+ * https://tools.ietf.org/html/rfc7946#section-3.1.6
162
+ */
163
+ interface Polygon$1 extends GeoJsonObject {
164
+ type: "Polygon";
165
+ coordinates: Position[][];
166
+ }
167
+ /**
168
+ * MultiPolygon geometry object.
169
+ * https://tools.ietf.org/html/rfc7946#section-3.1.7
170
+ */
171
+ interface MultiPolygon$1 extends GeoJsonObject {
172
+ type: "MultiPolygon";
173
+ coordinates: Position[][][];
174
+ }
175
+ /**
176
+ * Geometry Collection
177
+ * https://tools.ietf.org/html/rfc7946#section-3.1.8
178
+ */
179
+ interface GeometryCollection$1<G extends Geometry = Geometry> extends GeoJsonObject {
180
+ type: "GeometryCollection";
181
+ geometries: G[];
182
+ }
183
+ type GeoJsonProperties = {
184
+ [name: string]: any;
185
+ } | null;
186
+ /**
187
+ * A feature object which contains a geometry and associated properties.
188
+ * https://tools.ietf.org/html/rfc7946#section-3.2
189
+ */
190
+ interface Feature<G extends Geometry | null = Geometry, P$1 = GeoJsonProperties> extends GeoJsonObject {
191
+ type: "Feature";
192
+ /**
193
+ * The feature's geometry
194
+ */
195
+ geometry: G;
196
+ /**
197
+ * A value that uniquely identifies this feature in a
198
+ * https://tools.ietf.org/html/rfc7946#section-3.2.
199
+ */
200
+ id?: string | number | undefined;
201
+ /**
202
+ * Properties associated with this feature.
203
+ */
204
+ properties: P$1;
205
+ }
206
+ /**
207
+ * A collection of feature objects.
208
+ * https://tools.ietf.org/html/rfc7946#section-3.3
209
+ */
210
+ interface FeatureCollection<G extends Geometry | null = Geometry, P$1 = GeoJsonProperties> extends GeoJsonObject {
211
+ type: "FeatureCollection";
212
+ features: Array<Feature<G, P$1>>;
213
+ }
214
+ //#endregion
215
+ //#region ../../node_modules/.pnpm/@types+topojson-specification@1.0.5/node_modules/@types/topojson-specification/index.d.ts
216
+ // ---------------------------------------------------------------
217
+ // TopoJSON Format Specification
218
+ // ---------------------------------------------------------------
219
+
220
+ // See: https://github.com/topojson/topojson-specification/
221
+
222
+ // 2. TopoJSON Objects
223
+ interface TopoJSON {
224
+ type: "Topology" | GeoJsonGeometryTypes | null;
225
+ bbox?: BBox | undefined;
226
+ }
227
+ // 2.1. Topology Objects
228
+ interface Topology<T extends Objects<Properties> = Objects<Properties>> extends TopoJSON {
229
+ type: "Topology";
230
+ objects: T;
231
+ arcs: Arc[];
232
+ transform?: Transform | undefined;
233
+ }
234
+ // 2.1.1. Positions
235
+ type Positions = number[];
236
+ // at least two elements
237
+
238
+ // 2.1.2. Transforms
239
+ interface Transform {
240
+ scale: [number, number];
241
+ translate: [number, number];
242
+ }
243
+ // 2.1.3. Arcs
244
+ type Arc = Positions[];
245
+ // at least two elements
246
+
247
+ // 2.1.4. Arc Indexes
248
+ type ArcIndexes = number[];
249
+ // 2.1.5. Objects
250
+ type Properties = GeoJsonProperties;
251
+ interface Objects<P$1 extends Properties = {}> {
252
+ [key: string]: GeometryObject<P$1>;
253
+ }
254
+ // 2.2. Geometry Objects
255
+ interface GeometryObjectA<P$1 extends Properties = {}> extends TopoJSON {
256
+ type: GeoJsonGeometryTypes | null;
257
+ id?: number | string | undefined;
258
+ properties?: P$1 | undefined;
259
+ }
260
+ type GeometryObject<P$1 extends Properties = {}> = Point<P$1> | MultiPoint<P$1> | LineString<P$1> | MultiLineString<P$1> | Polygon<P$1> | MultiPolygon<P$1> | GeometryCollection<P$1> | NullObject;
261
+ // 2.2.1. Point
262
+ interface Point<P$1 extends Properties = {}> extends GeometryObjectA<P$1> {
263
+ type: "Point";
264
+ coordinates: Positions;
265
+ }
266
+ // 2.2.2. MultiPoint
267
+ interface MultiPoint<P$1 extends Properties = {}> extends GeometryObjectA<P$1> {
268
+ type: "MultiPoint";
269
+ coordinates: Positions[];
270
+ }
271
+ // 2.2.3. LineString
272
+ interface LineString<P$1 extends Properties = {}> extends GeometryObjectA<P$1> {
273
+ type: "LineString";
274
+ arcs: ArcIndexes;
275
+ }
276
+ // 2.2.4. MultiLineString
277
+ interface MultiLineString<P$1 extends Properties = {}> extends GeometryObjectA<P$1> {
278
+ type: "MultiLineString";
279
+ arcs: ArcIndexes[];
280
+ }
281
+ // 2.2.5. Polygon
282
+ interface Polygon<P$1 extends Properties = {}> extends GeometryObjectA<P$1> {
283
+ type: "Polygon";
284
+ arcs: ArcIndexes[];
285
+ }
286
+ // 2.2.6. MultiPolygon
287
+ interface MultiPolygon<P$1 extends Properties = {}> extends GeometryObjectA<P$1> {
288
+ type: "MultiPolygon";
289
+ arcs: ArcIndexes[][];
290
+ }
291
+ // 2.2.7. Geometry Collection
292
+ interface GeometryCollection<P$1 extends Properties = {}> extends GeometryObjectA<P$1> {
293
+ type: "GeometryCollection";
294
+ geometries: Array<GeometryObject<P$1>>;
295
+ }
296
+ // More
297
+ interface NullObject extends GeometryObjectA {
298
+ type: null;
299
+ }
300
+ //#endregion
301
+ //#region ../core/src/lib/utils.d.ts
302
+ type AnyFn = (...args: any) => any;
303
+ /**
304
+ * Extracts a union of parameter tuples from a (possibly overloaded) function type.
305
+ *
306
+ * TypeScript's built-in `Parameters<F>` only captures the *last* overload, which breaks typing
307
+ * for overloaded getter/setter APIs (common in d3), where the setter overload might not be last.
308
+ *
309
+ * Notes:
310
+ * - This helper supports up to 5 overload signatures (adjust if needed).
311
+ * - Getter overloads like `(): T` are filtered out later via `Exclude<..., []>` when we build
312
+ * setter-only config types.
313
+ */
314
+ type OverloadedArgs<F> = F extends {
315
+ (...a: infer A1): any;
316
+ (...a: infer A2): any;
317
+ (...a: infer A3): any;
318
+ (...a: infer A4): any;
319
+ (...a: infer A5): any;
320
+ } ? A1 | A2 | A3 | A4 | A5 : F extends {
321
+ (...a: infer A1): any;
322
+ (...a: infer A2): any;
323
+ (...a: infer A3): any;
324
+ (...a: infer A4): any;
325
+ } ? A1 | A2 | A3 | A4 : F extends {
326
+ (...a: infer A1): any;
327
+ (...a: infer A2): any;
328
+ (...a: infer A3): any;
329
+ } ? A1 | A2 | A3 : F extends {
330
+ (...a: infer A1): any;
331
+ (...a: infer A2): any;
332
+ } ? A1 | A2 : F extends ((...a: infer A1) => any) ? A1 : never;
333
+ /**
334
+ * Removes 0-arg overloads (getters), leaving only setter-style overload argument tuples.
335
+ */
336
+ type SetterArgs<F> = Exclude<OverloadedArgs<F>, []>;
337
+ /**
338
+ * True if the function has at least one overload that accepts arguments (i.e. a setter overload).
339
+ */
340
+ type HasArgs<F> = [SetterArgs<F>] extends [never] ? false : true;
341
+ type OwnKeys<T> = T extends AnyFn ? Exclude<keyof T, keyof CallableFunction> : keyof T;
342
+ /**
343
+ * Converts method parameters to modifiers values
344
+ * - single non-array arg: `arg` | `[arg]`
345
+ * - multiple args/single array wrapped with array
346
+ */
347
+ type ModifierArgs<P$1 extends unknown[]> = P$1 extends [infer Only] ? Only extends readonly unknown[] ? [Only] : Only | [Only] : P$1;
348
+ /**
349
+ * Maps methods with args to modifiers
350
+ *
351
+ * @example
352
+ * type X = {
353
+ * a: string; // not a function - will be ignored
354
+ * b(): void; // has no arguments - will be ignored
355
+ * c(x: number): void;
356
+ * d(x: number, y: string): void;
357
+ * e(xs: string[]): void;
358
+ * }
359
+ *
360
+ * type R = MethodsToModifiers<X>
361
+ * {
362
+ * c: number | [number];
363
+ * d: [number, string];
364
+ * e: [string[]]; // forced wrapper (arg is array)
365
+ * }
366
+ */
367
+ type MethodsToModifiers<T extends object> = { [K in OwnKeys<T> as Extract<T[K], AnyFn> extends never ? never : HasArgs<Extract<T[K], AnyFn>> extends true ? K : never]?: ModifierArgs<Extract<SetterArgs<Extract<T[K], AnyFn>>, unknown[]>> };
368
+ //#endregion
369
+ //#region ../core/src/lib/map.d.ts
370
+ type MapMesh$1 = ReturnType<typeof mesh>;
371
+ type MapData = ExtendedFeatureCollection | Topology;
372
+ type DataTransformer = (features: MapFeature$1[]) => MapFeature$1[];
373
+ /**
374
+ * Extra projection method calls to apply before rendering.
375
+ *
376
+ * Use projection method names as keys and method arguments as values.
377
+ * Example: `{ center: [[0, 20]], rotate: [[0, 0, 0]], scale: 160 }`
378
+ *
379
+ * @see https://d3js.org/d3-geo/projection
380
+ */
381
+ interface ProjectionConfig extends Omit<MethodsToModifiers<GeoProjection>, 'invert' | 'stream'> {}
382
+ /**
383
+ * Input configuration for creating a map context.
384
+ *
385
+ * In adapters, this is usually passed as component props.
386
+ */
387
+ interface MapConfig {
388
+ width?: number;
389
+ height?: number;
390
+ aspectRatio?: number;
391
+ /**
392
+ * Projection factory from d3-geo (or a compatible implementation).
393
+ *
394
+ * Example: `geoNaturalEarth1`.
395
+ */
396
+ projection?: () => GeoProjection;
397
+ /**
398
+ * Projection method arguments passed to the created projection
399
+ */
400
+ projectionConfig?: ProjectionConfig;
401
+ /**
402
+ * TopoJSON or GeoJSON input.
403
+ *
404
+ * TopoJSON is automatically converted to GeoJSON features.
405
+ */
406
+ data: MapData;
407
+ /**
408
+ * Optional feature transformer (filter/augment/normalize features).
409
+ */
410
+ dataTransformer?: DataTransformer;
411
+ }
412
+ /**
413
+ * Fully computed, framework-agnostic map context.
414
+ *
415
+ * Adapters provide this context to child layers (features, markers, custom SVG).
416
+ */
417
+ interface MapContext {
418
+ width: number;
419
+ height: number;
420
+ projection?: GeoProjection;
421
+ features: MapFeature$1[];
422
+ mesh?: MapMesh$1;
423
+ path: GeoPath;
424
+ renderPath: (feature: MapFeature$1) => ReturnType<GeoPath>;
425
+ renderMesh: () => ReturnType<GeoPath>;
426
+ }
427
+ //#endregion
428
+ //#region ../core/src/lib/marker.d.ts
429
+ type MapMarkerCoordinates = [number, number];
430
+ /**
431
+ * Shared props contract for marker layers.
432
+ */
433
+ interface MapMarkerProps$1<TStyle = unknown> {
434
+ coordinates?: MapMarkerCoordinates;
435
+ styles?: MapObjectStyles$1<TStyle>;
436
+ }
437
+ //#endregion
438
+ //#region ../core/src/lib/zoom.d.ts
439
+ interface DefaultZoomBehavior extends ZoomBehavior<SVGSVGElement, unknown> {}
440
+ /**
441
+ * Extra zoom method calls to apply before rendering.
442
+ *
443
+ * Use zoom method names as keys and method arguments as values.
444
+ * Example: `{ scaleExtent: [[2, 9]], translateExtent: [[[0, 0], [10, 10]]] }`
445
+ *
446
+ * @see https://d3js.org/d3-zoom
447
+ */
448
+ interface ZoomModifiers extends MethodsToModifiers<DefaultZoomBehavior> {}
449
+ interface ZoomProps {
450
+ center?: [number, number];
451
+ zoom?: number;
452
+ minZoom?: number;
453
+ maxZoom?: number;
454
+ config?: ZoomModifiers;
455
+ }
456
+ interface ZoomEvent extends D3ZoomEvent<SVGSVGElement, unknown> {}
457
+ //#endregion
458
+ //#region src/components/Map.d.ts
459
+ type MapRenderProp = (context: MapContext) => ReactNode;
460
+ interface MapProps extends MapConfig, Omit<SVGProps<SVGSVGElement>, keyof MapConfig | 'children'> {
461
+ children?: ReactNode | MapRenderProp;
462
+ }
463
+ declare function Map({
464
+ width,
465
+ height,
466
+ aspectRatio,
467
+ projection,
468
+ projectionConfig,
469
+ data,
470
+ dataTransformer,
471
+ children,
472
+ className,
473
+ ...svgProps
474
+ }: MapProps): ReactElement;
475
+ //#endregion
476
+ //#region src/components/MapFeature.d.ts
477
+ interface MapFeatureProps extends MapFeatureProps$1<CSSProperties>, Omit<SVGProps<SVGPathElement>, 'children' | 'd' | 'style'> {}
478
+ declare function MapFeature({
479
+ data,
480
+ styles,
481
+ fill,
482
+ stroke,
483
+ onMouseEnter,
484
+ onMouseLeave,
485
+ onMouseDown,
486
+ onMouseUp,
487
+ onClick,
488
+ onFocus,
489
+ onBlur,
490
+ ...pathProps
491
+ }: MapFeatureProps): ReactElement | null;
492
+ //#endregion
493
+ //#region src/hooks/useMapObject.d.ts
494
+ type MapObjectStyle = CSSProperties;
495
+ type MapObjectStyles = MapObjectStyles$1<MapObjectStyle>;
496
+ interface UseMapObjectOptions<TElement extends Element> {
497
+ styles?: MapObjectStyles;
498
+ onMouseEnter?: MouseEventHandler<TElement>;
499
+ onMouseLeave?: MouseEventHandler<TElement>;
500
+ onMouseDown?: MouseEventHandler<TElement>;
501
+ onMouseUp?: MouseEventHandler<TElement>;
502
+ onClick?: MouseEventHandler<TElement>;
503
+ onFocus?: FocusEventHandler<TElement>;
504
+ onBlur?: FocusEventHandler<TElement>;
505
+ }
506
+ interface UseMapObjectResult<TElement extends Element> {
507
+ computedStyle: MapObjectStyle | undefined;
508
+ onMouseEnter: MouseEventHandler<TElement>;
509
+ onMouseLeave: MouseEventHandler<TElement>;
510
+ onMouseDown: MouseEventHandler<TElement>;
511
+ onMouseUp: MouseEventHandler<TElement>;
512
+ onClick: MouseEventHandler<TElement>;
513
+ onFocus: FocusEventHandler<TElement>;
514
+ onBlur: FocusEventHandler<TElement>;
515
+ }
516
+ declare function useMapObject<TElement extends Element>(options: UseMapObjectOptions<TElement>): UseMapObjectResult<TElement>;
517
+ //#endregion
518
+ //#region src/components/MapFeatures.d.ts
519
+ interface MapFeaturesRenderProps {
520
+ features: MapFeature$1[];
521
+ }
522
+ type MapFeaturesChildren = ReactNode | ((props: MapFeaturesRenderProps) => ReactNode);
523
+ interface MapFeaturesProps {
524
+ idKey?: string;
525
+ fill?: string;
526
+ stroke?: string;
527
+ styles?: MapObjectStyles;
528
+ children?: MapFeaturesChildren;
529
+ }
530
+ declare function MapFeatures({
531
+ idKey,
532
+ fill,
533
+ stroke,
534
+ styles,
535
+ children
536
+ }: MapFeaturesProps): ReactElement;
537
+ //#endregion
538
+ //#region src/components/MapMarker.d.ts
539
+ interface MapMarkerProps extends MapMarkerProps$1<CSSProperties>, Omit<SVGProps<SVGGElement>, 'style'> {}
540
+ declare function MapMarker({
541
+ coordinates,
542
+ styles,
543
+ children,
544
+ onMouseEnter,
545
+ onMouseLeave,
546
+ onMouseDown,
547
+ onMouseUp,
548
+ onClick,
549
+ onFocus,
550
+ onBlur,
551
+ ...groupProps
552
+ }: MapMarkerProps): ReactElement;
553
+ //#endregion
554
+ //#region src/components/MapMesh.d.ts
555
+ interface MapMeshProps extends Omit<SVGProps<SVGPathElement>, 'children' | 'd' | 'style'> {
556
+ fill?: string;
557
+ stroke?: string;
558
+ styles?: MapObjectStyles;
559
+ }
560
+ declare function MapMesh({
561
+ fill,
562
+ stroke,
563
+ styles,
564
+ onMouseEnter,
565
+ onMouseLeave,
566
+ onMouseDown,
567
+ onMouseUp,
568
+ onClick,
569
+ onFocus,
570
+ onBlur,
571
+ ...pathProps
572
+ }: MapMeshProps): ReactElement | null;
573
+ //#endregion
574
+ //#region src/components/MapZoom.d.ts
575
+ interface MapZoomProps extends ZoomProps, Omit<SVGProps<SVGGElement>, 'children' | 'onZoom'> {
576
+ children?: ReactNode;
577
+ onZoomStart?: (event: ZoomEvent) => void;
578
+ onZoom?: (event: ZoomEvent) => void;
579
+ onZoomEnd?: (event: ZoomEvent) => void;
580
+ }
581
+ declare function MapZoom({
582
+ center,
583
+ zoom,
584
+ minZoom,
585
+ maxZoom,
586
+ config,
587
+ onZoomStart,
588
+ onZoom,
589
+ onZoomEnd,
590
+ children,
591
+ className,
592
+ ...groupProps
593
+ }: MapZoomProps): ReactElement;
594
+ //#endregion
595
+ //#region src/hooks/useMapContext.d.ts
596
+ declare const MapContextValue: react0.Context<MapContext | undefined>;
597
+ declare function useMapContext(): MapContext | undefined;
598
+ //#endregion
599
+ export { Map, MapContextValue, MapFeature, MapFeatures, MapMarker, MapMesh, MapObjectStyle, MapObjectStyles, MapZoom, UseMapObjectOptions, UseMapObjectResult, useMapContext, useMapObject };
@@ -0,0 +1 @@
1
+ "use client";(function(e,t,n,r,i){let a=(0,r.createContext)(void 0);function o(){return(0,r.useContext)(a)}function s({context:e,children:t}){return(0,i.jsx)(a.Provider,{value:e,children:t})}function c(e){return typeof e==`function`}function l({width:e,height:t,aspectRatio:a,projection:o,projectionConfig:l,data:u,dataTransformer:d,children:f,className:p,...m}){let h=(0,r.useMemo)(()=>(0,n.makeMapContext)({width:e,height:t,aspectRatio:a,projection:o,projectionConfig:l,data:u,dataTransformer:d}),[e,t,a,o,l,u,d]),g=c(f)?f(h):f;return(0,i.jsx)(s,{context:h,children:(0,i.jsx)(`svg`,{...m,className:`d3-map ${p??``}`,viewBox:`0 0 ${h.width} ${h.height}`,children:g})})}function u(e){let t=(0,r.useRef)(e);return t.current=e,t}function d(e){let[t,i]=(0,r.useState)(`default`),a=u(e.onMouseEnter),o=u(e.onMouseLeave),s=u(e.onMouseDown),c=u(e.onMouseUp),l=u(e.onClick),d=u(e.onFocus),f=u(e.onBlur),p=(0,r.useCallback)(e=>{i(t=>{let r=(0,n.getObjectStateUpdate)(e);return t===r?t:r})},[]);return{computedStyle:(0,r.useMemo)(()=>(0,n.resolveObjectStyle)(t,e.styles),[t,e.styles]),onMouseEnter:(0,r.useCallback)(e=>{p(`mouseenter`),a.current?.(e)},[p]),onMouseLeave:(0,r.useCallback)(e=>{p(`mouseleave`),o.current?.(e)},[p]),onMouseDown:(0,r.useCallback)(e=>{p(`mousedown`),s.current?.(e)},[p]),onMouseUp:(0,r.useCallback)(e=>{p(`mouseup`),c.current?.(e)},[p]),onClick:(0,r.useCallback)(e=>{p(`mouseup`),l.current?.(e)},[p]),onFocus:(0,r.useCallback)(e=>{p(`focus`),d.current?.(e)},[p]),onBlur:(0,r.useCallback)(e=>{p(`blur`),f.current?.(e)},[p])}}function f({data:e,styles:t,fill:n,stroke:a,onMouseEnter:s,onMouseLeave:c,onMouseDown:l,onMouseUp:u,onClick:f,onFocus:p,onBlur:m,...h}){let g=o(),_=(0,r.useMemo)(()=>g?.renderPath(e)??null,[g,e]),{computedStyle:v,onMouseEnter:y,onMouseLeave:b,onMouseDown:x,onMouseUp:S,onClick:C,onFocus:w,onBlur:T}=d({styles:t,onMouseEnter:s,onMouseLeave:c,onMouseDown:l,onMouseUp:u,onClick:f,onFocus:p,onBlur:m});return _?(0,i.jsx)(`path`,{...h,d:_,style:v,fill:n,stroke:a,onMouseEnter:y,onMouseLeave:b,onMouseDown:x,onMouseUp:S,onClick:C,onFocus:w,onBlur:T}):null}function p(e){return typeof e==`function`}function m({idKey:e=`id`,fill:t,stroke:r,styles:a,children:s}){let c=o()?.features??[];return(0,i.jsx)(`g`,{children:(p(s)?s({features:c}):s)??c.map((o,s)=>(0,i.jsx)(f,{data:o,fill:t,stroke:r,styles:a},(0,n.getFeatureKey)(o,e,s)))})}let h=[0,0];function g({coordinates:e=h,styles:t,children:a,onMouseEnter:s,onMouseLeave:c,onMouseDown:l,onMouseUp:u,onClick:f,onFocus:p,onBlur:m,...g}){let _=o(),v=(0,r.useMemo)(()=>(0,n.getMarkerTransform)(_,e),[_,e[0],e[1]]),{computedStyle:y,onMouseEnter:b,onMouseLeave:x,onMouseDown:S,onMouseUp:C,onClick:w,onFocus:T,onBlur:E}=d({styles:t,onMouseEnter:s,onMouseLeave:c,onMouseDown:l,onMouseUp:u,onClick:f,onFocus:p,onBlur:m});return(0,i.jsx)(`g`,{...g,transform:v,style:y,onMouseEnter:b,onMouseLeave:x,onMouseDown:S,onMouseUp:C,onClick:w,onFocus:T,onBlur:E,children:a})}function _({fill:e=`none`,stroke:t,styles:n,onMouseEnter:a,onMouseLeave:s,onMouseDown:c,onMouseUp:l,onClick:u,onFocus:f,onBlur:p,...m}){let h=o(),g=(0,r.useMemo)(()=>h?.renderMesh()??null,[h]),{computedStyle:_,onMouseEnter:v,onMouseLeave:y,onMouseDown:b,onMouseUp:x,onClick:S,onFocus:C,onBlur:w}=d({styles:n,onMouseEnter:a,onMouseLeave:s,onMouseDown:c,onMouseUp:l,onClick:u,onFocus:f,onBlur:p});return g?(0,i.jsx)(`path`,{...m,d:g,style:_,fill:e,stroke:t,onMouseEnter:v,onMouseLeave:y,onMouseDown:b,onMouseUp:x,onClick:S,onFocus:C,onBlur:w}):null}function v({center:e,zoom:t,minZoom:a=n.ZOOM_DEFAULTS.minZoom,maxZoom:s=n.ZOOM_DEFAULTS.maxZoom,config:c,onZoomStart:l,onZoom:d,onZoomEnd:f,children:p,className:m,...h}){let g=(0,r.useRef)(null),_=(0,r.useRef)(!1),v=o(),y=u(l),b=u(d),x=u(f),S=e??n.ZOOM_DEFAULTS.center,C=t??n.ZOOM_DEFAULTS.zoom,w=S[0],T=S[1],E=(0,r.useMemo)(()=>(0,n.createZoomBehavior)(v,{minZoom:a,maxZoom:s,config:c,onZoomStart:e=>{y.current?.(e)},onZoom:e=>{(0,n.applyZoomGroupTransform)(g.current,e.transform),b.current?.(e)},onZoomEnd:e=>{x.current?.(e)}}),[v,a,s,c]);(0,r.useEffect)(()=>{_.current=!0,(0,n.setupZoom)({element:g.current,behavior:E,center:S,zoom:C})},[E]),(0,r.useEffect)(()=>{if(_.current){_.current=!1;return}(0,n.applyZoomTransform)({element:g.current,behavior:E,center:[w,T],zoom:C})},[E,w,T,C]);let D=m?`d3-map-zoom ${m}`:`d3-map-zoom`;return(0,i.jsx)(`g`,{...h,ref:g,className:D,children:p})}e.Map=l,e.MapContextValue=a,e.MapFeature=f,e.MapFeatures=m,e.MapMarker=g,e.MapMesh=_,e.MapZoom=v,e.useMapContext=o,e.useMapObject=d})(this.D3Maps=this.D3Maps||{},_d3_maps_core_index_css,D3Maps,React,ReactJSXRuntime);
package/dist/index.js ADDED
@@ -0,0 +1,309 @@
1
+ 'use client';
2
+
3
+ import "@d3-maps/core/index.css";
4
+ import { ZOOM_DEFAULTS, applyZoomGroupTransform, applyZoomTransform, createZoomBehavior, getFeatureKey, getMarkerTransform, getObjectStateUpdate, makeMapContext, resolveObjectStyle, setupZoom } from "@d3-maps/core";
5
+ import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+
8
+ //#region src/hooks/useMapContext.ts
9
+ const MapContextValue = createContext(void 0);
10
+ function useMapContext() {
11
+ return useContext(MapContextValue);
12
+ }
13
+
14
+ //#endregion
15
+ //#region src/components/MapContext.tsx
16
+ function MapProvider({ context, children }) {
17
+ return /* @__PURE__ */ jsx(MapContextValue.Provider, {
18
+ value: context,
19
+ children
20
+ });
21
+ }
22
+
23
+ //#endregion
24
+ //#region src/components/Map.tsx
25
+ function isRenderProp$1(children) {
26
+ return typeof children === "function";
27
+ }
28
+ function Map({ width, height, aspectRatio, projection, projectionConfig, data, dataTransformer, children, className, ...svgProps }) {
29
+ const context = useMemo(() => {
30
+ return makeMapContext({
31
+ width,
32
+ height,
33
+ aspectRatio,
34
+ projection,
35
+ projectionConfig,
36
+ data,
37
+ dataTransformer
38
+ });
39
+ }, [
40
+ width,
41
+ height,
42
+ aspectRatio,
43
+ projection,
44
+ projectionConfig,
45
+ data,
46
+ dataTransformer
47
+ ]);
48
+ const resolvedChildren = isRenderProp$1(children) ? children(context) : children;
49
+ return /* @__PURE__ */ jsx(MapProvider, {
50
+ context,
51
+ children: /* @__PURE__ */ jsx("svg", {
52
+ ...svgProps,
53
+ className: `d3-map ${className ?? ""}`,
54
+ viewBox: `0 0 ${context.width} ${context.height}`,
55
+ children: resolvedChildren
56
+ })
57
+ });
58
+ }
59
+
60
+ //#endregion
61
+ //#region src/hooks/useLatest.ts
62
+ function useLatest(value) {
63
+ const ref = useRef(value);
64
+ ref.current = value;
65
+ return ref;
66
+ }
67
+
68
+ //#endregion
69
+ //#region src/hooks/useMapObject.ts
70
+ function useMapObject(options) {
71
+ const [state, setState] = useState("default");
72
+ const onMouseEnterRef = useLatest(options.onMouseEnter);
73
+ const onMouseLeaveRef = useLatest(options.onMouseLeave);
74
+ const onMouseDownRef = useLatest(options.onMouseDown);
75
+ const onMouseUpRef = useLatest(options.onMouseUp);
76
+ const onClickRef = useLatest(options.onClick);
77
+ const onFocusRef = useLatest(options.onFocus);
78
+ const onBlurRef = useLatest(options.onBlur);
79
+ const setStateForEvent = useCallback((eventName) => {
80
+ setState((currentState) => {
81
+ const nextState = getObjectStateUpdate(eventName);
82
+ return currentState === nextState ? currentState : nextState;
83
+ });
84
+ }, []);
85
+ return {
86
+ computedStyle: useMemo(() => {
87
+ return resolveObjectStyle(state, options.styles);
88
+ }, [state, options.styles]),
89
+ onMouseEnter: useCallback((event) => {
90
+ setStateForEvent("mouseenter");
91
+ onMouseEnterRef.current?.(event);
92
+ }, [setStateForEvent]),
93
+ onMouseLeave: useCallback((event) => {
94
+ setStateForEvent("mouseleave");
95
+ onMouseLeaveRef.current?.(event);
96
+ }, [setStateForEvent]),
97
+ onMouseDown: useCallback((event) => {
98
+ setStateForEvent("mousedown");
99
+ onMouseDownRef.current?.(event);
100
+ }, [setStateForEvent]),
101
+ onMouseUp: useCallback((event) => {
102
+ setStateForEvent("mouseup");
103
+ onMouseUpRef.current?.(event);
104
+ }, [setStateForEvent]),
105
+ onClick: useCallback((event) => {
106
+ setStateForEvent("mouseup");
107
+ onClickRef.current?.(event);
108
+ }, [setStateForEvent]),
109
+ onFocus: useCallback((event) => {
110
+ setStateForEvent("focus");
111
+ onFocusRef.current?.(event);
112
+ }, [setStateForEvent]),
113
+ onBlur: useCallback((event) => {
114
+ setStateForEvent("blur");
115
+ onBlurRef.current?.(event);
116
+ }, [setStateForEvent])
117
+ };
118
+ }
119
+
120
+ //#endregion
121
+ //#region src/components/MapFeature.tsx
122
+ function MapFeature({ data, styles, fill, stroke, onMouseEnter, onMouseLeave, onMouseDown, onMouseUp, onClick, onFocus, onBlur, ...pathProps }) {
123
+ const context = useMapContext();
124
+ const path = useMemo(() => {
125
+ return context?.renderPath(data) ?? null;
126
+ }, [context, data]);
127
+ const { computedStyle, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onClick: handleClick, onFocus: handleFocus, onBlur: handleBlur } = useMapObject({
128
+ styles,
129
+ onMouseEnter,
130
+ onMouseLeave,
131
+ onMouseDown,
132
+ onMouseUp,
133
+ onClick,
134
+ onFocus,
135
+ onBlur
136
+ });
137
+ return path ? /* @__PURE__ */ jsx("path", {
138
+ ...pathProps,
139
+ d: path,
140
+ style: computedStyle,
141
+ fill,
142
+ stroke,
143
+ onMouseEnter: handleMouseEnter,
144
+ onMouseLeave: handleMouseLeave,
145
+ onMouseDown: handleMouseDown,
146
+ onMouseUp: handleMouseUp,
147
+ onClick: handleClick,
148
+ onFocus: handleFocus,
149
+ onBlur: handleBlur
150
+ }) : null;
151
+ }
152
+
153
+ //#endregion
154
+ //#region src/components/MapFeatures.tsx
155
+ function isRenderProp(children) {
156
+ return typeof children === "function";
157
+ }
158
+ function MapFeatures({ idKey = "id", fill, stroke, styles, children }) {
159
+ const features = useMapContext()?.features ?? [];
160
+ return /* @__PURE__ */ jsx("g", { children: (isRenderProp(children) ? children({ features }) : children) ?? features.map((feature, index) => /* @__PURE__ */ jsx(MapFeature, {
161
+ data: feature,
162
+ fill,
163
+ stroke,
164
+ styles
165
+ }, getFeatureKey(feature, idKey, index))) });
166
+ }
167
+
168
+ //#endregion
169
+ //#region src/components/MapMarker.tsx
170
+ const DEFAULT_COORDINATES = [0, 0];
171
+ function MapMarker({ coordinates = DEFAULT_COORDINATES, styles, children, onMouseEnter, onMouseLeave, onMouseDown, onMouseUp, onClick, onFocus, onBlur, ...groupProps }) {
172
+ const context = useMapContext();
173
+ const transform = useMemo(() => {
174
+ return getMarkerTransform(context, coordinates);
175
+ }, [
176
+ context,
177
+ coordinates[0],
178
+ coordinates[1]
179
+ ]);
180
+ const { computedStyle, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onClick: handleClick, onFocus: handleFocus, onBlur: handleBlur } = useMapObject({
181
+ styles,
182
+ onMouseEnter,
183
+ onMouseLeave,
184
+ onMouseDown,
185
+ onMouseUp,
186
+ onClick,
187
+ onFocus,
188
+ onBlur
189
+ });
190
+ return /* @__PURE__ */ jsx("g", {
191
+ ...groupProps,
192
+ transform,
193
+ style: computedStyle,
194
+ onMouseEnter: handleMouseEnter,
195
+ onMouseLeave: handleMouseLeave,
196
+ onMouseDown: handleMouseDown,
197
+ onMouseUp: handleMouseUp,
198
+ onClick: handleClick,
199
+ onFocus: handleFocus,
200
+ onBlur: handleBlur,
201
+ children
202
+ });
203
+ }
204
+
205
+ //#endregion
206
+ //#region src/components/MapMesh.tsx
207
+ function MapMesh({ fill = "none", stroke, styles, onMouseEnter, onMouseLeave, onMouseDown, onMouseUp, onClick, onFocus, onBlur, ...pathProps }) {
208
+ const context = useMapContext();
209
+ const path = useMemo(() => {
210
+ return context?.renderMesh() ?? null;
211
+ }, [context]);
212
+ const { computedStyle, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onClick: handleClick, onFocus: handleFocus, onBlur: handleBlur } = useMapObject({
213
+ styles,
214
+ onMouseEnter,
215
+ onMouseLeave,
216
+ onMouseDown,
217
+ onMouseUp,
218
+ onClick,
219
+ onFocus,
220
+ onBlur
221
+ });
222
+ return path ? /* @__PURE__ */ jsx("path", {
223
+ ...pathProps,
224
+ d: path,
225
+ style: computedStyle,
226
+ fill,
227
+ stroke,
228
+ onMouseEnter: handleMouseEnter,
229
+ onMouseLeave: handleMouseLeave,
230
+ onMouseDown: handleMouseDown,
231
+ onMouseUp: handleMouseUp,
232
+ onClick: handleClick,
233
+ onFocus: handleFocus,
234
+ onBlur: handleBlur
235
+ }) : null;
236
+ }
237
+
238
+ //#endregion
239
+ //#region src/components/MapZoom.tsx
240
+ function MapZoom({ center, zoom, minZoom = ZOOM_DEFAULTS.minZoom, maxZoom = ZOOM_DEFAULTS.maxZoom, config, onZoomStart, onZoom, onZoomEnd, children, className, ...groupProps }) {
241
+ const containerRef = useRef(null);
242
+ const skipNextTransformSyncRef = useRef(false);
243
+ const context = useMapContext();
244
+ const onZoomStartRef = useLatest(onZoomStart);
245
+ const onZoomRef = useLatest(onZoom);
246
+ const onZoomEndRef = useLatest(onZoomEnd);
247
+ const resolvedCenter = center ?? ZOOM_DEFAULTS.center;
248
+ const resolvedZoom = zoom ?? ZOOM_DEFAULTS.zoom;
249
+ const centerX = resolvedCenter[0];
250
+ const centerY = resolvedCenter[1];
251
+ const zoomBehavior = useMemo(() => {
252
+ return createZoomBehavior(context, {
253
+ minZoom,
254
+ maxZoom,
255
+ config,
256
+ onZoomStart: (event) => {
257
+ onZoomStartRef.current?.(event);
258
+ },
259
+ onZoom: (event) => {
260
+ applyZoomGroupTransform(containerRef.current, event.transform);
261
+ onZoomRef.current?.(event);
262
+ },
263
+ onZoomEnd: (event) => {
264
+ onZoomEndRef.current?.(event);
265
+ }
266
+ });
267
+ }, [
268
+ context,
269
+ minZoom,
270
+ maxZoom,
271
+ config
272
+ ]);
273
+ useEffect(() => {
274
+ skipNextTransformSyncRef.current = true;
275
+ setupZoom({
276
+ element: containerRef.current,
277
+ behavior: zoomBehavior,
278
+ center: resolvedCenter,
279
+ zoom: resolvedZoom
280
+ });
281
+ }, [zoomBehavior]);
282
+ useEffect(() => {
283
+ if (skipNextTransformSyncRef.current) {
284
+ skipNextTransformSyncRef.current = false;
285
+ return;
286
+ }
287
+ applyZoomTransform({
288
+ element: containerRef.current,
289
+ behavior: zoomBehavior,
290
+ center: [centerX, centerY],
291
+ zoom: resolvedZoom
292
+ });
293
+ }, [
294
+ zoomBehavior,
295
+ centerX,
296
+ centerY,
297
+ resolvedZoom
298
+ ]);
299
+ const mergedClassName = className ? `d3-map-zoom ${className}` : "d3-map-zoom";
300
+ return /* @__PURE__ */ jsx("g", {
301
+ ...groupProps,
302
+ ref: containerRef,
303
+ className: mergedClassName,
304
+ children
305
+ });
306
+ }
307
+
308
+ //#endregion
309
+ export { Map, MapContextValue, MapFeature, MapFeatures, MapMarker, MapMesh, MapZoom, useMapContext, useMapObject };
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@d3-maps/react",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "private": false,
6
+ "description": "React bindings for @d3-maps/core to build reactive D3 SVG maps",
7
+ "author": "Georgii Bukharov <souljorje@gmail.com>",
8
+ "license": "MIT",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "homepage": "https://souljorje.github.io/d3-maps",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/souljorje/d3-maps.git",
16
+ "directory": "packages/react"
17
+ },
18
+ "bugs": {
19
+ "url": "https://github.com/souljorje/d3-maps/issues"
20
+ },
21
+ "keywords": [
22
+ "react",
23
+ "d3",
24
+ "svg",
25
+ "map"
26
+ ],
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js",
31
+ "browser": "./dist/index.iife.js"
32
+ }
33
+ },
34
+ "main": "dist/index.js",
35
+ "module": "dist/index.js",
36
+ "browser": "dist/index.iife.js",
37
+ "unpkg": "dist/index.iife.js",
38
+ "jsdelivr": "dist/index.iife.js",
39
+ "types": "dist/index.d.ts",
40
+ "files": [
41
+ "dist/*"
42
+ ],
43
+ "scripts": {
44
+ "typecheck": "tsc --noEmit",
45
+ "typecheck:test": "tsc -p tsconfig.test.json --noEmit",
46
+ "build": "pnpm run typecheck && tsdown",
47
+ "test": "vitest run",
48
+ "test:watch": "vitest"
49
+ },
50
+ "peerDependencies": {
51
+ "react": ">=19 <20",
52
+ "react-dom": ">=19 <20"
53
+ },
54
+ "dependencies": {
55
+ "@d3-maps/core": "workspace:*"
56
+ },
57
+ "devDependencies": {
58
+ "@testing-library/react": "catalog:",
59
+ "@types/geojson": "catalog:",
60
+ "@types/react": "catalog:",
61
+ "@types/react-dom": "catalog:",
62
+ "@types/topojson-client": "catalog:",
63
+ "@types/topojson-specification": "catalog:",
64
+ "@vitejs/plugin-react": "catalog:",
65
+ "jsdom": "catalog:",
66
+ "react": "catalog:",
67
+ "react-dom": "catalog:",
68
+ "tsdown": "catalog:",
69
+ "typescript": "catalog:",
70
+ "vite-tsconfig-paths": "catalog:",
71
+ "vitest": "catalog:"
72
+ }
73
+ }