@object-ui/plugin-map 0.3.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/LICENSE +21 -0
- package/README.md +276 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +461 -0
- package/dist/index.umd.cjs +6 -0
- package/dist/src/ObjectMap.d.ts +12 -0
- package/dist/src/ObjectMap.d.ts.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/package.json +52 -0
- package/src/ObjectMap.tsx +400 -0
- package/src/index.tsx +29 -0
- package/tsconfig.json +18 -0
- package/vite.config.ts +50 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* ObjectMap Component
|
|
11
|
+
*
|
|
12
|
+
* A specialized map visualization component that works with ObjectQL data sources.
|
|
13
|
+
* Displays records as markers/pins on a map based on location data.
|
|
14
|
+
* Implements the map view type from @objectstack/spec view.zod ListView schema.
|
|
15
|
+
*
|
|
16
|
+
* Features:
|
|
17
|
+
* - Interactive map with markers
|
|
18
|
+
* - Location-based data visualization
|
|
19
|
+
* - Marker clustering (when many points)
|
|
20
|
+
* - Popup/tooltip on marker click
|
|
21
|
+
* - Works with object/api/value data providers
|
|
22
|
+
*
|
|
23
|
+
* Note: This is a basic implementation. For production use, integrate with a
|
|
24
|
+
* proper mapping library like Mapbox, Leaflet, or Google Maps.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import React, { useEffect, useState, useMemo } from 'react';
|
|
28
|
+
import type { ObjectGridSchema, DataSource, ViewData } from '@object-ui/types';
|
|
29
|
+
|
|
30
|
+
export interface ObjectMapProps {
|
|
31
|
+
schema: ObjectGridSchema;
|
|
32
|
+
dataSource?: DataSource;
|
|
33
|
+
className?: string;
|
|
34
|
+
onMarkerClick?: (record: any) => void;
|
|
35
|
+
onEdit?: (record: any) => void;
|
|
36
|
+
onDelete?: (record: any) => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface MapConfig {
|
|
40
|
+
/** Field containing latitude value */
|
|
41
|
+
latitudeField?: string;
|
|
42
|
+
/** Field containing longitude value */
|
|
43
|
+
longitudeField?: string;
|
|
44
|
+
/** Field containing combined location (e.g., "lat,lng" or location object) */
|
|
45
|
+
locationField?: string;
|
|
46
|
+
/** Field to use for marker title/label */
|
|
47
|
+
titleField?: string;
|
|
48
|
+
/** Field to use for marker description */
|
|
49
|
+
descriptionField?: string;
|
|
50
|
+
/** Default zoom level (1-20) */
|
|
51
|
+
zoom?: number;
|
|
52
|
+
/** Center coordinates [lat, lng] */
|
|
53
|
+
center?: [number, number];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Helper to get data configuration from schema
|
|
58
|
+
*/
|
|
59
|
+
function getDataConfig(schema: ObjectGridSchema): ViewData | null {
|
|
60
|
+
if (schema.data) {
|
|
61
|
+
return schema.data;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (schema.staticData) {
|
|
65
|
+
return {
|
|
66
|
+
provider: 'value',
|
|
67
|
+
items: schema.staticData,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (schema.objectName) {
|
|
72
|
+
return {
|
|
73
|
+
provider: 'object',
|
|
74
|
+
object: schema.objectName,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Helper to convert sort config to QueryParams format
|
|
83
|
+
*/
|
|
84
|
+
function convertSortToQueryParams(sort: string | any[] | undefined): Record<string, 'asc' | 'desc'> | undefined {
|
|
85
|
+
if (!sort) return undefined;
|
|
86
|
+
|
|
87
|
+
// If it's a string like "name desc"
|
|
88
|
+
if (typeof sort === 'string') {
|
|
89
|
+
const parts = sort.split(' ');
|
|
90
|
+
const field = parts[0];
|
|
91
|
+
const order = (parts[1]?.toLowerCase() === 'desc' ? 'desc' : 'asc') as 'asc' | 'desc';
|
|
92
|
+
return { [field]: order };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// If it's an array of SortConfig objects
|
|
96
|
+
if (Array.isArray(sort)) {
|
|
97
|
+
return sort.reduce((acc, item) => {
|
|
98
|
+
if (item.field && item.order) {
|
|
99
|
+
acc[item.field] = item.order;
|
|
100
|
+
}
|
|
101
|
+
return acc;
|
|
102
|
+
}, {} as Record<string, 'asc' | 'desc'>);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Helper to get map configuration from schema
|
|
110
|
+
*/
|
|
111
|
+
function getMapConfig(schema: ObjectGridSchema): MapConfig {
|
|
112
|
+
// Check if schema has map configuration
|
|
113
|
+
if (schema.filter && typeof schema.filter === 'object' && 'map' in schema.filter) {
|
|
114
|
+
return (schema.filter as any).map as MapConfig;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// For backward compatibility, check if schema has map config at root
|
|
118
|
+
if ((schema as any).map) {
|
|
119
|
+
return (schema as any).map as MapConfig;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Default configuration
|
|
123
|
+
return {
|
|
124
|
+
latitudeField: 'latitude',
|
|
125
|
+
longitudeField: 'longitude',
|
|
126
|
+
locationField: 'location',
|
|
127
|
+
titleField: 'name',
|
|
128
|
+
descriptionField: 'description',
|
|
129
|
+
zoom: 10,
|
|
130
|
+
center: [0, 0],
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Extract coordinates from a record based on configuration
|
|
136
|
+
*/
|
|
137
|
+
function extractCoordinates(record: any, config: MapConfig): [number, number] | null {
|
|
138
|
+
// Try latitude/longitude fields
|
|
139
|
+
if (config.latitudeField && config.longitudeField) {
|
|
140
|
+
const lat = record[config.latitudeField];
|
|
141
|
+
const lng = record[config.longitudeField];
|
|
142
|
+
if (typeof lat === 'number' && typeof lng === 'number') {
|
|
143
|
+
return [lat, lng];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Try location field
|
|
148
|
+
if (config.locationField) {
|
|
149
|
+
const location = record[config.locationField];
|
|
150
|
+
|
|
151
|
+
// Handle object format: { lat: number, lng: number }
|
|
152
|
+
if (typeof location === 'object' && location !== null) {
|
|
153
|
+
const lat = location.lat || location.latitude;
|
|
154
|
+
const lng = location.lng || location.lon || location.longitude;
|
|
155
|
+
if (typeof lat === 'number' && typeof lng === 'number') {
|
|
156
|
+
return [lat, lng];
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Handle string format: "lat,lng"
|
|
161
|
+
if (typeof location === 'string') {
|
|
162
|
+
const parts = location.split(',').map(s => parseFloat(s.trim()));
|
|
163
|
+
if (parts.length === 2 && !isNaN(parts[0]) && !isNaN(parts[1])) {
|
|
164
|
+
return [parts[0], parts[1]];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Handle array format: [lat, lng]
|
|
169
|
+
if (Array.isArray(location) && location.length === 2) {
|
|
170
|
+
const lat = parseFloat(location[0]);
|
|
171
|
+
const lng = parseFloat(location[1]);
|
|
172
|
+
if (!isNaN(lat) && !isNaN(lng)) {
|
|
173
|
+
return [lat, lng];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export const ObjectMap: React.FC<ObjectMapProps> = ({
|
|
182
|
+
schema,
|
|
183
|
+
dataSource,
|
|
184
|
+
className,
|
|
185
|
+
onMarkerClick,
|
|
186
|
+
}) => {
|
|
187
|
+
const [data, setData] = useState<any[]>([]);
|
|
188
|
+
const [loading, setLoading] = useState(true);
|
|
189
|
+
const [error, setError] = useState<Error | null>(null);
|
|
190
|
+
const [objectSchema, setObjectSchema] = useState<any>(null);
|
|
191
|
+
const [selectedMarker, setSelectedMarker] = useState<string | null>(null);
|
|
192
|
+
|
|
193
|
+
const dataConfig = getDataConfig(schema);
|
|
194
|
+
const mapConfig = getMapConfig(schema);
|
|
195
|
+
const hasInlineData = dataConfig?.provider === 'value';
|
|
196
|
+
|
|
197
|
+
// Fetch data based on provider
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
const fetchData = async () => {
|
|
200
|
+
try {
|
|
201
|
+
setLoading(true);
|
|
202
|
+
|
|
203
|
+
if (hasInlineData && dataConfig?.provider === 'value') {
|
|
204
|
+
setData(dataConfig.items as any[]);
|
|
205
|
+
setLoading(false);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!dataSource) {
|
|
210
|
+
throw new Error('DataSource required for object/api providers');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (dataConfig?.provider === 'object') {
|
|
214
|
+
const objectName = dataConfig.object;
|
|
215
|
+
const result = await dataSource.find(objectName, {
|
|
216
|
+
$filter: schema.filter,
|
|
217
|
+
$orderby: convertSortToQueryParams(schema.sort),
|
|
218
|
+
});
|
|
219
|
+
setData(result?.data || []);
|
|
220
|
+
} else if (dataConfig?.provider === 'api') {
|
|
221
|
+
console.warn('API provider not yet implemented for ObjectMap');
|
|
222
|
+
setData([]);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
setLoading(false);
|
|
226
|
+
} catch (err) {
|
|
227
|
+
setError(err as Error);
|
|
228
|
+
setLoading(false);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
fetchData();
|
|
233
|
+
}, [dataConfig, dataSource, hasInlineData, schema.filter, schema.sort]);
|
|
234
|
+
|
|
235
|
+
// Fetch object schema for field metadata
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
const fetchObjectSchema = async () => {
|
|
238
|
+
try {
|
|
239
|
+
if (!dataSource) return;
|
|
240
|
+
|
|
241
|
+
const objectName = dataConfig?.provider === 'object'
|
|
242
|
+
? dataConfig.object
|
|
243
|
+
: schema.objectName;
|
|
244
|
+
|
|
245
|
+
if (!objectName) return;
|
|
246
|
+
|
|
247
|
+
const schemaData = await dataSource.getObjectSchema(objectName);
|
|
248
|
+
setObjectSchema(schemaData);
|
|
249
|
+
} catch (err) {
|
|
250
|
+
console.error('Failed to fetch object schema:', err);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
if (!hasInlineData && dataSource) {
|
|
255
|
+
fetchObjectSchema();
|
|
256
|
+
}
|
|
257
|
+
}, [schema.objectName, dataSource, hasInlineData, dataConfig]);
|
|
258
|
+
|
|
259
|
+
// Transform data to map markers
|
|
260
|
+
const markers = useMemo(() => {
|
|
261
|
+
return data
|
|
262
|
+
.map((record, index) => {
|
|
263
|
+
const coordinates = extractCoordinates(record, mapConfig);
|
|
264
|
+
if (!coordinates) return null;
|
|
265
|
+
|
|
266
|
+
const title = mapConfig.titleField ? record[mapConfig.titleField] : 'Marker';
|
|
267
|
+
const description = mapConfig.descriptionField ? record[mapConfig.descriptionField] : undefined;
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
id: record.id || record._id || `marker-${index}`,
|
|
271
|
+
title,
|
|
272
|
+
description,
|
|
273
|
+
coordinates,
|
|
274
|
+
data: record,
|
|
275
|
+
};
|
|
276
|
+
})
|
|
277
|
+
.filter((marker): marker is NonNullable<typeof marker> => marker !== null);
|
|
278
|
+
}, [data, mapConfig]);
|
|
279
|
+
|
|
280
|
+
// Calculate map bounds
|
|
281
|
+
const bounds = useMemo(() => {
|
|
282
|
+
if (!markers.length) {
|
|
283
|
+
return {
|
|
284
|
+
center: mapConfig.center || [0, 0],
|
|
285
|
+
minLat: (mapConfig.center?.[0] || 0) - 0.1,
|
|
286
|
+
maxLat: (mapConfig.center?.[0] || 0) + 0.1,
|
|
287
|
+
minLng: (mapConfig.center?.[1] || 0) - 0.1,
|
|
288
|
+
maxLng: (mapConfig.center?.[1] || 0) + 0.1,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const lats = markers.map(m => m.coordinates[0]);
|
|
293
|
+
const lngs = markers.map(m => m.coordinates[1]);
|
|
294
|
+
|
|
295
|
+
return {
|
|
296
|
+
center: [
|
|
297
|
+
(Math.min(...lats) + Math.max(...lats)) / 2,
|
|
298
|
+
(Math.min(...lngs) + Math.max(...lngs)) / 2,
|
|
299
|
+
] as [number, number],
|
|
300
|
+
minLat: Math.min(...lats),
|
|
301
|
+
maxLat: Math.max(...lats),
|
|
302
|
+
minLng: Math.min(...lngs),
|
|
303
|
+
maxLng: Math.max(...lngs),
|
|
304
|
+
};
|
|
305
|
+
}, [markers, mapConfig.center]);
|
|
306
|
+
|
|
307
|
+
if (loading) {
|
|
308
|
+
return (
|
|
309
|
+
<div className={className}>
|
|
310
|
+
<div className="flex items-center justify-center h-96 bg-muted rounded-lg">
|
|
311
|
+
<div className="text-muted-foreground">Loading map...</div>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (error) {
|
|
318
|
+
return (
|
|
319
|
+
<div className={className}>
|
|
320
|
+
<div className="flex items-center justify-center h-96 bg-muted rounded-lg">
|
|
321
|
+
<div className="text-destructive">Error: {error.message}</div>
|
|
322
|
+
</div>
|
|
323
|
+
</div>
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return (
|
|
328
|
+
<div className={className}>
|
|
329
|
+
<div className="relative border rounded-lg overflow-hidden bg-muted" style={{ height: '600px' }}>
|
|
330
|
+
{/* Placeholder map - in production, replace with actual map library */}
|
|
331
|
+
<div className="absolute inset-0 flex items-center justify-center bg-gradient-to-br from-blue-50 to-green-50 dark:from-blue-950 dark:to-green-950">
|
|
332
|
+
<div className="text-center">
|
|
333
|
+
<div className="text-4xl mb-2">🗺️</div>
|
|
334
|
+
<div className="text-sm text-muted-foreground mb-4">
|
|
335
|
+
Map Visualization (Placeholder)
|
|
336
|
+
</div>
|
|
337
|
+
<div className="text-xs text-muted-foreground max-w-md mx-auto">
|
|
338
|
+
This is a basic map placeholder. For production, integrate with Mapbox, Leaflet, or Google Maps.
|
|
339
|
+
<br />
|
|
340
|
+
<br />
|
|
341
|
+
<strong>Map Info:</strong>
|
|
342
|
+
<br />
|
|
343
|
+
Center: [{bounds.center[0].toFixed(4)}, {bounds.center[1].toFixed(4)}]
|
|
344
|
+
<br />
|
|
345
|
+
Markers: {markers.length}
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
349
|
+
|
|
350
|
+
{/* Marker List Overlay */}
|
|
351
|
+
<div className="absolute top-4 right-4 w-64 bg-background border rounded-lg shadow-lg max-h-96 overflow-y-auto">
|
|
352
|
+
<div className="p-3 border-b font-semibold bg-muted">
|
|
353
|
+
Locations ({markers.length})
|
|
354
|
+
</div>
|
|
355
|
+
{markers.length === 0 ? (
|
|
356
|
+
<div className="p-4 text-sm text-muted-foreground text-center">
|
|
357
|
+
No locations found with valid coordinates
|
|
358
|
+
</div>
|
|
359
|
+
) : (
|
|
360
|
+
<div>
|
|
361
|
+
{markers.map(marker => (
|
|
362
|
+
<div
|
|
363
|
+
key={marker.id}
|
|
364
|
+
className={`p-3 border-b hover:bg-muted/50 cursor-pointer transition-colors ${
|
|
365
|
+
selectedMarker === marker.id ? 'bg-muted' : ''
|
|
366
|
+
}`}
|
|
367
|
+
onClick={() => {
|
|
368
|
+
setSelectedMarker(marker.id);
|
|
369
|
+
onMarkerClick?.(marker.data);
|
|
370
|
+
}}
|
|
371
|
+
>
|
|
372
|
+
<div className="font-medium text-sm">{marker.title}</div>
|
|
373
|
+
{marker.description && (
|
|
374
|
+
<div className="text-xs text-muted-foreground mt-1 line-clamp-2">
|
|
375
|
+
{marker.description}
|
|
376
|
+
</div>
|
|
377
|
+
)}
|
|
378
|
+
<div className="text-xs text-muted-foreground mt-1">
|
|
379
|
+
📍 {marker.coordinates[0].toFixed(4)}, {marker.coordinates[1].toFixed(4)}
|
|
380
|
+
</div>
|
|
381
|
+
</div>
|
|
382
|
+
))}
|
|
383
|
+
</div>
|
|
384
|
+
)}
|
|
385
|
+
</div>
|
|
386
|
+
|
|
387
|
+
{/* Legend */}
|
|
388
|
+
<div className="absolute bottom-4 left-4 bg-background border rounded-lg shadow-lg p-3">
|
|
389
|
+
<div className="text-xs font-semibold mb-2">Legend</div>
|
|
390
|
+
<div className="text-xs space-y-1">
|
|
391
|
+
<div className="flex items-center gap-2">
|
|
392
|
+
<div className="w-3 h-3 rounded-full bg-blue-500" />
|
|
393
|
+
<span>Location Marker</span>
|
|
394
|
+
</div>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
</div>
|
|
398
|
+
</div>
|
|
399
|
+
);
|
|
400
|
+
};
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { ComponentRegistry } from '@object-ui/core';
|
|
11
|
+
import { ObjectMap } from './ObjectMap';
|
|
12
|
+
import type { ObjectMapProps } from './ObjectMap';
|
|
13
|
+
|
|
14
|
+
export { ObjectMap };
|
|
15
|
+
export type { ObjectMapProps };
|
|
16
|
+
|
|
17
|
+
// Register component
|
|
18
|
+
const ObjectMapRenderer: React.FC<{ schema: any }> = ({ schema }) => {
|
|
19
|
+
return <ObjectMap schema={schema} dataSource={null as any} />;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
ComponentRegistry.register('object-map', ObjectMapRenderer, {
|
|
23
|
+
label: 'Object Map',
|
|
24
|
+
category: 'plugin',
|
|
25
|
+
inputs: [
|
|
26
|
+
{ name: 'objectName', type: 'string', label: 'Object Name', required: true },
|
|
27
|
+
{ name: 'map', type: 'object', label: 'Map Config', description: 'latitudeField, longitudeField, titleField' },
|
|
28
|
+
],
|
|
29
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "dist",
|
|
5
|
+
"jsx": "react-jsx",
|
|
6
|
+
"baseUrl": ".",
|
|
7
|
+
"paths": {
|
|
8
|
+
"@/*": ["src/*"]
|
|
9
|
+
},
|
|
10
|
+
"noEmit": false,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"composite": true,
|
|
13
|
+
"declarationMap": true,
|
|
14
|
+
"skipLibCheck": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src"],
|
|
17
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"]
|
|
18
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { defineConfig } from 'vite';
|
|
10
|
+
import react from '@vitejs/plugin-react';
|
|
11
|
+
import dts from 'vite-plugin-dts';
|
|
12
|
+
import { resolve } from 'path';
|
|
13
|
+
|
|
14
|
+
export default defineConfig({
|
|
15
|
+
plugins: [
|
|
16
|
+
react(),
|
|
17
|
+
dts({
|
|
18
|
+
insertTypesEntry: true,
|
|
19
|
+
include: ['src'],
|
|
20
|
+
exclude: ['**/*.test.ts', '**/*.test.tsx', 'node_modules'],
|
|
21
|
+
skipDiagnostics: true,
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
24
|
+
resolve: {
|
|
25
|
+
alias: {
|
|
26
|
+
'@': resolve(__dirname, './src'),
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
build: {
|
|
30
|
+
lib: {
|
|
31
|
+
entry: resolve(__dirname, 'src/index.tsx'),
|
|
32
|
+
name: 'ObjectUIPluginMap',
|
|
33
|
+
fileName: 'index',
|
|
34
|
+
},
|
|
35
|
+
rollupOptions: {
|
|
36
|
+
external: ['react', 'react-dom', '@object-ui/components', '@object-ui/core', '@object-ui/react', '@object-ui/types', 'lucide-react'],
|
|
37
|
+
output: {
|
|
38
|
+
globals: {
|
|
39
|
+
react: 'React',
|
|
40
|
+
'react-dom': 'ReactDOM',
|
|
41
|
+
'@object-ui/components': 'ObjectUIComponents',
|
|
42
|
+
'@object-ui/core': 'ObjectUICore',
|
|
43
|
+
'@object-ui/react': 'ObjectUIReact',
|
|
44
|
+
'@object-ui/types': 'ObjectUITypes',
|
|
45
|
+
'lucide-react': 'LucideReact',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|