pixelize-design-library 2.2.82 → 2.2.83

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.
@@ -34,7 +34,7 @@ var desktopMenu_1 = __importDefault(require("./components/desktopMenu"));
34
34
  var mobileMenu_1 = __importDefault(require("./components/mobileMenu"));
35
35
  var Header = function (_a) {
36
36
  var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
37
- var logo = _a.logo, menuItems = _a.menuItems, rightSlot = _a.rightSlot, active = _a.active, colors = _a.colors, boxShadow = _a.boxShadow;
37
+ var logo = _a.logo, menuItems = _a.menuItems, rightSlot = _a.rightSlot, active = _a.active, colors = _a.colors, boxShadow = _a.boxShadow, onMobileMenuClose = _a.onMobileMenuClose;
38
38
  var _m = (0, react_1.useDisclosure)(), isOpen = _m.isOpen, onOpen = _m.onOpen, onClose = _m.onClose;
39
39
  var _o = (0, react_2.useState)(null), hoveredMenu = _o[0], setHoveredMenu = _o[1];
40
40
  var themeColor = (0, useCustomTheme_1.useCustomTheme)().colors;
@@ -44,12 +44,20 @@ var Header = function (_a) {
44
44
  var hoverBg = (_h = colors === null || colors === void 0 ? void 0 : colors.hover) !== null && _h !== void 0 ? _h : (_j = themeColor === null || themeColor === void 0 ? void 0 : themeColor.gray) === null || _j === void 0 ? void 0 : _j[500];
45
45
  var hoverText = (_k = colors === null || colors === void 0 ? void 0 : colors.hoverTextColor) !== null && _k !== void 0 ? _k : (_l = themeColor === null || themeColor === void 0 ? void 0 : themeColor.text) === null || _l === void 0 ? void 0 : _l[600];
46
46
  var isActive = function (href) { return href && active === href; };
47
+ var closeMobileMenu = function () {
48
+ onClose();
49
+ onMobileMenuClose === null || onMobileMenuClose === void 0 ? void 0 : onMobileMenuClose();
50
+ };
51
+ var rightSlotWithApi = react_2.default.isValidElement(rightSlot)
52
+ ? react_2.default.cloneElement(rightSlot, { closeMobileMenu: closeMobileMenu })
53
+ : rightSlot;
47
54
  return (react_2.default.createElement(react_1.Box, { bg: bg, color: color, px: 4, shadow: "md", boxShadow: boxShadow, zIndex: 1000, position: "sticky" },
48
55
  react_2.default.createElement(react_1.Flex, { minH: 16, align: "center", mx: "auto", justifyContent: "space-between" },
49
56
  react_2.default.createElement(react_1.Box, { cursor: "pointer" }, logo),
50
- react_2.default.createElement(desktopMenu_1.default, { menuItems: menuItems, rightSlot: rightSlot, setHoveredMenu: setHoveredMenu, isActive: isActive, activeBg: activeBg, hoveredMenu: hoveredMenu, hoverBg: hoverBg, color: color, hoverTextColor: hoverText }),
51
- react_2.default.createElement(react_1.HStack, { spacing: 4, display: { base: "none", md: "flex" } }, rightSlot),
52
- react_2.default.createElement(react_1.IconButton, { variant: "unstyled", icon: react_2.default.createElement(react_1.Box, { display: "flex", alignItems: "center", justifyContent: "center", w: "full", h: "full" }, isOpen ? react_2.default.createElement(lucide_react_1.X, { size: 20 }) : react_2.default.createElement(lucide_react_1.MenuIcon, { size: 20 })), "aria-label": "Toggle Menu", display: { md: "none" }, onClick: isOpen ? onClose : onOpen })),
53
- react_2.default.createElement(mobileMenu_1.default, { menuItems: menuItems, isOpen: isOpen, isActive: isActive, hoverBg: hoverBg, activeBg: activeBg, color: color, rightSlot: rightSlot })));
57
+ react_2.default.createElement(desktopMenu_1.default, { menuItems: menuItems, rightSlot: rightSlotWithApi, setHoveredMenu: setHoveredMenu, isActive: isActive, activeBg: activeBg, hoveredMenu: hoveredMenu, hoverBg: hoverBg, color: color, hoverTextColor: hoverText }),
58
+ react_2.default.createElement(react_1.HStack, { spacing: 4, display: { base: "none", md: "flex" } }, rightSlotWithApi),
59
+ react_2.default.createElement(react_1.HStack, { spacing: 2, display: { base: "flex", md: "none" } }, rightSlotWithApi),
60
+ react_2.default.createElement(react_1.IconButton, { variant: "unstyled", icon: react_2.default.createElement(react_1.Box, { display: "flex", alignItems: "center", justifyContent: "center", w: "full", h: "full" }, isOpen ? react_2.default.createElement(lucide_react_1.X, { size: 20 }) : react_2.default.createElement(lucide_react_1.MenuIcon, { size: 20 })), "aria-label": "Toggle Menu", display: { md: "none" }, onClick: isOpen ? closeMobileMenu : onOpen })),
61
+ react_2.default.createElement(mobileMenu_1.default, { menuItems: menuItems, isOpen: isOpen, isActive: isActive, hoverBg: hoverBg, activeBg: activeBg, color: color, rightSlot: rightSlotWithApi, onClose: closeMobileMenu })));
54
62
  };
