@gradeui/ui 0.8.2 → 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.
@@ -0,0 +1,160 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * Coordinate tuple — `[lng, lat]`. Always tuples in the public API; each
5
+ * adapter normalizes internally to whatever shape its provider expects
6
+ * (Google takes `{ lat, lng }` objects, Mapbox/MapLibre take tuples).
7
+ */
8
+ type Coords = [lng: number, lat: number];
9
+ type MapAppearance = "light" | "dark" | "satellite" | "auto";
10
+ type MapErrorCode = "sdk-missing" | "api-key-missing" | "provider-init-failed" | "style-load-failed" | "tile-load-failed";
11
+ type MapError = {
12
+ code: MapErrorCode;
13
+ message: string;
14
+ cause?: unknown;
15
+ };
16
+ /**
17
+ * Imperative handle exposed via `ref` and `onLoad`. Use for fly-to
18
+ * animations, fit-bounds, and the `.instance` escape hatch when you
19
+ * need the provider-native map object.
20
+ */
21
+ type MapHandle = {
22
+ /** Pan + zoom to a marker by id, or directly to coords. */
23
+ flyTo: (idOrCoords: string | Coords, opts?: {
24
+ zoom?: number;
25
+ durationMs?: number;
26
+ }) => void;
27
+ panTo: (coords: Coords, opts?: {
28
+ durationMs?: number;
29
+ }) => void;
30
+ fitBounds: (coords: Coords[], opts?: {
31
+ paddingPx?: number;
32
+ durationMs?: number;
33
+ }) => void;
34
+ getCenter: () => Coords;
35
+ getZoom: () => number;
36
+ getBounds: () => [Coords, Coords];
37
+ /**
38
+ * Provider-native instance. Cast to `mapboxgl.Map`, `maplibregl.Map`,
39
+ * or `google.maps.Map` to reach features the wrapper doesn't expose
40
+ * (3D extrusions, custom layers, drawing tools, heatmaps).
41
+ * Touching this makes your code provider-specific.
42
+ */
43
+ readonly instance: unknown;
44
+ };
45
+ type MapBaseProps = {
46
+ center: Coords;
47
+ zoom: number;
48
+ /** [southwest, northeast] — takes precedence over center/zoom when set. */
49
+ bounds?: [Coords, Coords];
50
+ /** Default `"auto"` (follows GradeThemeProvider mode). */
51
+ appearance?: MapAppearance;
52
+ /** Default `true`. `false` disables pan/zoom/rotate (static display). */
53
+ interactive?: boolean;
54
+ /** Controlled hovered marker id — pairs with `onHoveredIdChange` for list↔map sync. */
55
+ hoveredId?: string | null;
56
+ onHoveredIdChange?: (id: string | null) => void;
57
+ onLoad?: (handle: MapHandle) => void;
58
+ onError?: (error: MapError) => void;
59
+ className?: string;
60
+ style?: React.CSSProperties;
61
+ children?: React.ReactNode;
62
+ };
63
+ /**
64
+ * Discriminated union — TS enforces the right config fields per provider.
65
+ *
66
+ * @example
67
+ * // Zero-config public demo (MapLibre + MapTiler demo key):
68
+ * <Map center={[-122.42, 37.78]} zoom={12} />
69
+ *
70
+ * // Mapbox:
71
+ * <Map provider="mapbox" accessToken={env.MAPBOX_TOKEN} center={...} zoom={...} />
72
+ *
73
+ * // Google:
74
+ * <Map provider="google" apiKey={env.GOOGLE_MAPS_KEY} center={...} zoom={...} />
75
+ */
76
+ type MapProps = MapBaseProps & ({
77
+ provider?: "maplibre";
78
+ /** Override the default MapTiler style URL entirely. */
79
+ styleUrl?: string;
80
+ /** Your MapTiler key. Omit to use the Grade demo key (referrer-locked to gradeui.com). */
81
+ tilerKey?: string;
82
+ } | {
83
+ provider: "mapbox";
84
+ accessToken: string;
85
+ /** Override the appearance-derived Mapbox style URL. */
86
+ styleUrl?: string;
87
+ } | {
88
+ provider: "google";
89
+ apiKey: string;
90
+ /** Optional Google Cloud Map ID for cloud-based styling. */
91
+ mapId?: string;
92
+ });
93
+ type MapMarkerProps = {
94
+ /** Required — used by `flyTo(id)` and `hoveredId` matching. */
95
+ id: string;
96
+ at: Coords;
97
+ /** Default `"bottom"` — pin tip at the coord. */
98
+ anchor?: "center" | "bottom";
99
+ className?: string;
100
+ children?: React.ReactNode;
101
+ onClick?: (e: {
102
+ id: string;
103
+ coords: Coords;
104
+ native: MouseEvent;
105
+ }) => void;
106
+ };
107
+ type AdapterCallbacks = {
108
+ onLoad: () => void;
109
+ onError: (error: MapError) => void;
110
+ onMarkerHover: (id: string | null) => void;
111
+ onMarkerClick: (id: string, coords: Coords, native: MouseEvent) => void;
112
+ };
113
+ type AdapterOpts = {
114
+ center: Coords;
115
+ zoom: number;
116
+ bounds?: [Coords, Coords];
117
+ appearance: "light" | "dark" | "satellite";
118
+ interactive: boolean;
119
+ styleUrl?: string;
120
+ tilerKey?: string;
121
+ accessToken?: string;
122
+ apiKey?: string;
123
+ mapId?: string;
124
+ };
125
+ type MarkerHandle = {
126
+ /** DOM element the adapter created for this marker. `<MapMarker>` portals its children into here. */
127
+ element: HTMLElement;
128
+ /** Last-known coords, used by `flyTo(id)`. Updated via `setPosition`. */
129
+ coords: Coords;
130
+ setHovered: (hovered: boolean) => void;
131
+ setPosition: (coords: Coords) => void;
132
+ remove: () => void;
133
+ };
134
+ type AdapterInstance = {
135
+ setCenter: (coords: Coords) => void;
136
+ setZoom: (zoom: number) => void;
137
+ setBounds: (sw: Coords, ne: Coords) => void;
138
+ setAppearance: (appearance: "light" | "dark" | "satellite") => void;
139
+ setInteractive: (enabled: boolean) => void;
140
+ flyTo: (coords: Coords, opts?: {
141
+ zoom?: number;
142
+ durationMs?: number;
143
+ }) => void;
144
+ panTo: (coords: Coords, opts?: {
145
+ durationMs?: number;
146
+ }) => void;
147
+ fitBounds: (coords: Coords[], opts?: {
148
+ paddingPx?: number;
149
+ durationMs?: number;
150
+ }) => void;
151
+ getCenter: () => Coords;
152
+ getZoom: () => number;
153
+ getBounds: () => [Coords, Coords];
154
+ addMarker: (id: string, coords: Coords, anchor: "center" | "bottom") => MarkerHandle;
155
+ destroy: () => void;
156
+ instance: unknown;
157
+ };
158
+ type AdapterFactory = (container: HTMLElement, opts: AdapterOpts, callbacks: AdapterCallbacks) => Promise<AdapterInstance>;
159
+
160
+ export type { AdapterFactory as A, Coords as C, MapProps as M, MapHandle as a, MapMarkerProps as b, MapAppearance as c, MapError as d, MapErrorCode as e };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradeui/ui",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "Grade Design System — React components, theme engine, and design tokens",
5
5
  "license": "MIT",
