@j3m-quantum/ui 2.1.8 → 2.1.10
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 +7 -3
- package/dist/cli/index.js +7 -7
- package/dist/index.cjs +1761 -467
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +271 -129
- package/dist/index.d.ts +271 -129
- package/dist/index.js +1609 -332
- package/dist/index.js.map +1 -1
- package/dist/map.cjs +103 -0
- package/dist/map.cjs.map +1 -0
- package/dist/map.d.cts +132 -0
- package/dist/map.d.ts +132 -0
- package/dist/map.js +96 -0
- package/dist/map.js.map +1 -0
- package/dist/styles/index.css +1 -0
- package/package.json +11 -11
package/dist/map.cjs
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var reactLeaflet = require('react-leaflet');
|
|
4
|
+
var clsx = require('clsx');
|
|
5
|
+
var tailwindMerge = require('tailwind-merge');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
|
|
8
|
+
// src/components/map/map.tsx
|
|
9
|
+
function cn(...inputs) {
|
|
10
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
11
|
+
}
|
|
12
|
+
function Map({
|
|
13
|
+
center,
|
|
14
|
+
zoom = 13,
|
|
15
|
+
className,
|
|
16
|
+
children,
|
|
17
|
+
...props
|
|
18
|
+
}) {
|
|
19
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
20
|
+
reactLeaflet.MapContainer,
|
|
21
|
+
{
|
|
22
|
+
center,
|
|
23
|
+
zoom,
|
|
24
|
+
className: cn(
|
|
25
|
+
"w-full rounded-lg border border-border overflow-hidden",
|
|
26
|
+
"[&_.leaflet-control-zoom]:border-border",
|
|
27
|
+
"[&_.leaflet-control-zoom]:rounded-md",
|
|
28
|
+
"[&_.leaflet-control-zoom]:shadow-sm",
|
|
29
|
+
"[&_.leaflet-control-zoom-in]:rounded-t-md",
|
|
30
|
+
"[&_.leaflet-control-zoom-in]:border-b",
|
|
31
|
+
"[&_.leaflet-control-zoom-in]:border-border",
|
|
32
|
+
"[&_.leaflet-control-zoom-out]:rounded-b-md",
|
|
33
|
+
"[&_.leaflet-popup-content-wrapper]:rounded-lg",
|
|
34
|
+
"[&_.leaflet-popup-content-wrapper]:shadow-lg",
|
|
35
|
+
"[&_.leaflet-popup-content-wrapper]:border",
|
|
36
|
+
"[&_.leaflet-popup-content-wrapper]:border-border",
|
|
37
|
+
className
|
|
38
|
+
),
|
|
39
|
+
scrollWheelZoom: true,
|
|
40
|
+
...props,
|
|
41
|
+
children
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
var TILE_LAYERS = {
|
|
46
|
+
default: {
|
|
47
|
+
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
48
|
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
49
|
+
},
|
|
50
|
+
dark: {
|
|
51
|
+
url: "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
|
|
52
|
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>'
|
|
53
|
+
},
|
|
54
|
+
satellite: {
|
|
55
|
+
url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
|
56
|
+
attribution: "© Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
function MapTileLayer({
|
|
60
|
+
variant = "default",
|
|
61
|
+
...props
|
|
62
|
+
}) {
|
|
63
|
+
const layer = TILE_LAYERS[variant];
|
|
64
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
65
|
+
reactLeaflet.TileLayer,
|
|
66
|
+
{
|
|
67
|
+
url: layer.url,
|
|
68
|
+
attribution: layer.attribution,
|
|
69
|
+
...props
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
function MapMarker({
|
|
74
|
+
position,
|
|
75
|
+
children,
|
|
76
|
+
...props
|
|
77
|
+
}) {
|
|
78
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactLeaflet.Marker, { position, ...props, children });
|
|
79
|
+
}
|
|
80
|
+
function MapPopup({
|
|
81
|
+
children,
|
|
82
|
+
...props
|
|
83
|
+
}) {
|
|
84
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactLeaflet.Popup, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm", children }) });
|
|
85
|
+
}
|
|
86
|
+
function MapTooltip({
|
|
87
|
+
children,
|
|
88
|
+
...props
|
|
89
|
+
}) {
|
|
90
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactLeaflet.Tooltip, { ...props, children });
|
|
91
|
+
}
|
|
92
|
+
function MapZoomControl(props) {
|
|
93
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactLeaflet.ZoomControl, { ...props });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
exports.Map = Map;
|
|
97
|
+
exports.MapMarker = MapMarker;
|
|
98
|
+
exports.MapPopup = MapPopup;
|
|
99
|
+
exports.MapTileLayer = MapTileLayer;
|
|
100
|
+
exports.MapTooltip = MapTooltip;
|
|
101
|
+
exports.MapZoomControl = MapZoomControl;
|
|
102
|
+
//# sourceMappingURL=map.cjs.map
|
|
103
|
+
//# sourceMappingURL=map.cjs.map
|
package/dist/map.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/map/map.tsx","../src/components/map/map-tile-layer.tsx","../src/components/map/map-marker.tsx"],"names":["twMerge","clsx","jsx","MapContainer","TileLayer","Marker","Popup","Tooltip","ZoomControl"],"mappings":";;;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACmCA,SAAS,GAAA,CAAI;AAAA,EACX,MAAA;AAAA,EACA,IAAA,GAAO,EAAA;AAAA,EACP,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAa;AACX,EAAA,uBACEC,cAAA;AAAA,IAACC,yBAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,IAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,wDAAA;AAAA,QACA,yCAAA;AAAA,QACA,sCAAA;AAAA,QACA,qCAAA;AAAA,QACA,2CAAA;AAAA,QACA,uCAAA;AAAA,QACA,4CAAA;AAAA,QACA,4CAAA;AAAA,QACA,+CAAA;AAAA,QACA,8CAAA;AAAA,QACA,2CAAA;AAAA,QACA,kDAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,eAAA,EAAiB,IAAA;AAAA,MAChB,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AC5DA,IAAM,WAAA,GAAc;AAAA,EAClB,OAAA,EAAS;AAAA,IACP,GAAA,EAAK,oDAAA;AAAA,IACL,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,+DAAA;AAAA,IACL,WAAA,EAAa;AAAA,GACf;AAAA,EACA,SAAA,EAAW;AAAA,IACT,GAAA,EAAK,+FAAA;AAAA,IACL,WAAA,EAAa;AAAA;AAEjB,CAAA;AAiBA,SAAS,YAAA,CAAa;AAAA,EACpB,OAAA,GAAU,SAAA;AAAA,EACV,GAAG;AACL,CAAA,EAAsB;AACpB,EAAA,MAAM,KAAA,GAAQ,YAAY,OAAO,CAAA;AAEjC,EAAA,uBACED,cAAAA;AAAA,IAACE,sBAAA;AAAA,IAAA;AAAA,MACC,KAAK,KAAA,CAAM,GAAA;AAAA,MACX,aAAa,KAAA,CAAM,WAAA;AAAA,MAClB,GAAG;AAAA;AAAA,GACN;AAEJ;AC7BA,SAAS,SAAA,CAAU;AAAA,EACjB,QAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAmB;AACjB,EAAA,uBACEF,cAAAA,CAACG,mBAAA,EAAA,EAAO,QAAA,EAAyC,GAAG,OACjD,QAAA,EACH,CAAA;AAEJ;AAsBA,SAAS,QAAA,CAAS;AAAA,EAChB,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAkB;AAChB,EAAA,uBACEH,cAAAA,CAACI,kBAAA,EAAA,EAAO,GAAG,KAAA,EACT,QAAA,kBAAAJ,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,SAAA,EACZ,QAAA,EACH,CAAA,EACF,CAAA;AAEJ;AAmBA,SAAS,UAAA,CAAW;AAAA,EAClB,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAoB;AAClB,EAAA,uBACEA,cAAAA,CAACK,oBAAA,EAAA,EAAS,GAAG,OACV,QAAA,EACH,CAAA;AAEJ;AAiBA,SAAS,eAAe,KAAA,EAA4B;AAClD,EAAA,uBAAOL,cAAAA,CAACM,wBAAA,EAAA,EAAa,GAAG,KAAA,EAAO,CAAA;AACjC","file":"map.cjs","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\n// ============================================================================\n// SHARED STATUS CELL CLASSES\n// Reusable status fill classes for calibration table, planning table,\n// and supplier loading cards. Ensures visual consistency across components.\n// ============================================================================\n\n/**\n * Status types for cell/card fills\n * - complete/valid: Green - task is done\n * - warning: Amber - needs attention\n * - critical/risk: Red - at risk, urgent\n * - normal/pending: Grey - neutral, on track but not done\n * - shipped: Muted + green accent - completed delivery (distinct from complete)\n */\nexport type StatusCellType = \n | \"complete\" \n | \"valid\" \n | \"warning\" \n | \"critical\" \n | \"risk\" \n | \"normal\" \n | \"pending\" \n | \"shipped\"\n\n/**\n * Status cell fill classes - matching calibration/planning table styling\n * Uses left stroke (3px) + full background fill\n * \n * Pattern: \n * - Green = complete/valid/ready\n * - Amber = warning/attention\n * - Red = critical/risk\n * - Grey = normal/pending/neutral\n * - Muted = shipped (greyed out with green check)\n */\nexport const statusCellFillClasses = {\n // Green - complete/valid/ready state\n complete: {\n border: \"border-l-[3px] border-l-green-500\",\n bg: \"bg-green-50/50 dark:bg-green-950/30\",\n combined: \"border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30\",\n },\n valid: {\n border: \"border-l-[3px] border-l-green-500\",\n bg: \"bg-green-50/50 dark:bg-green-950/30\",\n combined: \"border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30\",\n },\n ready: {\n border: \"border-l-[3px] border-l-green-500\",\n bg: \"bg-green-50/50 dark:bg-green-950/30\",\n combined: \"border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30\",\n },\n \n // Amber - warning/attention state\n warning: {\n border: \"border-l-[3px] border-l-amber-500\",\n bg: \"bg-amber-50/50 dark:bg-amber-950/30\",\n combined: \"border-l-[3px] border-l-amber-500 bg-amber-50/50 dark:bg-amber-950/30\",\n },\n \n // Red - critical/risk state\n critical: {\n border: \"border-l-[3px] border-l-red-500\",\n bg: \"bg-red-50/50 dark:bg-red-950/30\",\n combined: \"border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30\",\n },\n risk: {\n border: \"border-l-[3px] border-l-red-500\",\n bg: \"bg-red-50/50 dark:bg-red-950/30\",\n combined: \"border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30\",\n },\n \n // Grey - normal/pending/neutral state (on track but not complete)\n normal: {\n border: \"border-l-[3px] border-l-muted-foreground/40\",\n bg: \"bg-muted/30 dark:bg-muted/20\",\n combined: \"border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20\",\n },\n pending: {\n border: \"border-l-[3px] border-l-muted-foreground/40\",\n bg: \"bg-muted/30 dark:bg-muted/20\",\n combined: \"border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20\",\n },\n \n // Shipped - distinct muted state with green accent (greyed out + check)\n shipped: {\n border: \"border-l-[3px] border-l-green-500/50\",\n bg: \"bg-muted/50 dark:bg-muted/30\",\n combined: \"border-l-[3px] border-l-green-500/50 bg-muted/50 dark:bg-muted/30\",\n },\n} as const\n\n/**\n * Status text colors for use inside status cells\n */\nexport const statusCellTextClasses = {\n complete: {\n title: \"text-foreground\",\n subtitle: \"text-green-700/80 dark:text-green-300/80\",\n icon: \"text-green-600 dark:text-green-400\",\n },\n valid: {\n title: \"text-foreground\",\n subtitle: \"text-green-700/80 dark:text-green-300/80\",\n icon: \"text-green-600 dark:text-green-400\",\n },\n ready: {\n title: \"text-foreground\",\n subtitle: \"text-green-700/80 dark:text-green-300/80\",\n icon: \"text-green-600 dark:text-green-400\",\n },\n warning: {\n title: \"text-foreground\",\n subtitle: \"text-amber-700/80 dark:text-amber-300/80\",\n icon: \"text-amber-600 dark:text-amber-400\",\n },\n critical: {\n title: \"text-foreground\",\n subtitle: \"text-red-700/80 dark:text-red-300/80\",\n icon: \"text-red-600 dark:text-red-400\",\n },\n risk: {\n title: \"text-foreground\",\n subtitle: \"text-red-700/80 dark:text-red-300/80\",\n icon: \"text-red-600 dark:text-red-400\",\n },\n normal: {\n title: \"text-foreground\",\n subtitle: \"text-muted-foreground\",\n icon: \"text-muted-foreground\",\n },\n pending: {\n title: \"text-foreground\",\n subtitle: \"text-muted-foreground\",\n icon: \"text-muted-foreground\",\n },\n shipped: {\n title: \"text-muted-foreground\",\n subtitle: \"text-muted-foreground/70\",\n icon: \"text-green-600/70 dark:text-green-400/70\",\n },\n} as const\n\n/**\n * Get combined status cell classes for a given status\n * @param status - The status type\n * @returns Object with border, bg, and combined classes\n */\nexport function getStatusCellClasses(status: keyof typeof statusCellFillClasses) {\n return statusCellFillClasses[status]\n}\n\n/**\n * Get status text classes for a given status\n * @param status - The status type\n * @returns Object with title, subtitle, and icon classes\n */\nexport function getStatusTextClasses(status: keyof typeof statusCellTextClasses) {\n return statusCellTextClasses[status]\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { MapContainer } from \"react-leaflet\"\nimport type { MapContainerProps } from \"react-leaflet\"\n\nimport { cn } from \"../../lib/utils\"\n\nexport interface MapProps extends Omit<MapContainerProps, \"center\" | \"zoom\"> {\n /** Map center coordinates [latitude, longitude] */\n center: [number, number]\n /** Initial zoom level (0-18) */\n zoom?: number\n /** Additional class names for the map container */\n className?: string\n /** Map content (TileLayer, Markers, etc.) */\n children?: React.ReactNode\n}\n\n/**\n * Map - Leaflet-based map component for Quantum UI\n * \n * A wrapper around react-leaflet's MapContainer with Quantum styling.\n * Requires explicit height on the container (via className or style).\n * \n * IMPORTANT: Consumer must import \"leaflet/dist/leaflet.css\" and handle\n * browser-only rendering (e.g., via React.lazy or dynamic import).\n * \n * @example\n * ```tsx\n * import \"leaflet/dist/leaflet.css\"\n * \n * <Map center={[57.7089, 11.9746]} zoom={12} className=\"h-[400px]\">\n * <MapTileLayer />\n * <MapMarker position={[57.7089, 11.9746]}>\n * <MapPopup>Hello!</MapPopup>\n * </MapMarker>\n * </Map>\n * ```\n */\nfunction Map({\n center,\n zoom = 13,\n className,\n children,\n ...props\n}: MapProps) {\n return (\n <MapContainer\n center={center}\n zoom={zoom}\n className={cn(\n \"w-full rounded-lg border border-border overflow-hidden\",\n \"[&_.leaflet-control-zoom]:border-border\",\n \"[&_.leaflet-control-zoom]:rounded-md\",\n \"[&_.leaflet-control-zoom]:shadow-sm\",\n \"[&_.leaflet-control-zoom-in]:rounded-t-md\",\n \"[&_.leaflet-control-zoom-in]:border-b\",\n \"[&_.leaflet-control-zoom-in]:border-border\",\n \"[&_.leaflet-control-zoom-out]:rounded-b-md\",\n \"[&_.leaflet-popup-content-wrapper]:rounded-lg\",\n \"[&_.leaflet-popup-content-wrapper]:shadow-lg\",\n \"[&_.leaflet-popup-content-wrapper]:border\",\n \"[&_.leaflet-popup-content-wrapper]:border-border\",\n className\n )}\n scrollWheelZoom={true}\n {...props}\n >\n {children}\n </MapContainer>\n )\n}\n\nexport { Map }\n","\"use client\"\n\nimport * as React from \"react\"\nimport { TileLayer } from \"react-leaflet\"\nimport type { TileLayerProps } from \"react-leaflet\"\n\nexport interface MapTileLayerProps extends Partial<TileLayerProps> {\n /** Tile layer variant */\n variant?: \"default\" | \"dark\" | \"satellite\"\n}\n\n// Tile layer URLs for different variants\nconst TILE_LAYERS = {\n default: {\n url: \"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\",\n attribution: '© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors',\n },\n dark: {\n url: \"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png\",\n attribution: '© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors © <a href=\"https://carto.com/attributions\">CARTO</a>',\n },\n satellite: {\n url: \"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}\",\n attribution: '© Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',\n },\n}\n\n/**\n * MapTileLayer - Tile layer for the Map component\n * \n * Provides different tile variants:\n * - default: OpenStreetMap standard tiles\n * - dark: Carto dark basemap (good for dark mode)\n * - satellite: Esri satellite imagery\n * \n * @example\n * ```tsx\n * <Map center={[57.7089, 11.9746]} zoom={12}>\n * <MapTileLayer variant=\"default\" />\n * </Map>\n * ```\n */\nfunction MapTileLayer({\n variant = \"default\",\n ...props\n}: MapTileLayerProps) {\n const layer = TILE_LAYERS[variant]\n \n return (\n <TileLayer\n url={layer.url}\n attribution={layer.attribution}\n {...props}\n />\n )\n}\n\nexport { MapTileLayer }\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Marker, Popup, Tooltip, ZoomControl } from \"react-leaflet\"\nimport type { MarkerProps, PopupProps, TooltipProps, ZoomControlProps } from \"react-leaflet\"\nimport type { LatLngExpression } from \"leaflet\"\n\nexport interface MapMarkerProps extends Omit<MarkerProps, \"position\"> {\n /** Marker position [latitude, longitude] */\n position: [number, number]\n /** Marker content (Popup, Tooltip, etc.) */\n children?: React.ReactNode\n}\n\n/**\n * MapMarker - Marker component for the Map\n * \n * Renders a marker at the specified position. Can contain Popup or Tooltip children.\n * \n * @example\n * ```tsx\n * <MapMarker position={[57.7089, 11.9746]}>\n * <MapPopup>Hello from Gothenburg!</MapPopup>\n * </MapMarker>\n * ```\n */\nfunction MapMarker({\n position,\n children,\n ...props\n}: MapMarkerProps) {\n return (\n <Marker position={position as LatLngExpression} {...props}>\n {children}\n </Marker>\n )\n}\n\nexport interface MapPopupProps extends PopupProps {\n /** Popup content */\n children?: React.ReactNode\n}\n\n/**\n * MapPopup - Popup component for MapMarker\n * \n * Displays a popup when the marker is clicked.\n * \n * @example\n * ```tsx\n * <MapMarker position={[57.7089, 11.9746]}>\n * <MapPopup>\n * <h3>Gothenburg</h3>\n * <p>Sweden's second largest city</p>\n * </MapPopup>\n * </MapMarker>\n * ```\n */\nfunction MapPopup({\n children,\n ...props\n}: MapPopupProps) {\n return (\n <Popup {...props}>\n <div className=\"text-sm\">\n {children}\n </div>\n </Popup>\n )\n}\n\nexport interface MapTooltipProps extends TooltipProps {\n /** Tooltip content */\n children?: React.ReactNode\n}\n\n/**\n * MapTooltip - Tooltip component for MapMarker\n * \n * Displays a tooltip on hover.\n * \n * @example\n * ```tsx\n * <MapMarker position={[57.7089, 11.9746]}>\n * <MapTooltip>Gothenburg</MapTooltip>\n * </MapMarker>\n * ```\n */\nfunction MapTooltip({\n children,\n ...props\n}: MapTooltipProps) {\n return (\n <Tooltip {...props}>\n {children}\n </Tooltip>\n )\n}\n\nexport interface MapZoomControlProps extends ZoomControlProps {}\n\n/**\n * MapZoomControl - Zoom control component for the Map\n * \n * Renders zoom in/out buttons. By default positioned top-right.\n * Note: MapContainer has built-in zoom controls, use this only if you need custom positioning.\n * \n * @example\n * ```tsx\n * <Map center={[57.7089, 11.9746]} zoom={12} zoomControl={false}>\n * <MapZoomControl position=\"bottomright\" />\n * </Map>\n * ```\n */\nfunction MapZoomControl(props: MapZoomControlProps) {\n return <ZoomControl {...props} />\n}\n\nexport { MapMarker, MapPopup, MapTooltip, MapZoomControl }\n"]}
|
package/dist/map.d.cts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { MapContainerProps, TileLayerProps, MarkerProps, PopupProps, TooltipProps, ZoomControlProps } from 'react-leaflet';
|
|
4
|
+
|
|
5
|
+
interface MapProps extends Omit<MapContainerProps, "center" | "zoom"> {
|
|
6
|
+
/** Map center coordinates [latitude, longitude] */
|
|
7
|
+
center: [number, number];
|
|
8
|
+
/** Initial zoom level (0-18) */
|
|
9
|
+
zoom?: number;
|
|
10
|
+
/** Additional class names for the map container */
|
|
11
|
+
className?: string;
|
|
12
|
+
/** Map content (TileLayer, Markers, etc.) */
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Map - Leaflet-based map component for Quantum UI
|
|
17
|
+
*
|
|
18
|
+
* A wrapper around react-leaflet's MapContainer with Quantum styling.
|
|
19
|
+
* Requires explicit height on the container (via className or style).
|
|
20
|
+
*
|
|
21
|
+
* IMPORTANT: Consumer must import "leaflet/dist/leaflet.css" and handle
|
|
22
|
+
* browser-only rendering (e.g., via React.lazy or dynamic import).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* import "leaflet/dist/leaflet.css"
|
|
27
|
+
*
|
|
28
|
+
* <Map center={[57.7089, 11.9746]} zoom={12} className="h-[400px]">
|
|
29
|
+
* <MapTileLayer />
|
|
30
|
+
* <MapMarker position={[57.7089, 11.9746]}>
|
|
31
|
+
* <MapPopup>Hello!</MapPopup>
|
|
32
|
+
* </MapMarker>
|
|
33
|
+
* </Map>
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
declare function Map({ center, zoom, className, children, ...props }: MapProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
|
|
38
|
+
interface MapTileLayerProps extends Partial<TileLayerProps> {
|
|
39
|
+
/** Tile layer variant */
|
|
40
|
+
variant?: "default" | "dark" | "satellite";
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* MapTileLayer - Tile layer for the Map component
|
|
44
|
+
*
|
|
45
|
+
* Provides different tile variants:
|
|
46
|
+
* - default: OpenStreetMap standard tiles
|
|
47
|
+
* - dark: Carto dark basemap (good for dark mode)
|
|
48
|
+
* - satellite: Esri satellite imagery
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* <Map center={[57.7089, 11.9746]} zoom={12}>
|
|
53
|
+
* <MapTileLayer variant="default" />
|
|
54
|
+
* </Map>
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
declare function MapTileLayer({ variant, ...props }: MapTileLayerProps): react_jsx_runtime.JSX.Element;
|
|
58
|
+
|
|
59
|
+
interface MapMarkerProps extends Omit<MarkerProps, "position"> {
|
|
60
|
+
/** Marker position [latitude, longitude] */
|
|
61
|
+
position: [number, number];
|
|
62
|
+
/** Marker content (Popup, Tooltip, etc.) */
|
|
63
|
+
children?: React.ReactNode;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* MapMarker - Marker component for the Map
|
|
67
|
+
*
|
|
68
|
+
* Renders a marker at the specified position. Can contain Popup or Tooltip children.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```tsx
|
|
72
|
+
* <MapMarker position={[57.7089, 11.9746]}>
|
|
73
|
+
* <MapPopup>Hello from Gothenburg!</MapPopup>
|
|
74
|
+
* </MapMarker>
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare function MapMarker({ position, children, ...props }: MapMarkerProps): react_jsx_runtime.JSX.Element;
|
|
78
|
+
interface MapPopupProps extends PopupProps {
|
|
79
|
+
/** Popup content */
|
|
80
|
+
children?: React.ReactNode;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* MapPopup - Popup component for MapMarker
|
|
84
|
+
*
|
|
85
|
+
* Displays a popup when the marker is clicked.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```tsx
|
|
89
|
+
* <MapMarker position={[57.7089, 11.9746]}>
|
|
90
|
+
* <MapPopup>
|
|
91
|
+
* <h3>Gothenburg</h3>
|
|
92
|
+
* <p>Sweden's second largest city</p>
|
|
93
|
+
* </MapPopup>
|
|
94
|
+
* </MapMarker>
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare function MapPopup({ children, ...props }: MapPopupProps): react_jsx_runtime.JSX.Element;
|
|
98
|
+
interface MapTooltipProps extends TooltipProps {
|
|
99
|
+
/** Tooltip content */
|
|
100
|
+
children?: React.ReactNode;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* MapTooltip - Tooltip component for MapMarker
|
|
104
|
+
*
|
|
105
|
+
* Displays a tooltip on hover.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```tsx
|
|
109
|
+
* <MapMarker position={[57.7089, 11.9746]}>
|
|
110
|
+
* <MapTooltip>Gothenburg</MapTooltip>
|
|
111
|
+
* </MapMarker>
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function MapTooltip({ children, ...props }: MapTooltipProps): react_jsx_runtime.JSX.Element;
|
|
115
|
+
interface MapZoomControlProps extends ZoomControlProps {
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* MapZoomControl - Zoom control component for the Map
|
|
119
|
+
*
|
|
120
|
+
* Renders zoom in/out buttons. By default positioned top-right.
|
|
121
|
+
* Note: MapContainer has built-in zoom controls, use this only if you need custom positioning.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```tsx
|
|
125
|
+
* <Map center={[57.7089, 11.9746]} zoom={12} zoomControl={false}>
|
|
126
|
+
* <MapZoomControl position="bottomright" />
|
|
127
|
+
* </Map>
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
declare function MapZoomControl(props: MapZoomControlProps): react_jsx_runtime.JSX.Element;
|
|
131
|
+
|
|
132
|
+
export { Map, MapMarker, type MapMarkerProps, MapPopup, type MapPopupProps, type MapProps, MapTileLayer, type MapTileLayerProps, MapTooltip, type MapTooltipProps, MapZoomControl, type MapZoomControlProps };
|
package/dist/map.d.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { MapContainerProps, TileLayerProps, MarkerProps, PopupProps, TooltipProps, ZoomControlProps } from 'react-leaflet';
|
|
4
|
+
|
|
5
|
+
interface MapProps extends Omit<MapContainerProps, "center" | "zoom"> {
|
|
6
|
+
/** Map center coordinates [latitude, longitude] */
|
|
7
|
+
center: [number, number];
|
|
8
|
+
/** Initial zoom level (0-18) */
|
|
9
|
+
zoom?: number;
|
|
10
|
+
/** Additional class names for the map container */
|
|
11
|
+
className?: string;
|
|
12
|
+
/** Map content (TileLayer, Markers, etc.) */
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Map - Leaflet-based map component for Quantum UI
|
|
17
|
+
*
|
|
18
|
+
* A wrapper around react-leaflet's MapContainer with Quantum styling.
|
|
19
|
+
* Requires explicit height on the container (via className or style).
|
|
20
|
+
*
|
|
21
|
+
* IMPORTANT: Consumer must import "leaflet/dist/leaflet.css" and handle
|
|
22
|
+
* browser-only rendering (e.g., via React.lazy or dynamic import).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* import "leaflet/dist/leaflet.css"
|
|
27
|
+
*
|
|
28
|
+
* <Map center={[57.7089, 11.9746]} zoom={12} className="h-[400px]">
|
|
29
|
+
* <MapTileLayer />
|
|
30
|
+
* <MapMarker position={[57.7089, 11.9746]}>
|
|
31
|
+
* <MapPopup>Hello!</MapPopup>
|
|
32
|
+
* </MapMarker>
|
|
33
|
+
* </Map>
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
declare function Map({ center, zoom, className, children, ...props }: MapProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
|
|
38
|
+
interface MapTileLayerProps extends Partial<TileLayerProps> {
|
|
39
|
+
/** Tile layer variant */
|
|
40
|
+
variant?: "default" | "dark" | "satellite";
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* MapTileLayer - Tile layer for the Map component
|
|
44
|
+
*
|
|
45
|
+
* Provides different tile variants:
|
|
46
|
+
* - default: OpenStreetMap standard tiles
|
|
47
|
+
* - dark: Carto dark basemap (good for dark mode)
|
|
48
|
+
* - satellite: Esri satellite imagery
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* <Map center={[57.7089, 11.9746]} zoom={12}>
|
|
53
|
+
* <MapTileLayer variant="default" />
|
|
54
|
+
* </Map>
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
declare function MapTileLayer({ variant, ...props }: MapTileLayerProps): react_jsx_runtime.JSX.Element;
|
|
58
|
+
|
|
59
|
+
interface MapMarkerProps extends Omit<MarkerProps, "position"> {
|
|
60
|
+
/** Marker position [latitude, longitude] */
|
|
61
|
+
position: [number, number];
|
|
62
|
+
/** Marker content (Popup, Tooltip, etc.) */
|
|
63
|
+
children?: React.ReactNode;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* MapMarker - Marker component for the Map
|
|
67
|
+
*
|
|
68
|
+
* Renders a marker at the specified position. Can contain Popup or Tooltip children.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```tsx
|
|
72
|
+
* <MapMarker position={[57.7089, 11.9746]}>
|
|
73
|
+
* <MapPopup>Hello from Gothenburg!</MapPopup>
|
|
74
|
+
* </MapMarker>
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare function MapMarker({ position, children, ...props }: MapMarkerProps): react_jsx_runtime.JSX.Element;
|
|
78
|
+
interface MapPopupProps extends PopupProps {
|
|
79
|
+
/** Popup content */
|
|
80
|
+
children?: React.ReactNode;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* MapPopup - Popup component for MapMarker
|
|
84
|
+
*
|
|
85
|
+
* Displays a popup when the marker is clicked.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```tsx
|
|
89
|
+
* <MapMarker position={[57.7089, 11.9746]}>
|
|
90
|
+
* <MapPopup>
|
|
91
|
+
* <h3>Gothenburg</h3>
|
|
92
|
+
* <p>Sweden's second largest city</p>
|
|
93
|
+
* </MapPopup>
|
|
94
|
+
* </MapMarker>
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare function MapPopup({ children, ...props }: MapPopupProps): react_jsx_runtime.JSX.Element;
|
|
98
|
+
interface MapTooltipProps extends TooltipProps {
|
|
99
|
+
/** Tooltip content */
|
|
100
|
+
children?: React.ReactNode;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* MapTooltip - Tooltip component for MapMarker
|
|
104
|
+
*
|
|
105
|
+
* Displays a tooltip on hover.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```tsx
|
|
109
|
+
* <MapMarker position={[57.7089, 11.9746]}>
|
|
110
|
+
* <MapTooltip>Gothenburg</MapTooltip>
|
|
111
|
+
* </MapMarker>
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function MapTooltip({ children, ...props }: MapTooltipProps): react_jsx_runtime.JSX.Element;
|
|
115
|
+
interface MapZoomControlProps extends ZoomControlProps {
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* MapZoomControl - Zoom control component for the Map
|
|
119
|
+
*
|
|
120
|
+
* Renders zoom in/out buttons. By default positioned top-right.
|
|
121
|
+
* Note: MapContainer has built-in zoom controls, use this only if you need custom positioning.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```tsx
|
|
125
|
+
* <Map center={[57.7089, 11.9746]} zoom={12} zoomControl={false}>
|
|
126
|
+
* <MapZoomControl position="bottomright" />
|
|
127
|
+
* </Map>
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
declare function MapZoomControl(props: MapZoomControlProps): react_jsx_runtime.JSX.Element;
|
|
131
|
+
|
|
132
|
+
export { Map, MapMarker, type MapMarkerProps, MapPopup, type MapPopupProps, type MapProps, MapTileLayer, type MapTileLayerProps, MapTooltip, type MapTooltipProps, MapZoomControl, type MapZoomControlProps };
|
package/dist/map.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { MapContainer, TileLayer, Marker, Popup, Tooltip, ZoomControl } from 'react-leaflet';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/components/map/map.tsx
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
function Map({
|
|
11
|
+
center,
|
|
12
|
+
zoom = 13,
|
|
13
|
+
className,
|
|
14
|
+
children,
|
|
15
|
+
...props
|
|
16
|
+
}) {
|
|
17
|
+
return /* @__PURE__ */ jsx(
|
|
18
|
+
MapContainer,
|
|
19
|
+
{
|
|
20
|
+
center,
|
|
21
|
+
zoom,
|
|
22
|
+
className: cn(
|
|
23
|
+
"w-full rounded-lg border border-border overflow-hidden",
|
|
24
|
+
"[&_.leaflet-control-zoom]:border-border",
|
|
25
|
+
"[&_.leaflet-control-zoom]:rounded-md",
|
|
26
|
+
"[&_.leaflet-control-zoom]:shadow-sm",
|
|
27
|
+
"[&_.leaflet-control-zoom-in]:rounded-t-md",
|
|
28
|
+
"[&_.leaflet-control-zoom-in]:border-b",
|
|
29
|
+
"[&_.leaflet-control-zoom-in]:border-border",
|
|
30
|
+
"[&_.leaflet-control-zoom-out]:rounded-b-md",
|
|
31
|
+
"[&_.leaflet-popup-content-wrapper]:rounded-lg",
|
|
32
|
+
"[&_.leaflet-popup-content-wrapper]:shadow-lg",
|
|
33
|
+
"[&_.leaflet-popup-content-wrapper]:border",
|
|
34
|
+
"[&_.leaflet-popup-content-wrapper]:border-border",
|
|
35
|
+
className
|
|
36
|
+
),
|
|
37
|
+
scrollWheelZoom: true,
|
|
38
|
+
...props,
|
|
39
|
+
children
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
var TILE_LAYERS = {
|
|
44
|
+
default: {
|
|
45
|
+
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
46
|
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
47
|
+
},
|
|
48
|
+
dark: {
|
|
49
|
+
url: "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
|
|
50
|
+
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>'
|
|
51
|
+
},
|
|
52
|
+
satellite: {
|
|
53
|
+
url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
|
54
|
+
attribution: "© Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
function MapTileLayer({
|
|
58
|
+
variant = "default",
|
|
59
|
+
...props
|
|
60
|
+
}) {
|
|
61
|
+
const layer = TILE_LAYERS[variant];
|
|
62
|
+
return /* @__PURE__ */ jsx(
|
|
63
|
+
TileLayer,
|
|
64
|
+
{
|
|
65
|
+
url: layer.url,
|
|
66
|
+
attribution: layer.attribution,
|
|
67
|
+
...props
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
function MapMarker({
|
|
72
|
+
position,
|
|
73
|
+
children,
|
|
74
|
+
...props
|
|
75
|
+
}) {
|
|
76
|
+
return /* @__PURE__ */ jsx(Marker, { position, ...props, children });
|
|
77
|
+
}
|
|
78
|
+
function MapPopup({
|
|
79
|
+
children,
|
|
80
|
+
...props
|
|
81
|
+
}) {
|
|
82
|
+
return /* @__PURE__ */ jsx(Popup, { ...props, children: /* @__PURE__ */ jsx("div", { className: "text-sm", children }) });
|
|
83
|
+
}
|
|
84
|
+
function MapTooltip({
|
|
85
|
+
children,
|
|
86
|
+
...props
|
|
87
|
+
}) {
|
|
88
|
+
return /* @__PURE__ */ jsx(Tooltip, { ...props, children });
|
|
89
|
+
}
|
|
90
|
+
function MapZoomControl(props) {
|
|
91
|
+
return /* @__PURE__ */ jsx(ZoomControl, { ...props });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { Map, MapMarker, MapPopup, MapTileLayer, MapTooltip, MapZoomControl };
|
|
95
|
+
//# sourceMappingURL=map.js.map
|
|
96
|
+
//# sourceMappingURL=map.js.map
|
package/dist/map.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/map/map.tsx","../src/components/map/map-tile-layer.tsx","../src/components/map/map-marker.tsx"],"names":["jsx"],"mappings":";;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACmCA,SAAS,GAAA,CAAI;AAAA,EACX,MAAA;AAAA,EACA,IAAA,GAAO,EAAA;AAAA,EACP,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAa;AACX,EAAA,uBACE,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,IAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,wDAAA;AAAA,QACA,yCAAA;AAAA,QACA,sCAAA;AAAA,QACA,qCAAA;AAAA,QACA,2CAAA;AAAA,QACA,uCAAA;AAAA,QACA,4CAAA;AAAA,QACA,4CAAA;AAAA,QACA,+CAAA;AAAA,QACA,8CAAA;AAAA,QACA,2CAAA;AAAA,QACA,kDAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,eAAA,EAAiB,IAAA;AAAA,MAChB,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AC5DA,IAAM,WAAA,GAAc;AAAA,EAClB,OAAA,EAAS;AAAA,IACP,GAAA,EAAK,oDAAA;AAAA,IACL,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,+DAAA;AAAA,IACL,WAAA,EAAa;AAAA,GACf;AAAA,EACA,SAAA,EAAW;AAAA,IACT,GAAA,EAAK,+FAAA;AAAA,IACL,WAAA,EAAa;AAAA;AAEjB,CAAA;AAiBA,SAAS,YAAA,CAAa;AAAA,EACpB,OAAA,GAAU,SAAA;AAAA,EACV,GAAG;AACL,CAAA,EAAsB;AACpB,EAAA,MAAM,KAAA,GAAQ,YAAY,OAAO,CAAA;AAEjC,EAAA,uBACEA,GAAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,KAAK,KAAA,CAAM,GAAA;AAAA,MACX,aAAa,KAAA,CAAM,WAAA;AAAA,MAClB,GAAG;AAAA;AAAA,GACN;AAEJ;AC7BA,SAAS,SAAA,CAAU;AAAA,EACjB,QAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAmB;AACjB,EAAA,uBACEA,GAAAA,CAAC,MAAA,EAAA,EAAO,QAAA,EAAyC,GAAG,OACjD,QAAA,EACH,CAAA;AAEJ;AAsBA,SAAS,QAAA,CAAS;AAAA,EAChB,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAkB;AAChB,EAAA,uBACEA,GAAAA,CAAC,KAAA,EAAA,EAAO,GAAG,KAAA,EACT,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,SAAA,EACZ,QAAA,EACH,CAAA,EACF,CAAA;AAEJ;AAmBA,SAAS,UAAA,CAAW;AAAA,EAClB,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAoB;AAClB,EAAA,uBACEA,GAAAA,CAAC,OAAA,EAAA,EAAS,GAAG,OACV,QAAA,EACH,CAAA;AAEJ;AAiBA,SAAS,eAAe,KAAA,EAA4B;AAClD,EAAA,uBAAOA,GAAAA,CAAC,WAAA,EAAA,EAAa,GAAG,KAAA,EAAO,CAAA;AACjC","file":"map.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\n// ============================================================================\n// SHARED STATUS CELL CLASSES\n// Reusable status fill classes for calibration table, planning table,\n// and supplier loading cards. Ensures visual consistency across components.\n// ============================================================================\n\n/**\n * Status types for cell/card fills\n * - complete/valid: Green - task is done\n * - warning: Amber - needs attention\n * - critical/risk: Red - at risk, urgent\n * - normal/pending: Grey - neutral, on track but not done\n * - shipped: Muted + green accent - completed delivery (distinct from complete)\n */\nexport type StatusCellType = \n | \"complete\" \n | \"valid\" \n | \"warning\" \n | \"critical\" \n | \"risk\" \n | \"normal\" \n | \"pending\" \n | \"shipped\"\n\n/**\n * Status cell fill classes - matching calibration/planning table styling\n * Uses left stroke (3px) + full background fill\n * \n * Pattern: \n * - Green = complete/valid/ready\n * - Amber = warning/attention\n * - Red = critical/risk\n * - Grey = normal/pending/neutral\n * - Muted = shipped (greyed out with green check)\n */\nexport const statusCellFillClasses = {\n // Green - complete/valid/ready state\n complete: {\n border: \"border-l-[3px] border-l-green-500\",\n bg: \"bg-green-50/50 dark:bg-green-950/30\",\n combined: \"border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30\",\n },\n valid: {\n border: \"border-l-[3px] border-l-green-500\",\n bg: \"bg-green-50/50 dark:bg-green-950/30\",\n combined: \"border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30\",\n },\n ready: {\n border: \"border-l-[3px] border-l-green-500\",\n bg: \"bg-green-50/50 dark:bg-green-950/30\",\n combined: \"border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30\",\n },\n \n // Amber - warning/attention state\n warning: {\n border: \"border-l-[3px] border-l-amber-500\",\n bg: \"bg-amber-50/50 dark:bg-amber-950/30\",\n combined: \"border-l-[3px] border-l-amber-500 bg-amber-50/50 dark:bg-amber-950/30\",\n },\n \n // Red - critical/risk state\n critical: {\n border: \"border-l-[3px] border-l-red-500\",\n bg: \"bg-red-50/50 dark:bg-red-950/30\",\n combined: \"border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30\",\n },\n risk: {\n border: \"border-l-[3px] border-l-red-500\",\n bg: \"bg-red-50/50 dark:bg-red-950/30\",\n combined: \"border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30\",\n },\n \n // Grey - normal/pending/neutral state (on track but not complete)\n normal: {\n border: \"border-l-[3px] border-l-muted-foreground/40\",\n bg: \"bg-muted/30 dark:bg-muted/20\",\n combined: \"border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20\",\n },\n pending: {\n border: \"border-l-[3px] border-l-muted-foreground/40\",\n bg: \"bg-muted/30 dark:bg-muted/20\",\n combined: \"border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20\",\n },\n \n // Shipped - distinct muted state with green accent (greyed out + check)\n shipped: {\n border: \"border-l-[3px] border-l-green-500/50\",\n bg: \"bg-muted/50 dark:bg-muted/30\",\n combined: \"border-l-[3px] border-l-green-500/50 bg-muted/50 dark:bg-muted/30\",\n },\n} as const\n\n/**\n * Status text colors for use inside status cells\n */\nexport const statusCellTextClasses = {\n complete: {\n title: \"text-foreground\",\n subtitle: \"text-green-700/80 dark:text-green-300/80\",\n icon: \"text-green-600 dark:text-green-400\",\n },\n valid: {\n title: \"text-foreground\",\n subtitle: \"text-green-700/80 dark:text-green-300/80\",\n icon: \"text-green-600 dark:text-green-400\",\n },\n ready: {\n title: \"text-foreground\",\n subtitle: \"text-green-700/80 dark:text-green-300/80\",\n icon: \"text-green-600 dark:text-green-400\",\n },\n warning: {\n title: \"text-foreground\",\n subtitle: \"text-amber-700/80 dark:text-amber-300/80\",\n icon: \"text-amber-600 dark:text-amber-400\",\n },\n critical: {\n title: \"text-foreground\",\n subtitle: \"text-red-700/80 dark:text-red-300/80\",\n icon: \"text-red-600 dark:text-red-400\",\n },\n risk: {\n title: \"text-foreground\",\n subtitle: \"text-red-700/80 dark:text-red-300/80\",\n icon: \"text-red-600 dark:text-red-400\",\n },\n normal: {\n title: \"text-foreground\",\n subtitle: \"text-muted-foreground\",\n icon: \"text-muted-foreground\",\n },\n pending: {\n title: \"text-foreground\",\n subtitle: \"text-muted-foreground\",\n icon: \"text-muted-foreground\",\n },\n shipped: {\n title: \"text-muted-foreground\",\n subtitle: \"text-muted-foreground/70\",\n icon: \"text-green-600/70 dark:text-green-400/70\",\n },\n} as const\n\n/**\n * Get combined status cell classes for a given status\n * @param status - The status type\n * @returns Object with border, bg, and combined classes\n */\nexport function getStatusCellClasses(status: keyof typeof statusCellFillClasses) {\n return statusCellFillClasses[status]\n}\n\n/**\n * Get status text classes for a given status\n * @param status - The status type\n * @returns Object with title, subtitle, and icon classes\n */\nexport function getStatusTextClasses(status: keyof typeof statusCellTextClasses) {\n return statusCellTextClasses[status]\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { MapContainer } from \"react-leaflet\"\nimport type { MapContainerProps } from \"react-leaflet\"\n\nimport { cn } from \"../../lib/utils\"\n\nexport interface MapProps extends Omit<MapContainerProps, \"center\" | \"zoom\"> {\n /** Map center coordinates [latitude, longitude] */\n center: [number, number]\n /** Initial zoom level (0-18) */\n zoom?: number\n /** Additional class names for the map container */\n className?: string\n /** Map content (TileLayer, Markers, etc.) */\n children?: React.ReactNode\n}\n\n/**\n * Map - Leaflet-based map component for Quantum UI\n * \n * A wrapper around react-leaflet's MapContainer with Quantum styling.\n * Requires explicit height on the container (via className or style).\n * \n * IMPORTANT: Consumer must import \"leaflet/dist/leaflet.css\" and handle\n * browser-only rendering (e.g., via React.lazy or dynamic import).\n * \n * @example\n * ```tsx\n * import \"leaflet/dist/leaflet.css\"\n * \n * <Map center={[57.7089, 11.9746]} zoom={12} className=\"h-[400px]\">\n * <MapTileLayer />\n * <MapMarker position={[57.7089, 11.9746]}>\n * <MapPopup>Hello!</MapPopup>\n * </MapMarker>\n * </Map>\n * ```\n */\nfunction Map({\n center,\n zoom = 13,\n className,\n children,\n ...props\n}: MapProps) {\n return (\n <MapContainer\n center={center}\n zoom={zoom}\n className={cn(\n \"w-full rounded-lg border border-border overflow-hidden\",\n \"[&_.leaflet-control-zoom]:border-border\",\n \"[&_.leaflet-control-zoom]:rounded-md\",\n \"[&_.leaflet-control-zoom]:shadow-sm\",\n \"[&_.leaflet-control-zoom-in]:rounded-t-md\",\n \"[&_.leaflet-control-zoom-in]:border-b\",\n \"[&_.leaflet-control-zoom-in]:border-border\",\n \"[&_.leaflet-control-zoom-out]:rounded-b-md\",\n \"[&_.leaflet-popup-content-wrapper]:rounded-lg\",\n \"[&_.leaflet-popup-content-wrapper]:shadow-lg\",\n \"[&_.leaflet-popup-content-wrapper]:border\",\n \"[&_.leaflet-popup-content-wrapper]:border-border\",\n className\n )}\n scrollWheelZoom={true}\n {...props}\n >\n {children}\n </MapContainer>\n )\n}\n\nexport { Map }\n","\"use client\"\n\nimport * as React from \"react\"\nimport { TileLayer } from \"react-leaflet\"\nimport type { TileLayerProps } from \"react-leaflet\"\n\nexport interface MapTileLayerProps extends Partial<TileLayerProps> {\n /** Tile layer variant */\n variant?: \"default\" | \"dark\" | \"satellite\"\n}\n\n// Tile layer URLs for different variants\nconst TILE_LAYERS = {\n default: {\n url: \"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\",\n attribution: '© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors',\n },\n dark: {\n url: \"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png\",\n attribution: '© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors © <a href=\"https://carto.com/attributions\">CARTO</a>',\n },\n satellite: {\n url: \"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}\",\n attribution: '© Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',\n },\n}\n\n/**\n * MapTileLayer - Tile layer for the Map component\n * \n * Provides different tile variants:\n * - default: OpenStreetMap standard tiles\n * - dark: Carto dark basemap (good for dark mode)\n * - satellite: Esri satellite imagery\n * \n * @example\n * ```tsx\n * <Map center={[57.7089, 11.9746]} zoom={12}>\n * <MapTileLayer variant=\"default\" />\n * </Map>\n * ```\n */\nfunction MapTileLayer({\n variant = \"default\",\n ...props\n}: MapTileLayerProps) {\n const layer = TILE_LAYERS[variant]\n \n return (\n <TileLayer\n url={layer.url}\n attribution={layer.attribution}\n {...props}\n />\n )\n}\n\nexport { MapTileLayer }\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Marker, Popup, Tooltip, ZoomControl } from \"react-leaflet\"\nimport type { MarkerProps, PopupProps, TooltipProps, ZoomControlProps } from \"react-leaflet\"\nimport type { LatLngExpression } from \"leaflet\"\n\nexport interface MapMarkerProps extends Omit<MarkerProps, \"position\"> {\n /** Marker position [latitude, longitude] */\n position: [number, number]\n /** Marker content (Popup, Tooltip, etc.) */\n children?: React.ReactNode\n}\n\n/**\n * MapMarker - Marker component for the Map\n * \n * Renders a marker at the specified position. Can contain Popup or Tooltip children.\n * \n * @example\n * ```tsx\n * <MapMarker position={[57.7089, 11.9746]}>\n * <MapPopup>Hello from Gothenburg!</MapPopup>\n * </MapMarker>\n * ```\n */\nfunction MapMarker({\n position,\n children,\n ...props\n}: MapMarkerProps) {\n return (\n <Marker position={position as LatLngExpression} {...props}>\n {children}\n </Marker>\n )\n}\n\nexport interface MapPopupProps extends PopupProps {\n /** Popup content */\n children?: React.ReactNode\n}\n\n/**\n * MapPopup - Popup component for MapMarker\n * \n * Displays a popup when the marker is clicked.\n * \n * @example\n * ```tsx\n * <MapMarker position={[57.7089, 11.9746]}>\n * <MapPopup>\n * <h3>Gothenburg</h3>\n * <p>Sweden's second largest city</p>\n * </MapPopup>\n * </MapMarker>\n * ```\n */\nfunction MapPopup({\n children,\n ...props\n}: MapPopupProps) {\n return (\n <Popup {...props}>\n <div className=\"text-sm\">\n {children}\n </div>\n </Popup>\n )\n}\n\nexport interface MapTooltipProps extends TooltipProps {\n /** Tooltip content */\n children?: React.ReactNode\n}\n\n/**\n * MapTooltip - Tooltip component for MapMarker\n * \n * Displays a tooltip on hover.\n * \n * @example\n * ```tsx\n * <MapMarker position={[57.7089, 11.9746]}>\n * <MapTooltip>Gothenburg</MapTooltip>\n * </MapMarker>\n * ```\n */\nfunction MapTooltip({\n children,\n ...props\n}: MapTooltipProps) {\n return (\n <Tooltip {...props}>\n {children}\n </Tooltip>\n )\n}\n\nexport interface MapZoomControlProps extends ZoomControlProps {}\n\n/**\n * MapZoomControl - Zoom control component for the Map\n * \n * Renders zoom in/out buttons. By default positioned top-right.\n * Note: MapContainer has built-in zoom controls, use this only if you need custom positioning.\n * \n * @example\n * ```tsx\n * <Map center={[57.7089, 11.9746]} zoom={12} zoomControl={false}>\n * <MapZoomControl position=\"bottomright\" />\n * </Map>\n * ```\n */\nfunction MapZoomControl(props: MapZoomControlProps) {\n return <ZoomControl {...props} />\n}\n\nexport { MapMarker, MapPopup, MapTooltip, MapZoomControl }\n"]}
|
package/dist/styles/index.css
CHANGED
|
@@ -664,6 +664,7 @@
|
|
|
664
664
|
--color-destructive: var(--destructive);
|
|
665
665
|
--color-destructive-foreground: var(--destructive-foreground);
|
|
666
666
|
--color-border: var(--border);
|
|
667
|
+
--color-border-subtle: color-mix(in srgb, var(--border) 40%, transparent);
|
|
667
668
|
--color-input: var(--input);
|
|
668
669
|
--color-ring: var(--ring);
|
|
669
670
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@j3m-quantum/ui",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "J3M UI Component Library - React components with J3M design tokens",
|
|
6
6
|
"type": "module",
|
|
@@ -21,6 +21,16 @@
|
|
|
21
21
|
"default": "./dist/index.cjs"
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
|
+
"./map": {
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./dist/map.d.ts",
|
|
27
|
+
"default": "./dist/map.js"
|
|
28
|
+
},
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./dist/map.d.cts",
|
|
31
|
+
"default": "./dist/map.cjs"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
24
34
|
"./styles": "./dist/styles/index.css",
|
|
25
35
|
"./styles/*": "./dist/styles/*"
|
|
26
36
|
},
|
|
@@ -103,21 +113,11 @@
|
|
|
103
113
|
"vaul": "^1.0.0"
|
|
104
114
|
},
|
|
105
115
|
"peerDependencies": {
|
|
106
|
-
"leaflet": "^1.9.4",
|
|
107
116
|
"react": ">=18",
|
|
108
117
|
"react-dom": ">=18",
|
|
109
|
-
"react-leaflet": "^5.0.0",
|
|
110
118
|
"tailwindcss": ">=4",
|
|
111
119
|
"tw-animate-css": "^1.0.0"
|
|
112
120
|
},
|
|
113
|
-
"peerDependenciesMeta": {
|
|
114
|
-
"leaflet": {
|
|
115
|
-
"optional": true
|
|
116
|
-
},
|
|
117
|
-
"react-leaflet": {
|
|
118
|
-
"optional": true
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
121
|
"devDependencies": {
|
|
122
122
|
"@changesets/cli": "^2.29.4",
|
|
123
123
|
"@types/leaflet": "^1.9.12",
|