@zekidev/ui 2.1.0 → 2.2.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/dist/components/section-shell.d.ts +13 -0
- package/dist/index.cjs +6243 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1395 -1106
- package/dist/types/index.d.ts +11 -0
- package/package.json +17 -27
- package/src/styles/globals.css +8 -8
- package/dist/leaflet-map-inner-SOHFKEYD.js +0 -171
package/dist/types/index.d.ts
CHANGED
|
@@ -45,6 +45,14 @@ export interface SectionBase {
|
|
|
45
45
|
paddingTop?: "none" | "sm" | "md" | "lg" | "xl";
|
|
46
46
|
paddingBottom?: "none" | "sm" | "md" | "lg" | "xl";
|
|
47
47
|
background?: "default" | "muted" | "primary" | "secondary" | "success" | "info" | "warning" | "error";
|
|
48
|
+
/** Decorative background image (shown behind section content) */
|
|
49
|
+
backgroundImage?: MediaAsset;
|
|
50
|
+
/** Direct URL to a .mp4 file. Not played on mobile. */
|
|
51
|
+
backgroundVideoUrl?: string;
|
|
52
|
+
/** 0–100 opacity of a dark overlay on top of background media */
|
|
53
|
+
backgroundOverlay?: number;
|
|
54
|
+
/** Fade-in entrance animation triggered on scroll */
|
|
55
|
+
animate?: boolean;
|
|
48
56
|
}
|
|
49
57
|
export type HeroVariant = "centered" | "split" | "left" | "video" | "minimal" | "background" | "card";
|
|
50
58
|
export interface HeroSection extends SectionBase {
|
|
@@ -407,15 +415,18 @@ export interface BackgroundMusic {
|
|
|
407
415
|
*/
|
|
408
416
|
autoplayOnInteraction?: boolean;
|
|
409
417
|
}
|
|
418
|
+
export type NotFoundVariant = "centered" | "split" | "minimal";
|
|
410
419
|
export interface SiteSettings {
|
|
411
420
|
_id: string;
|
|
412
421
|
_type: "siteSettings";
|
|
413
422
|
siteName: string;
|
|
414
423
|
logo?: MediaAsset;
|
|
424
|
+
favicon?: MediaAsset;
|
|
415
425
|
theme: SiteTheme;
|
|
416
426
|
headerVariant?: HeaderVariant;
|
|
417
427
|
footerVariant?: FooterVariant;
|
|
418
428
|
layoutVariant?: LayoutVariant;
|
|
429
|
+
notFoundVariant?: NotFoundVariant;
|
|
419
430
|
navigation?: {
|
|
420
431
|
links: {
|
|
421
432
|
label: string;
|
package/package.json
CHANGED
|
@@ -1,43 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zekidev/ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
|
-
"types": "./
|
|
8
|
-
"import": "./
|
|
9
|
-
"
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js",
|
|
9
|
+
"require": "./dist/index.cjs",
|
|
10
|
+
"default": "./dist/index.js"
|
|
10
11
|
},
|
|
11
12
|
"./styles": "./src/styles/globals.css",
|
|
12
13
|
"./tailwind-config": "./tailwind.config.ts"
|
|
13
14
|
},
|
|
14
|
-
"main": "./
|
|
15
|
-
"types": "./
|
|
15
|
+
"main": "./dist/index.cjs",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
16
17
|
"files": [
|
|
17
18
|
"dist",
|
|
18
19
|
"src/styles",
|
|
19
20
|
"tailwind.config.ts"
|
|
20
21
|
],
|
|
21
22
|
"publishConfig": {
|
|
22
|
-
"access": "public"
|
|
23
|
-
"exports": {
|
|
24
|
-
".": {
|
|
25
|
-
"types": "./dist/index.d.ts",
|
|
26
|
-
"import": "./dist/index.js",
|
|
27
|
-
"default": "./dist/index.js"
|
|
28
|
-
},
|
|
29
|
-
"./styles": "./src/styles/globals.css",
|
|
30
|
-
"./tailwind-config": "./tailwind.config.ts"
|
|
31
|
-
},
|
|
32
|
-
"main": "./dist/index.js",
|
|
33
|
-
"module": "./dist/index.js",
|
|
34
|
-
"types": "./dist/index.d.ts"
|
|
35
|
-
},
|
|
36
|
-
"scripts": {
|
|
37
|
-
"build": "tsup && tsc -p tsconfig.build.json",
|
|
38
|
-
"dev": "tsup --watch",
|
|
39
|
-
"type-check": "tsc --noEmit",
|
|
40
|
-
"lint": "eslint src --ext ts,tsx"
|
|
23
|
+
"access": "public"
|
|
41
24
|
},
|
|
42
25
|
"dependencies": {
|
|
43
26
|
"@portabletext/react": "^3.0.0",
|
|
@@ -73,5 +56,12 @@
|
|
|
73
56
|
"tailwindcss": "^3.4.0",
|
|
74
57
|
"tsup": "^8.0.0",
|
|
75
58
|
"typescript": "^5.4.0"
|
|
76
|
-
}
|
|
77
|
-
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "tsup && tsc -p tsconfig.build.json",
|
|
62
|
+
"dev": "tsup --watch",
|
|
63
|
+
"type-check": "tsc --noEmit",
|
|
64
|
+
"lint": "eslint src --ext ts,tsx"
|
|
65
|
+
},
|
|
66
|
+
"module": "./dist/index.js"
|
|
67
|
+
}
|
package/src/styles/globals.css
CHANGED
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
--input: 214.3 31.8% 91.4%;
|
|
74
74
|
--ring: 221.2 83.2% 53.3%;
|
|
75
75
|
}
|
|
76
|
-
.dark
|
|
76
|
+
.dark[data-palette="default"],
|
|
77
77
|
.dark:not([data-palette]) {
|
|
78
78
|
--background: 222.2 84% 4.9%;
|
|
79
79
|
--foreground: 210 40% 98%;
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
--input: 240 5.9% 90%;
|
|
119
119
|
--ring: 346.8 77.2% 49.8%;
|
|
120
120
|
}
|
|
121
|
-
.dark
|
|
121
|
+
.dark[data-palette="rose"] {
|
|
122
122
|
--background: 20 14.3% 4.1%;
|
|
123
123
|
--foreground: 0 0% 95%;
|
|
124
124
|
--card: 24 9.8% 10%;
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
--input: 20 5.9% 90%;
|
|
163
163
|
--ring: 24.6 95% 53.1%;
|
|
164
164
|
}
|
|
165
|
-
.dark
|
|
165
|
+
.dark[data-palette="orange"] {
|
|
166
166
|
--background: 20 14.3% 4.1%;
|
|
167
167
|
--foreground: 60 9.1% 97.8%;
|
|
168
168
|
--card: 20 14.3% 4.1%;
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
--input: 240 5.9% 90%;
|
|
207
207
|
--ring: 142.1 76.2% 36.3%;
|
|
208
208
|
}
|
|
209
|
-
.dark
|
|
209
|
+
.dark[data-palette="green"] {
|
|
210
210
|
--background: 20 14.3% 4.1%;
|
|
211
211
|
--foreground: 0 0% 95%;
|
|
212
212
|
--card: 24 9.8% 10%;
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
--input: 220 13% 91%;
|
|
251
251
|
--ring: 262.1 83.3% 57.8%;
|
|
252
252
|
}
|
|
253
|
-
.dark
|
|
253
|
+
.dark[data-palette="violet"] {
|
|
254
254
|
--background: 224 71.4% 4.1%;
|
|
255
255
|
--foreground: 210 20% 98%;
|
|
256
256
|
--card: 224 71.4% 4.1%;
|
|
@@ -294,7 +294,7 @@
|
|
|
294
294
|
--input: 214.3 31.8% 91.4%;
|
|
295
295
|
--ring: 173 80% 36%;
|
|
296
296
|
}
|
|
297
|
-
.dark
|
|
297
|
+
.dark[data-palette="teal"] {
|
|
298
298
|
--background: 222.2 84% 4.9%;
|
|
299
299
|
--foreground: 210 40% 98%;
|
|
300
300
|
--card: 222.2 84% 4.9%;
|
|
@@ -338,7 +338,7 @@
|
|
|
338
338
|
--input: 20 5.9% 90%;
|
|
339
339
|
--ring: 47.9 95.8% 53.1%;
|
|
340
340
|
}
|
|
341
|
-
.dark
|
|
341
|
+
.dark[data-palette="yellow"] {
|
|
342
342
|
--background: 20 14.3% 4.1%;
|
|
343
343
|
--foreground: 60 9.1% 97.8%;
|
|
344
344
|
--card: 20 14.3% 4.1%;
|
|
@@ -382,7 +382,7 @@
|
|
|
382
382
|
--input: 240 5.9% 90%;
|
|
383
383
|
--ring: 0 72.2% 50.6%;
|
|
384
384
|
}
|
|
385
|
-
.dark
|
|
385
|
+
.dark[data-palette="red"] {
|
|
386
386
|
--background: 20 14.3% 4.1%;
|
|
387
387
|
--foreground: 0 0% 95%;
|
|
388
388
|
--card: 24 9.8% 10%;
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
// src/sections/map/leaflet-map-inner.tsx
|
|
4
|
-
import "leaflet/dist/leaflet.css";
|
|
5
|
-
import { useEffect, useRef, useState } from "react";
|
|
6
|
-
import L from "leaflet";
|
|
7
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
var OSM_ATTR = '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';
|
|
9
|
-
var CARTO_ATTR = `${OSM_ATTR} © <a href="https://carto.com/attributions">CARTO</a>`;
|
|
10
|
-
var ESRI_ATTR = "Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community";
|
|
11
|
-
var TILES = {
|
|
12
|
-
// OpenStreetMap
|
|
13
|
-
standard: {
|
|
14
|
-
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
15
|
-
attribution: OSM_ATTR
|
|
16
|
-
},
|
|
17
|
-
// CartoDB Positron — clean, minimal, ideal for data overlays
|
|
18
|
-
light: {
|
|
19
|
-
url: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
|
|
20
|
-
attribution: CARTO_ATTR
|
|
21
|
-
},
|
|
22
|
-
// CartoDB Dark Matter
|
|
23
|
-
dark: {
|
|
24
|
-
url: "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
|
|
25
|
-
attribution: CARTO_ATTR
|
|
26
|
-
},
|
|
27
|
-
// CartoDB Voyager — colorful, modern
|
|
28
|
-
voyager: {
|
|
29
|
-
url: "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
|
|
30
|
-
attribution: CARTO_ATTR
|
|
31
|
-
},
|
|
32
|
-
// OpenTopoMap — topographic with elevation contours
|
|
33
|
-
topo: {
|
|
34
|
-
url: "https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
35
|
-
attribution: `${OSM_ATTR}, <a href="https://viewfinderpanoramas.org">SRTM</a> | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a>`,
|
|
36
|
-
maxZoom: 17
|
|
37
|
-
},
|
|
38
|
-
// ESRI World Imagery — satellite/aerial photography
|
|
39
|
-
satellite: {
|
|
40
|
-
url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
|
41
|
-
attribution: ESRI_ATTR,
|
|
42
|
-
maxZoom: 18
|
|
43
|
-
},
|
|
44
|
-
// ESRI World Street Map — detailed street basemap
|
|
45
|
-
streets: {
|
|
46
|
-
url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}",
|
|
47
|
-
attribution: ESRI_ATTR,
|
|
48
|
-
maxZoom: 18
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
var markerIcon = new L.Icon({
|
|
52
|
-
iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png",
|
|
53
|
-
iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png",
|
|
54
|
-
shadowUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png",
|
|
55
|
-
iconSize: [25, 41],
|
|
56
|
-
iconAnchor: [12, 41],
|
|
57
|
-
popupAnchor: [1, -34],
|
|
58
|
-
shadowSize: [41, 41]
|
|
59
|
-
});
|
|
60
|
-
async function geocodeAddress(address) {
|
|
61
|
-
try {
|
|
62
|
-
const res = await fetch(
|
|
63
|
-
`https://nominatim.openstreetmap.org/search?format=json&limit=1&q=${encodeURIComponent(address)}`,
|
|
64
|
-
{ headers: { "Accept-Language": "en", "User-Agent": "LandingBuilder/1.0" } }
|
|
65
|
-
);
|
|
66
|
-
if (!res.ok) return null;
|
|
67
|
-
const data = await res.json();
|
|
68
|
-
if (!data.length) return null;
|
|
69
|
-
return [parseFloat(data[0].lat), parseFloat(data[0].lon)];
|
|
70
|
-
} catch {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
async function geocodeAll(locations) {
|
|
75
|
-
const result = [];
|
|
76
|
-
for (const loc of locations) {
|
|
77
|
-
if (loc.lat != null && loc.lng != null) {
|
|
78
|
-
result.push({ ...loc, coords: [loc.lat, loc.lng] });
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
if (loc.address) {
|
|
82
|
-
const coords = await geocodeAddress(loc.address);
|
|
83
|
-
if (coords) result.push({ ...loc, coords });
|
|
84
|
-
await new Promise((r) => setTimeout(r, 1e3));
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return result;
|
|
88
|
-
}
|
|
89
|
-
function buildPopup(loc) {
|
|
90
|
-
const parts = [];
|
|
91
|
-
parts.push(`<strong style="display:block;font-size:13px">${loc.name}</strong>`);
|
|
92
|
-
if (loc.address)
|
|
93
|
-
parts.push(`<span style="display:block;font-size:11px;color:#6b7280;margin-top:2px">${loc.address}</span>`);
|
|
94
|
-
if (loc.phone)
|
|
95
|
-
parts.push(`<span style="display:block;font-size:11px;margin-top:2px">${loc.phone}</span>`);
|
|
96
|
-
if (loc.hours)
|
|
97
|
-
parts.push(`<span style="display:block;font-size:11px;color:#6b7280;margin-top:2px">${loc.hours}</span>`);
|
|
98
|
-
if (loc.address)
|
|
99
|
-
parts.push(
|
|
100
|
-
`<a href="https://maps.google.com/?q=${encodeURIComponent(loc.address)}" target="_blank" rel="noopener noreferrer" style="display:block;font-size:11px;color:#2563eb;margin-top:4px">Ver en Google Maps \u2192</a>`
|
|
101
|
-
);
|
|
102
|
-
return parts.join("");
|
|
103
|
-
}
|
|
104
|
-
function LeafletMapInner({ locations, mapStyle = "standard", className }) {
|
|
105
|
-
const containerRef = useRef(null);
|
|
106
|
-
const mapRef = useRef(null);
|
|
107
|
-
const tileRef = useRef(null);
|
|
108
|
-
const [loading, setLoading] = useState(!!locations?.length);
|
|
109
|
-
useEffect(() => {
|
|
110
|
-
if (!containerRef.current || mapRef.current) return;
|
|
111
|
-
const tile = TILES[mapStyle] ?? TILES.standard;
|
|
112
|
-
const map = L.map(containerRef.current, { scrollWheelZoom: false });
|
|
113
|
-
const tileLayer = L.tileLayer(tile.url, { attribution: tile.attribution, maxZoom: tile.maxZoom ?? 19 }).addTo(map);
|
|
114
|
-
map.setView([20, 0], 2);
|
|
115
|
-
mapRef.current = map;
|
|
116
|
-
tileRef.current = tileLayer;
|
|
117
|
-
return () => {
|
|
118
|
-
map.remove();
|
|
119
|
-
mapRef.current = null;
|
|
120
|
-
tileRef.current = null;
|
|
121
|
-
};
|
|
122
|
-
}, []);
|
|
123
|
-
useEffect(() => {
|
|
124
|
-
if (!mapRef.current) return;
|
|
125
|
-
const tile = TILES[mapStyle] ?? TILES.standard;
|
|
126
|
-
tileRef.current?.remove();
|
|
127
|
-
tileRef.current = L.tileLayer(tile.url, { attribution: tile.attribution, maxZoom: tile.maxZoom ?? 19 }).addTo(mapRef.current);
|
|
128
|
-
}, [mapStyle]);
|
|
129
|
-
useEffect(() => {
|
|
130
|
-
if (!locations?.length) {
|
|
131
|
-
setLoading(false);
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
let cancelled = false;
|
|
135
|
-
setLoading(true);
|
|
136
|
-
geocodeAll(locations).then((geocoded) => {
|
|
137
|
-
if (cancelled || !mapRef.current) return;
|
|
138
|
-
mapRef.current.eachLayer((layer) => {
|
|
139
|
-
if (layer instanceof L.Marker) layer.remove();
|
|
140
|
-
});
|
|
141
|
-
geocoded.forEach((loc) => {
|
|
142
|
-
L.marker(loc.coords, { icon: markerIcon }).addTo(mapRef.current).bindPopup(buildPopup(loc));
|
|
143
|
-
});
|
|
144
|
-
if (geocoded.length === 1) {
|
|
145
|
-
mapRef.current.setView(geocoded[0].coords, 14);
|
|
146
|
-
} else if (geocoded.length > 1) {
|
|
147
|
-
mapRef.current.fitBounds(
|
|
148
|
-
geocoded.map((l) => l.coords),
|
|
149
|
-
{ padding: [48, 48] }
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
setLoading(false);
|
|
153
|
-
});
|
|
154
|
-
return () => {
|
|
155
|
-
cancelled = true;
|
|
156
|
-
};
|
|
157
|
-
}, [locations]);
|
|
158
|
-
return /* @__PURE__ */ jsxs("div", { className: `relative ${className ?? ""}`, children: [
|
|
159
|
-
loading && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-[1000] flex items-center justify-center bg-muted/80 rounded-xl", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 text-muted-foreground text-sm", children: [
|
|
160
|
-
/* @__PURE__ */ jsxs("svg", { className: "animate-spin h-6 w-6", viewBox: "0 0 24 24", fill: "none", children: [
|
|
161
|
-
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
162
|
-
/* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" })
|
|
163
|
-
] }),
|
|
164
|
-
"Geocoding addresses\u2026"
|
|
165
|
-
] }) }),
|
|
166
|
-
/* @__PURE__ */ jsx("div", { ref: containerRef, style: { height: "100%", width: "100%" } })
|
|
167
|
-
] });
|
|
168
|
-
}
|
|
169
|
-
export {
|
|
170
|
-
LeafletMapInner
|
|
171
|
-
};
|