6
6
  "author": "Grade",
@@ -62,6 +62,21 @@
62
62
  "types": "./dist/tailwind-preset.d.ts",
63
63
  "import": "./dist/tailwind-preset.mjs",
64
64
  "require": "./dist/tailwind-preset.js"
65
+ },
66
+ "./map/maplibre": {
67
+ "types": "./dist/map/maplibre.d.ts",
68
+ "import": "./dist/map/maplibre.mjs",
69
+ "require": "./dist/map/maplibre.js"
70
+ },
71
+ "./map/mapbox": {
72
+ "types": "./dist/map/mapbox.d.ts",
73
+ "import": "./dist/map/mapbox.mjs",
74
+ "require": "./dist/map/mapbox.js"
75
+ },
76
+ "./map/google": {
77
+ "types": "./dist/map/google.d.ts",
78
+ "import": "./dist/map/google.mjs",
79
+ "require": "./dist/map/google.js"
65
80
  }
66
81
  },
67
82
  "files": [
@@ -72,7 +87,21 @@
72
87
  ],
73
88
  "peerDependencies": {
74
89
  "react": "^18.0.0 || ^19.0.0",
75
- "react-dom": "^18.0.0 || ^19.0.0"
90
+ "react-dom": "^18.0.0 || ^19.0.0",
91
+ "maplibre-gl": "^4.0.0 || ^5.0.0",
92
+ "mapbox-gl": "^3.0.0",
93
+ "@googlemaps/js-api-loader": "^1.16.0"
94
+ },
95
+ "peerDependenciesMeta": {
96
+ "maplibre-gl": {
97
+ "optional": true
98
+ },
99
+ "mapbox-gl": {
100
+ "optional": true
101
+ },
102
+ "@googlemaps/js-api-loader": {
103
+ "optional": true
104
+ }
76
105
  },
77
106
  "dependencies": {
78
107
  "@radix-ui/react-accordion": "^1.2.12",
@@ -107,6 +136,7 @@
107
136
  "postprocessing": "^6.36.5",
108
137
  "react-day-picker": "^9.13.0",
109
138
  "react-markdown": "^10.1.0",
139
+ "react-resizable-panels": "^2.1.7",
110
140
  "recharts": "^2.15.4",
111
141
  "remark-gfm": "^4.0.1",
112
142
  "sonner": "^2.0.7",
@@ -117,11 +147,15 @@
117
147
  "@rive-app/react-canvas": "^4.21.4"
118
148
  },
119
149
  "devDependencies": {
150
+ "@googlemaps/js-api-loader": "^1.16.0",
151
+ "@types/google.maps": "^3.55.0",
120
152
  "@types/node": "^20",
121
153
  "@types/react": "^19",
122
154
  "@types/react-dom": "^19",
123
155
  "@types/three": "^0.170.0",
124
156
  "autoprefixer": "^10.4.23",
157
+ "maplibre-gl": "^4.7.0",
158
+ "mapbox-gl": "^3.8.0",
125
159
  "postcss": "^8",
126
160
  "tailwindcss": "^3.4.1",
127
161
  "tailwindcss-animate": "^1.0.7",
@@ -129,9 +163,11 @@
129
163
  "typescript": "^5.6.3"
130
164
  },
131
165
  "scripts": {
132
- "build": "tsup && npm run build:css",
166
+ "build": "npm run clean && tsup && npm run build:css",
133
167
  "build:css": "tailwindcss -i ./styles/globals.css -o ./dist/styles.css --minify",
134
- "dev": "tsup --watch",
168
+ "build:css:watch": "tailwindcss -i ./styles/globals.css -o ./dist/styles.css --watch",
169
+ "dev": "npm run build:css && tsup --watch",
170
+ "dev:full": "npm run build:css && (tsup --watch & npm run build:css:watch)",
135
171
  "lint": "echo \"(no lint configured for @gradeui/ui yet)\"",
136
172
  "clean": "rm -rf dist"
137
173
  }