55
63
  exports.default = Header;
@@ -31,6 +31,7 @@ export type HeaderProps = {
31
31
  hoverTextColor?: string;
32
32
  };
33
33
  boxShadow?: string;
34
+ onMobileMenuClose?: () => void;
34
35
  };
35
36
  export type DesktopMenuProps = Pick<HeaderProps, "menuItems" | "rightSlot"> & {
36
37
  setHoveredMenu: (menu: string | null) => void;
@@ -43,5 +44,6 @@ export type DesktopMenuProps = Pick<HeaderProps, "menuItems" | "rightSlot"> & {
43
44
  };
44
45
  export type MobileMenuProps = Pick<HeaderProps, 'menuItems' | 'rightSlot'> & Pick<DesktopMenuProps, 'isActive' | 'activeBg' | 'color' | 'hoverBg'> & {
45
46
  isOpen: boolean;
47
+ onClose?: () => void;
46
48
  };
47
49
  export {};
@@ -1,4 +1,4 @@
1
1
  import React from "react";
2
2
  import { MobileMenuProps } from "../HeaderProps";
3
- declare const MobileMenu: ({ menuItems, isOpen, isActive, hoverBg, activeBg, color, rightSlot, }: MobileMenuProps) => React.JSX.Element;
3
+ declare const MobileMenu: ({ menuItems, isOpen, isActive, hoverBg, activeBg, color, rightSlot, onClose, }: MobileMenuProps) => React.JSX.Element;
4
4
  export default MobileMenu;
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  var react_1 = require("@chakra-ui/react");
7
7
  var react_2 = __importDefault(require("react"));
8
8
  var MobileMenu = function (_a) {
9
- var menuItems = _a.menuItems, isOpen = _a.isOpen, isActive = _a.isActive, hoverBg = _a.hoverBg, activeBg = _a.activeBg, color = _a.color, rightSlot = _a.rightSlot;
9
+ var menuItems = _a.menuItems, isOpen = _a.isOpen, isActive = _a.isActive, hoverBg = _a.hoverBg, activeBg = _a.activeBg, color = _a.color, rightSlot = _a.rightSlot, onClose = _a.onClose;
10
10
  return (react_2.default.createElement(react_1.Collapse, { in: isOpen, animateOpacity: true },
11
11
  react_2.default.createElement(react_1.Box, { pb: 4, display: { md: "none" } },
12
12
  react_2.default.createElement(react_1.Stack, { spacing: 4 },
@@ -18,11 +18,11 @@ var MobileMenu = function (_a) {
18
18
  react_2.default.createElement(react_1.Text, { fontWeight: "medium" }, item.label)),
19
19
  react_2.default.createElement(react_1.Stack, { pl: 4, mt: 1 }, item.children.map(function (subItem) {
20
20
  var _a, _b, _c;
21
- return (react_2.default.createElement(react_1.Button, { key: subItem.label, onClick: subItem.onClick, variant: "ghost", w: "full", justifyContent: "flex-start", color: color, bg: isActive(subItem.href) ? activeBg : "transparent", _hover: { bg: hoverBg } },
21
+ return (react_2.default.createElement(react_1.Button, { key: subItem.label, onClick: function () { var _a; (_a = subItem.onClick) === null || _a === void 0 ? void 0 : _a.call(subItem); onClose === null || onClose === void 0 ? void 0 : onClose(); }, variant: "ghost", w: "full", justifyContent: "flex-start", color: color, bg: isActive(subItem.href) ? activeBg : "transparent", _hover: { bg: hoverBg } },
22
22
  react_2.default.createElement(react_1.VStack, { spacing: 0, align: "start" },
23
23
  subItem.badge && (react_2.default.createElement(react_1.Badge, { colorScheme: (_b = (_a = subItem === null || subItem === void 0 ? void 0 : subItem.badge) === null || _a === void 0 ? void 0 : _a.colorScheme) !== null && _b !== void 0 ? _b : "blue", fontSize: "0.6em" }, (_c = subItem.badge) === null || _c === void 0 ? void 0 : _c.label)),
24
24
  react_2.default.createElement(react_1.Text, null, subItem.label))));
25
- })))) : (react_2.default.createElement(react_1.Button, { key: item.label, onClick: item.onClick, variant: "ghost", w: "full", justifyContent: "flex-start", color: color, bg: isActive(item.href) ? activeBg : "transparent", _hover: { bg: hoverBg } },
25
+ })))) : (react_2.default.createElement(react_1.Button, { key: item.label, onClick: function () { var _a; (_a = item.onClick) === null || _a === void 0 ? void 0 : _a.call(item); onClose === null || onClose === void 0 ? void 0 : onClose(); }, variant: "ghost", w: "full", justifyContent: "flex-start", color: color, bg: isActive(item.href) ? activeBg : "transparent", _hover: { bg: hoverBg } },
26
26
  react_2.default.createElement(react_1.VStack, { spacing: 0, align: "start" },
27
27
  item.badge && (react_2.default.createElement(react_1.Badge, { colorScheme: (_d = (_c = item === null || item === void 0 ? void 0 : item.badge) === null || _c === void 0 ? void 0 : _c.colorScheme) !== null && _d !== void 0 ? _d : "blue", fontSize: "0.6em" }, (_e = item.badge) === null || _e === void 0 ? void 0 : _e.label)),
28
28
  react_2.default.createElement(react_1.Text, null, item.label))));
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ import "leaflet/dist/leaflet.css";
3
+ import "leaflet-routing-machine";
4
+ import "leaflet-routing-machine/dist/leaflet-routing-machine.css";
5
+ export type ShopLocation = {
6
+ id: string | number;
7
+ name: string;
8
+ lat: number;
9
+ lng: number;
10
+ address?: string;
11
+ };
12
+ export type ShopMapProps = {
13
+ shops: ShopLocation[];
14
+ selectedShopId?: string | number;
15
+ userLocation?: {
16
+ lat: number;
17
+ lng: number;
18
+ };
19
+ height?: string | number;
20
+ onSelectShop?: (shop: ShopLocation) => void;
21
+ navigateToShopId?: string | number;
22
+ };
23
+ declare const ShopMap: React.FC<ShopMapProps>;
24
+ export default ShopMap;
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ var react_1 = __importStar(require("react"));
30
+ var react_2 = require("@chakra-ui/react");
31
+ var leaflet_1 = __importDefault(require("leaflet"));
32
+ require("leaflet/dist/leaflet.css");
33
+ require("leaflet-routing-machine");
34
+ require("leaflet-routing-machine/dist/leaflet-routing-machine.css");
35
+ var tileUrl = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
36
+ function directionsUrl(dest, origin) {
37
+ var base = "https://www.google.com/maps/dir/?api=1";
38
+ var destination = "destination=".concat(dest.lat, ",").concat(dest.lng);
39
+ var o = origin ? "&origin=".concat(origin.lat, ",").concat(origin.lng) : "";
40
+ return "".concat(base, "&").concat(destination).concat(o);
41
+ }
42
+ var ShopMap = function (_a) {
43
+ var shops = _a.shops, selectedShopId = _a.selectedShopId, userLocation = _a.userLocation, _b = _a.height, height = _b === void 0 ? 360 : _b, onSelectShop = _a.onSelectShop, navigateToShopId = _a.navigateToShopId;
44
+ var mapElRef = (0, react_1.useRef)(null);
45
+ var mapRef = (0, react_1.useRef)(null);
46
+ var markersRef = (0, react_1.useRef)(new Map());
47
+ var routeLayerRef = (0, react_1.useRef)(null);
48
+ var routingControlRef = (0, react_1.useRef)(null);
49
+ var internalOriginRef = (0, react_1.useRef)(null);
50
+ var bounds = (0, react_1.useMemo)(function () {
51
+ var b = leaflet_1.default.latLngBounds([]);
52
+ shops.forEach(function (s) { return b.extend([s.lat, s.lng]); });
53
+ return b;
54
+ }, [shops]);
55
+ (0, react_1.useEffect)(function () {
56
+ if (!mapElRef.current)
57
+ return;
58
+ if (!mapRef.current) {
59
+ mapRef.current = leaflet_1.default.map(mapElRef.current);
60
+ leaflet_1.default.tileLayer(tileUrl, {
61
+ attribution: "&copy; OpenStreetMap contributors",
62
+ }).addTo(mapRef.current);
63
+ }
64
+ markersRef.current.forEach(function (layer) {
65
+ if (mapRef.current && mapRef.current.hasLayer(layer))
66
+ mapRef.current.removeLayer(layer);
67
+ });
68
+ markersRef.current.clear();
69
+ shops.forEach(function (shop) {
70
+ var marker = leaflet_1.default.circleMarker([shop.lat, shop.lng], {
71
+ radius: 7,
72
+ color: "#2563eb",
73
+ weight: 2,
74
+ fillColor: "#60a5fa",
75
+ fillOpacity: 0.8,
76
+ });
77
+ var html = "<div style=\"min-width:220px;line-height:1.4\">".concat(shop.name).concat(shop.address ? "<br/><small>".concat(shop.address, "</small>") : "", "<br/><div style=\"display:flex;gap:8px;margin-top:6px\"><button data-id=\"").concat(shop.id, "\" data-action=\"navigate\" style=\"padding:6px 10px;border-radius:6px;background:#7c3aed;color:#fff;border:none;cursor:pointer\">Navigate</button><button data-id=\"").concat(shop.id, "\" data-action=\"gmaps\" style=\"padding:6px 10px;border-radius:6px;background:#9333ea;color:#fff;border:none;cursor:pointer\">Google Maps</button></div></div>");
78
+ marker.bindPopup(html, { autoPan: false });
79
+ marker.on("click", function () { return onSelectShop && onSelectShop(shop); });
80
+ marker.on("popupopen", function () {
81
+ var _a;
82
+ var el = (_a = marker.getPopup()) === null || _a === void 0 ? void 0 : _a.getElement();
83
+ if (!el)
84
+ return;
85
+ var navBtn = el.querySelector("button[data-id='".concat(shop.id, "'][data-action='navigate']"));
86
+ var gmapsBtn = el.querySelector("button[data-id='".concat(shop.id, "'][data-action='gmaps']"));
87
+ if (navBtn) {
88
+ navBtn.addEventListener("click", function () {
89
+ if (!mapRef.current)
90
+ return;
91
+ var proceed = function (origin) {
92
+ if (routingControlRef.current) {
93
+ mapRef.current.removeControl(routingControlRef.current);
94
+ routingControlRef.current = null;
95
+ }
96
+ var dest = leaflet_1.default.latLng(shop.lat, shop.lng);
97
+ var plan = leaflet_1.default.Routing.plan([origin, dest], {
98
+ draggableWaypoints: false,
99
+ addWaypoints: false,
100
+ createMarker: function (_i, wp) { return leaflet_1.default.marker(wp.latLng, { opacity: 0, interactive: false }); },
101
+ });
102
+ routingControlRef.current = leaflet_1.default.Routing.control({
103
+ plan: plan,
104
+ router: leaflet_1.default.Routing.osrmv1({ serviceUrl: "https://router.project-osrm.org/route/v1" }),
105
+ fitSelectedRoutes: true,
106
+ routeWhileDragging: false,
107
+ showAlternatives: false,
108
+ });
109
+ routingControlRef.current.addTo(mapRef.current);
110
+ };
111
+ var originSource = userLocation || internalOriginRef.current;
112
+ if (originSource) {
113
+ proceed(leaflet_1.default.latLng(originSource.lat, originSource.lng));
114
+ }
115
+ else if (navigator.geolocation) {
116
+ navigator.geolocation.getCurrentPosition(function (pos) {
117
+ internalOriginRef.current = { lat: pos.coords.latitude, lng: pos.coords.longitude };
118
+ proceed(leaflet_1.default.latLng(pos.coords.latitude, pos.coords.longitude));
119
+ });
120
+ }
121
+ });
122
+ }
123
+ if (gmapsBtn) {
124
+ gmapsBtn.addEventListener("click", function () {
125
+ var originSource = userLocation || internalOriginRef.current || undefined;
126
+ var link = directionsUrl({ lat: shop.lat, lng: shop.lng }, originSource ? { lat: originSource.lat, lng: originSource.lng } : undefined);
127
+ window.open(link, "_blank", "noopener");
128
+ });
129
+ }
130
+ });
131
+ marker.addTo(mapRef.current);
132
+ markersRef.current.set(shop.id, marker);
133
+ });
134
+ if (shops.length) {
135
+ mapRef.current.fitBounds(bounds.pad(0.2));
136
+ }
137
+ return function () {
138
+ if (routingControlRef.current && mapRef.current) {
139
+ mapRef.current.removeControl(routingControlRef.current);
140
+ }
141
+ routingControlRef.current = null;
142
+ if (routeLayerRef.current && mapRef.current && mapRef.current.hasLayer(routeLayerRef.current)) {
143
+ mapRef.current.removeLayer(routeLayerRef.current);
144
+ }
145
+ routeLayerRef.current = null;
146
+ markersRef.current.clear();
147
+ if (mapRef.current) {
148
+ mapRef.current.off();
149
+ mapRef.current.remove();
150
+ mapRef.current = null;
151
+ }
152
+ };
153
+ }, [shops, bounds, userLocation]);
154
+ (0, react_1.useEffect)(function () {
155
+ var _a, _b;
156
+ if (!selectedShopId || !mapRef.current)
157
+ return;
158
+ var layer = markersRef.current.get(selectedShopId);
159
+ if (!layer)
160
+ return;
161
+ (_b = (_a = layer).openPopup) === null || _b === void 0 ? void 0 : _b.call(_a);
162
+ }, [selectedShopId]);
163
+ (0, react_1.useEffect)(function () {
164
+ var _a, _b, _c, _d;
165
+ if (!navigateToShopId || !mapRef.current)
166
+ return;
167
+ var layer = markersRef.current.get(navigateToShopId);
168
+ if (!layer)
169
+ return;
170
+ var center = (_b = (_a = layer).getLatLng) === null || _b === void 0 ? void 0 : _b.call(_a);
171
+ if (!center)
172
+ return;
173
+ var build = function (origin) {
174
+ if (routingControlRef.current) {
175
+ mapRef.current.removeControl(routingControlRef.current);
176
+ routingControlRef.current = null;
177
+ }
178
+ var plan = leaflet_1.default.Routing.plan([origin, center], {
179
+ draggableWaypoints: false,
180
+ addWaypoints: false,
181
+ createMarker: function (_i, wp) { return leaflet_1.default.marker(wp.latLng, { opacity: 0, interactive: false }); },
182
+ });
183
+ routingControlRef.current = leaflet_1.default.Routing.control({
184
+ plan: plan,
185
+ router: leaflet_1.default.Routing.osrmv1({ serviceUrl: "https://router.project-osrm.org/route/v1" }),
186
+ fitSelectedRoutes: true,
187
+ routeWhileDragging: false,
188
+ showAlternatives: false,
189
+ });
190
+ routingControlRef.current.addTo(mapRef.current);
191
+ };
192
+ var originSrc = userLocation || internalOriginRef.current;
193
+ if (originSrc) {
194
+ build(leaflet_1.default.latLng(originSrc.lat, originSrc.lng));
195
+ }
196
+ else if (navigator.geolocation) {
197
+ navigator.geolocation.getCurrentPosition(function (pos) {
198
+ internalOriginRef.current = { lat: pos.coords.latitude, lng: pos.coords.longitude };
199
+ build(leaflet_1.default.latLng(pos.coords.latitude, pos.coords.longitude));
200
+ });
201
+ }
202
+ (_d = (_c = layer).openPopup) === null || _d === void 0 ? void 0 : _d.call(_c);
203
+ }, [navigateToShopId, userLocation]);
204
+ return react_1.default.createElement(react_2.Box, { w: "100%", h: height },
205
+ react_1.default.createElement("div", { ref: mapElRef, style: { width: "100%", height: "100%" } }));
206
+ };
207
+ exports.default = ShopMap;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelize-design-library",
3
- "version": "2.2.82",
3
+ "version": "2.2.83",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -10,6 +10,8 @@
10
10
  "@hello-pangea/dnd": "^18.0.1",
11
11
  "framer-motion": "^11.2.2",
12
12
  "jodit-react": "^5.2.38",
13
+ "leaflet": "^1.9.4",
14
+ "leaflet-routing-machine": "^3.2.12",
13
15
  "lucide-react": "^0.487.0",
14
16
  "react": "^18.3.1",
15
17
  "react-apexcharts": "^1.4.1",
@@ -54,6 +56,8 @@
54
56
  "@testing-library/react": "^13.4.0",
55
57
  "@testing-library/user-event": "^13.5.0",
56
58
  "@types/jest": "^27.5.2",
59
+ "@types/leaflet": "^1.9.21",
60
+ "@types/leaflet-routing-machine": "^3.2.9",
57
61
  "@types/node": "^16.18.97",
58
62
  "@types/react": "^18.3.2",
59
63
  "@types/react-dom": "^18.3.0",