xertica-ui 1.3.7 → 1.3.8

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.
@@ -74,6 +74,8 @@ interface SidebarProps {
74
74
  location: { pathname: string };
75
75
  navigate: (path: string) => void;
76
76
  routes: RouteConfig[];
77
+ logo?: React.ReactNode;
78
+ logoCollapsed?: React.ReactNode;
77
79
  }
78
80
 
79
81
  export function Sidebar({
@@ -84,6 +86,8 @@ export function Sidebar({
84
86
  location,
85
87
  navigate,
86
88
  routes,
89
+ logo,
90
+ logoCollapsed,
87
91
  }: SidebarProps) {
88
92
  const navRef = useRef<HTMLDivElement>(null);
89
93
  const [hasOverflow, setHasOverflow] = useState(false);
@@ -318,15 +322,19 @@ export function Sidebar({
318
322
  >
319
323
  <div className="flex items-center justify-center flex-shrink-0">
320
324
  {expanded ? (
321
- <XerticaLogo
322
- className="h-5 w-auto"
323
- variant="white"
324
- />
325
+ logo || (
326
+ <XerticaLogo
327
+ className="h-5 w-auto"
328
+ variant="white"
329
+ />
330
+ )
325
331
  ) : (
326
- <XerticaXLogo
327
- className="h-5 w-auto"
328
- variant="white"
329
- />
332
+ logoCollapsed || (
333
+ <XerticaXLogo
334
+ className="h-5 w-auto"
335
+ variant="white"
336
+ />
337
+ )
330
338
  )}
331
339
  </div>
332
340
  </div>
@@ -0,0 +1,71 @@
1
+ import React from 'react';
2
+ import { Map } from '../ui/map';
3
+ import { RouteMap } from '../ui/route-map';
4
+
5
+ export function ApiKeyMapExample() {
6
+ const [key, setKey] = React.useState('');
7
+ const [appliedKey, setAppliedKey] = React.useState('');
8
+
9
+ const handleApply = () => {
10
+ if (key) setAppliedKey(key);
11
+ };
12
+
13
+ return (
14
+ <div className="space-y-8 p-6">
15
+ <div className="space-y-4">
16
+ <h2 className="text-2xl font-bold">Map with Explicit API Key</h2>
17
+ <p className="text-muted-foreground">
18
+ Enter a Google Maps API Key to load the maps below. This simulates a scenario where the key is provided dynamically or via props, overriding/fallback for the global context.
19
+ </p>
20
+
21
+ <div className="flex gap-4 max-w-xl">
22
+ <input
23
+ type="text"
24
+ value={key}
25
+ onChange={(e) => setKey(e.target.value)}
26
+ placeholder="Enter Google Maps API Key"
27
+ className="flex-1 px-4 py-2 border rounded-md bg-background"
28
+ />
29
+ <button
30
+ onClick={handleApply}
31
+ className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90"
32
+ >
33
+ Load Maps
34
+ </button>
35
+ </div>
36
+ </div>
37
+
38
+ {appliedKey ? (
39
+ <div className="grid md:grid-cols-2 gap-8">
40
+ <div className="space-y-4">
41
+ <h3 className="font-semibold">Standard Map</h3>
42
+ <Map
43
+ apiKey={appliedKey}
44
+ height="400px"
45
+ center={{ lat: -23.5505, lng: -46.6333 }}
46
+ zoom={12}
47
+ markers={[
48
+ { position: { lat: -23.5505, lng: -46.6333 }, title: 'São Paulo' }
49
+ ]}
50
+ />
51
+ </div>
52
+
53
+ <div className="space-y-4">
54
+ <h3 className="font-semibold">Route Map</h3>
55
+ <RouteMap
56
+ apiKey={appliedKey}
57
+ height="400px"
58
+ origin={{ lat: -23.5505, lng: -46.6333 }}
59
+ destination={{ lat: -23.6005, lng: -46.6833 }}
60
+ travelMode="DRIVING"
61
+ />
62
+ </div>
63
+ </div>
64
+ ) : (
65
+ <div className="p-12 border-2 border-dashed rounded-lg text-center text-muted-foreground">
66
+ Enter an API Key above to render the maps.
67
+ </div>
68
+ )}
69
+ </div>
70
+ );
71
+ }
@@ -0,0 +1,65 @@
1
+ import React, { useState } from 'react';
2
+ import { Sidebar, RouteConfig } from '../Sidebar';
3
+ import { Home, Settings, User } from 'lucide-react';
4
+ import { BrowserRouter, useNavigate, useLocation } from 'react-router';
5
+
6
+ // Wrapper wrapper to provide router context
7
+ export function SidebarLogoExample() {
8
+ return (
9
+ <BrowserRouter>
10
+ <SidebarLogoContent />
11
+ </BrowserRouter>
12
+ );
13
+ }
14
+
15
+ function SidebarLogoContent() {
16
+ const [expanded, setExpanded] = useState(true);
17
+ const navigate = useNavigate();
18
+ const location = useLocation();
19
+
20
+ const routes: RouteConfig[] = [
21
+ { path: '/home', label: 'Home', icon: Home },
22
+ { path: '/profile', label: 'Profile', icon: User },
23
+ { path: '/settings', label: 'Settings', icon: Settings },
24
+ ];
25
+
26
+ const CustomLogo = (
27
+ <div className="flex items-center gap-2 font-bold text-xl text-primary">
28
+ <div className="w-8 h-8 bg-primary rounded-full flex items-center justify-center text-primary-foreground">
29
+ C
30
+ </div>
31
+ <span>CustomBrand</span>
32
+ </div>
33
+ );
34
+
35
+ const CustomLogoCollapsed = (
36
+ <div className="w-8 h-8 bg-primary rounded-full flex items-center justify-center text-primary-foreground font-bold">
37
+ C
38
+ </div>
39
+ );
40
+
41
+ return (
42
+ <div className="flex h-[500px] border rounded-lg overflow-hidden bg-background">
43
+ <Sidebar
44
+ expanded={expanded}
45
+ onToggle={() => setExpanded(!expanded)}
46
+ user={{ email: 'test@example.com' }}
47
+ onLogout={() => console.log('Logout')}
48
+ location={location}
49
+ navigate={navigate}
50
+ routes={routes}
51
+ logo={CustomLogo}
52
+ logoCollapsed={CustomLogoCollapsed}
53
+ />
54
+ <div className={`flex-1 p-8 transition-all duration-300 ${expanded ? 'ml-64' : 'ml-20'}`}>
55
+ <h1 className="text-2xl font-bold mb-4">Sidebar with Custom Logo</h1>
56
+ <p>This example demonstrates passing a custom logo component to the Sidebar.</p>
57
+ <div className="mt-8 p-4 border rounded bg-muted/20">
58
+ <p className="text-sm text-muted-foreground">
59
+ Try toggling the sidebar to see the collapsed logo version.
60
+ </p>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ );
65
+ }
@@ -6,11 +6,13 @@ import { GOOGLE_MAPS_LIBRARIES, GOOGLE_MAPS_ID } from './map-config';
6
6
  interface GoogleMapsContextType {
7
7
  isLoaded: boolean;
8
8
  loadError: Error | undefined;
9
+ load: (apiKey: string) => Promise<void>;
9
10
  }
10
11
 
11
12
  const GoogleMapsContext = createContext<GoogleMapsContextType>({
12
13
  isLoaded: false,
13
14
  loadError: undefined,
15
+ load: () => Promise.resolve(),
14
16
  });
15
17
 
16
18
  // Singleton global para prevenir múltiplos carregamentos
@@ -57,7 +59,7 @@ function removeExistingScript(): void {
57
59
  }
58
60
 
59
61
  // Remover script existente
60
- const existingScript = document.querySelector(`script[src*=\"maps.googleapis.com/maps/api/js\"]`);
62
+ const existingScript = document.querySelector(`script[src*="maps.googleapis.com/maps/api/js"]`);
61
63
  if (existingScript) {
62
64
  existingScript.remove();
63
65
  }
@@ -202,6 +204,7 @@ function getOrCreateSingleton() {
202
204
  isLoaded: isPreloaded,
203
205
  loadError: undefined,
204
206
  listeners: new Set(),
207
+ scriptElement: undefined
205
208
  };
206
209
  }
207
210
 
@@ -218,7 +221,24 @@ function updateSingleton(state: Partial<GoogleMapsContextType>) {
218
221
  if (state.isLoaded !== undefined) singleton.isLoaded = state.isLoaded;
219
222
  if (state.loadError !== undefined) singleton.loadError = state.loadError;
220
223
 
221
- const newState = { isLoaded: singleton.isLoaded, loadError: singleton.loadError };
224
+ // Prepare safe state to notify
225
+ const newState: GoogleMapsContextType = {
226
+ isLoaded: singleton.isLoaded,
227
+ loadError: singleton.loadError,
228
+ load: async (apiKey: string) => {
229
+ // Allow manual loading call via stored function in context if needed,
230
+ // though typically we use the direct export or loadGoogleMapsScript
231
+ if (singleton.isLoaded) return;
232
+ try {
233
+ await loadGoogleMapsScript(apiKey);
234
+ updateSingleton({ isLoaded: true, loadError: undefined });
235
+ } catch (error: any) {
236
+ updateSingleton({ isLoaded: false, loadError: error });
237
+ throw error;
238
+ }
239
+ }
240
+ };
241
+
222
242
  singleton.listeners.forEach(listener => listener(newState));
223
243
  }
224
244
 
@@ -228,11 +248,25 @@ function updateSingleton(state: Partial<GoogleMapsContextType>) {
228
248
  const SingletonLoaderWrapper = ({ children }: { children: ReactNode }) => {
229
249
  const [state, setState] = useState<GoogleMapsContextType>(() => {
230
250
  const singleton = getOrCreateSingleton();
231
- if (!singleton) return { isLoaded: false, loadError: undefined };
251
+
252
+ // Default load function that triggers the script load
253
+ const loadFn = async (apiKey: string) => {
254
+ if (singleton?.isLoaded) return;
255
+ try {
256
+ await loadGoogleMapsScript(apiKey);
257
+ updateSingleton({ isLoaded: true, loadError: undefined });
258
+ } catch (error: any) {
259
+ updateSingleton({ isLoaded: false, loadError: error });
260
+ throw error;
261
+ }
262
+ };
263
+
264
+ if (!singleton) return { isLoaded: false, loadError: undefined, load: loadFn };
232
265
 
233
266
  return {
234
267
  isLoaded: singleton.isLoaded,
235
268
  loadError: singleton.loadError,
269
+ load: loadFn
236
270
  };
237
271
  });
238
272
 
@@ -246,8 +280,12 @@ const SingletonLoaderWrapper = ({ children }: { children: ReactNode }) => {
246
280
 
247
281
  singleton.listeners.add(listener);
248
282
 
249
- // Sincronizar estado inicial
250
- listener({ isLoaded: singleton.isLoaded, loadError: singleton.loadError });
283
+ // Sincronizar estado inicial e função de load
284
+ listener({
285
+ isLoaded: singleton.isLoaded,
286
+ loadError: singleton.loadError,
287
+ load: state.load
288
+ });
251
289
 
252
290
  return () => {
253
291
  singleton.listeners.delete(listener);
@@ -264,7 +302,7 @@ const SingletonLoaderWrapper = ({ children }: { children: ReactNode }) => {
264
302
  /**
265
303
  * Componente que carrega o Google Maps manualmente
266
304
  */
267
- const LoaderInitializer = () => {
305
+ const LoaderInitializer = ({ apiKey }: { apiKey?: string }) => {
268
306
  const hasInitializedRef = useRef(false);
269
307
 
270
308
  useEffect(() => {
@@ -285,10 +323,11 @@ const LoaderInitializer = () => {
285
323
 
286
324
  hasInitializedRef.current = true;
287
325
 
288
- const apiKey = getInitialApiKey();
326
+ // Use prop key OR get from storage
327
+ const keyToUse = apiKey || getInitialApiKey();
289
328
 
290
329
  // Se não houver API key, apenas marcar como não carregado (sem erro)
291
- if (!apiKey) {
330
+ if (!keyToUse) {
292
331
  updateSingleton({
293
332
  isLoaded: false,
294
333
  loadError: undefined // Não definir erro quando não há API key
@@ -296,25 +335,30 @@ const LoaderInitializer = () => {
296
335
  return;
297
336
  }
298
337
 
299
- loadGoogleMapsScript(apiKey)
338
+ loadGoogleMapsScript(keyToUse)
300
339
  .then(() => {
301
340
  updateSingleton({ isLoaded: true, loadError: undefined });
302
341
  })
303
342
  .catch((error) => {
304
343
  updateSingleton({ isLoaded: false, loadError: error });
305
344
  });
306
- }, []);
345
+ }, [apiKey]);
307
346
 
308
347
  return null;
309
348
  };
310
349
 
350
+ interface GoogleMapsLoaderProviderProps {
351
+ children: ReactNode;
352
+ apiKey?: string;
353
+ }
354
+
311
355
  /**
312
356
  * GoogleMapsLoaderProvider
313
357
  *
314
358
  * Provider global que gerencia o carregamento da API do Google Maps.
315
359
  * Usa carregamento manual do script para evitar conflitos com custom elements.
316
360
  */
317
- export const GoogleMapsLoaderProvider = ({ children }: { children: ReactNode }) => {
361
+ export const GoogleMapsLoaderProvider = ({ children, apiKey }: GoogleMapsLoaderProviderProps) => {
318
362
  const [shouldInitialize] = useState(() => {
319
363
  const singleton = getOrCreateSingleton();
320
364
  if (!singleton) return false;
@@ -330,7 +374,7 @@ export const GoogleMapsLoaderProvider = ({ children }: { children: ReactNode })
330
374
 
331
375
  return (
332
376
  <>
333
- {shouldInitialize && <LoaderInitializer />}
377
+ {shouldInitialize && <LoaderInitializer apiKey={apiKey} />}
334
378
  <SingletonLoaderWrapper>{children}</SingletonLoaderWrapper>
335
379
  </>
336
380
  );
@@ -96,6 +96,14 @@ const MapContent = React.forwardRef<HTMLDivElement, MapProps & { apiKey: string
96
96
 
97
97
  // Initialize map once
98
98
  useEffect(() => {
99
+ // If we have an apiKey and not loaded, try to load it
100
+ if (!isLoaded && apiKey && !loadError) {
101
+ const { load } = useGoogleMapsLoader();
102
+ if (load) {
103
+ load(apiKey).catch((console.error));
104
+ }
105
+ }
106
+
99
107
  if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
100
108
 
101
109
  isInitializedRef.current = true;
@@ -121,7 +129,7 @@ const MapContent = React.forwardRef<HTMLDivElement, MapProps & { apiKey: string
121
129
  isInitializedRef.current = false;
122
130
  mapRef.current = null;
123
131
  };
124
- }, [isLoaded]);
132
+ }, [isLoaded, apiKey]);
125
133
 
126
134
  // Update markers
127
135
  useEffect(() => {
@@ -47,6 +47,14 @@ const RouteMapContent = React.forwardRef<HTMLDivElement, RouteMapProps & { apiKe
47
47
 
48
48
  // Initialize map once
49
49
  useEffect(() => {
50
+ // If we have an apiKey and not loaded, try to load it
51
+ if (!isLoaded && apiKey && !loadError) {
52
+ const { load } = useGoogleMapsLoader();
53
+ if (load) {
54
+ load(apiKey).catch((console.error));
55
+ }
56
+ }
57
+
50
58
  if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
51
59
 
52
60
  isInitializedRef.current = true;
@@ -85,7 +93,7 @@ const RouteMapContent = React.forwardRef<HTMLDivElement, RouteMapProps & { apiKe
85
93
  isInitializedRef.current = false;
86
94
  mapRef.current = null;
87
95
  };
88
- }, [isLoaded]);
96
+ }, [isLoaded, apiKey]);
89
97
 
90
98
  // Calculate route
91
99
  useEffect(() => {
@@ -17,6 +17,8 @@ interface SidebarProps {
17
17
  };
18
18
  navigate: (path: string) => void;
19
19
  routes: RouteConfig[];
20
+ logo?: React.ReactNode;
21
+ logoCollapsed?: React.ReactNode;
20
22
  }
21
- export declare function Sidebar({ expanded, onToggle, user, onLogout, location, navigate, routes, }: SidebarProps): import("react/jsx-runtime").JSX.Element;
23
+ export declare function Sidebar({ expanded, onToggle, user, onLogout, location, navigate, routes, logo, logoCollapsed, }: SidebarProps): import("react/jsx-runtime").JSX.Element;
22
24
  export {};
@@ -2,6 +2,7 @@ import { ReactNode } from 'react';
2
2
  interface GoogleMapsContextType {
3
3
  isLoaded: boolean;
4
4
  loadError: Error | undefined;
5
+ load: (apiKey: string) => Promise<void>;
5
6
  }
6
7
  declare global {
7
8
  interface Window {
@@ -13,15 +14,17 @@ declare global {
13
14
  };
14
15
  }
15
16
  }
17
+ interface GoogleMapsLoaderProviderProps {
18
+ children: ReactNode;
19
+ apiKey?: string;
20
+ }
16
21
  /**
17
22
  * GoogleMapsLoaderProvider
18
23
  *
19
24
  * Provider global que gerencia o carregamento da API do Google Maps.
20
25
  * Usa carregamento manual do script para evitar conflitos com custom elements.
21
26
  */
22
- export declare const GoogleMapsLoaderProvider: ({ children }: {
23
- children: ReactNode;
24
- }) => import("react/jsx-runtime").JSX.Element;
27
+ export declare const GoogleMapsLoaderProvider: ({ children, apiKey }: GoogleMapsLoaderProviderProps) => import("react/jsx-runtime").JSX.Element;
25
28
  export declare const useGoogleMapsLoader: () => GoogleMapsContextType;
26
29
  /**
27
30
  * Recarrega o Google Maps com uma nova API key
package/dist/index.es.js CHANGED
@@ -47735,7 +47735,8 @@ const GOOGLE_MAPS_LIBRARIES = ["marker", "places", "geometry", "drawing"];
47735
47735
  const GOOGLE_MAPS_ID = "xertica-google-map-script";
47736
47736
  const GoogleMapsContext = createContext({
47737
47737
  isLoaded: false,
47738
- loadError: void 0
47738
+ loadError: void 0,
47739
+ load: () => Promise.resolve()
47739
47740
  });
47740
47741
  function getInitialApiKey() {
47741
47742
  if (typeof window === "undefined") return void 0;
@@ -47856,7 +47857,8 @@ function getOrCreateSingleton() {
47856
47857
  window.__XERTICA_GOOGLE_MAPS_LOADER__ = {
47857
47858
  isLoaded: isPreloaded,
47858
47859
  loadError: void 0,
47859
- listeners: /* @__PURE__ */ new Set()
47860
+ listeners: /* @__PURE__ */ new Set(),
47861
+ scriptElement: void 0
47860
47862
  };
47861
47863
  }
47862
47864
  return window.__XERTICA_GOOGLE_MAPS_LOADER__;
@@ -47866,16 +47868,40 @@ function updateSingleton(state) {
47866
47868
  if (!singleton) return;
47867
47869
  if (state.isLoaded !== void 0) singleton.isLoaded = state.isLoaded;
47868
47870
  if (state.loadError !== void 0) singleton.loadError = state.loadError;
47869
- const newState = { isLoaded: singleton.isLoaded, loadError: singleton.loadError };
47871
+ const newState = {
47872
+ isLoaded: singleton.isLoaded,
47873
+ loadError: singleton.loadError,
47874
+ load: async (apiKey) => {
47875
+ if (singleton.isLoaded) return;
47876
+ try {
47877
+ await loadGoogleMapsScript(apiKey);
47878
+ updateSingleton({ isLoaded: true, loadError: void 0 });
47879
+ } catch (error) {
47880
+ updateSingleton({ isLoaded: false, loadError: error });
47881
+ throw error;
47882
+ }
47883
+ }
47884
+ };
47870
47885
  singleton.listeners.forEach((listener) => listener(newState));
47871
47886
  }
47872
47887
  const SingletonLoaderWrapper = ({ children }) => {
47873
47888
  const [state, setState] = useState(() => {
47874
47889
  const singleton = getOrCreateSingleton();
47875
- if (!singleton) return { isLoaded: false, loadError: void 0 };
47890
+ const loadFn = async (apiKey) => {
47891
+ if (singleton == null ? void 0 : singleton.isLoaded) return;
47892
+ try {
47893
+ await loadGoogleMapsScript(apiKey);
47894
+ updateSingleton({ isLoaded: true, loadError: void 0 });
47895
+ } catch (error) {
47896
+ updateSingleton({ isLoaded: false, loadError: error });
47897
+ throw error;
47898
+ }
47899
+ };
47900
+ if (!singleton) return { isLoaded: false, loadError: void 0, load: loadFn };
47876
47901
  return {
47877
47902
  isLoaded: singleton.isLoaded,
47878
- loadError: singleton.loadError
47903
+ loadError: singleton.loadError,
47904
+ load: loadFn
47879
47905
  };
47880
47906
  });
47881
47907
  useEffect(() => {
@@ -47885,14 +47911,18 @@ const SingletonLoaderWrapper = ({ children }) => {
47885
47911
  setState(newState);
47886
47912
  };
47887
47913
  singleton.listeners.add(listener);
47888
- listener({ isLoaded: singleton.isLoaded, loadError: singleton.loadError });
47914
+ listener({
47915
+ isLoaded: singleton.isLoaded,
47916
+ loadError: singleton.loadError,
47917
+ load: state.load
47918
+ });
47889
47919
  return () => {
47890
47920
  singleton.listeners.delete(listener);
47891
47921
  };
47892
47922
  }, []);
47893
47923
  return /* @__PURE__ */ jsxRuntimeExports.jsx(GoogleMapsContext.Provider, { value: state, children });
47894
47924
  };
47895
- const LoaderInitializer = () => {
47925
+ const LoaderInitializer = ({ apiKey }) => {
47896
47926
  const hasInitializedRef = useRef(false);
47897
47927
  useEffect(() => {
47898
47928
  if (hasInitializedRef.current) {
@@ -47906,8 +47936,8 @@ const LoaderInitializer = () => {
47906
47936
  return;
47907
47937
  }
47908
47938
  hasInitializedRef.current = true;
47909
- const apiKey = getInitialApiKey();
47910
- if (!apiKey) {
47939
+ const keyToUse = apiKey || getInitialApiKey();
47940
+ if (!keyToUse) {
47911
47941
  updateSingleton({
47912
47942
  isLoaded: false,
47913
47943
  loadError: void 0
@@ -47915,15 +47945,15 @@ const LoaderInitializer = () => {
47915
47945
  });
47916
47946
  return;
47917
47947
  }
47918
- loadGoogleMapsScript(apiKey).then(() => {
47948
+ loadGoogleMapsScript(keyToUse).then(() => {
47919
47949
  updateSingleton({ isLoaded: true, loadError: void 0 });
47920
47950
  }).catch((error) => {
47921
47951
  updateSingleton({ isLoaded: false, loadError: error });
47922
47952
  });
47923
- }, []);
47953
+ }, [apiKey]);
47924
47954
  return null;
47925
47955
  };
47926
- const GoogleMapsLoaderProvider = ({ children }) => {
47956
+ const GoogleMapsLoaderProvider = ({ children, apiKey }) => {
47927
47957
  const [shouldInitialize] = useState(() => {
47928
47958
  const singleton = getOrCreateSingleton();
47929
47959
  if (!singleton) return false;
@@ -47934,7 +47964,7 @@ const GoogleMapsLoaderProvider = ({ children }) => {
47934
47964
  return true;
47935
47965
  });
47936
47966
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
47937
- shouldInitialize && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderInitializer, {}),
47967
+ shouldInitialize && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderInitializer, { apiKey }),
47938
47968
  /* @__PURE__ */ jsxRuntimeExports.jsx(SingletonLoaderWrapper, { children })
47939
47969
  ] });
47940
47970
  };
@@ -50509,7 +50539,9 @@ function Sidebar({
50509
50539
  onLogout,
50510
50540
  location,
50511
50541
  navigate,
50512
- routes: routes2
50542
+ routes: routes2,
50543
+ logo,
50544
+ logoCollapsed
50513
50545
  }) {
50514
50546
  const navRef = useRef(null);
50515
50547
  const [hasOverflow, setHasOverflow] = useState(false);
@@ -50666,13 +50698,13 @@ function Sidebar({
50666
50698
  "div",
50667
50699
  {
50668
50700
  className: `flex items-center h-10 ${expanded ? "justify-center" : "justify-center"}`,
50669
- children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(
50701
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: expanded ? logo || /* @__PURE__ */ jsxRuntimeExports.jsx(
50670
50702
  XerticaLogo,
50671
50703
  {
50672
50704
  className: "h-5 w-auto",
50673
50705
  variant: "white"
50674
50706
  }
50675
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
50707
+ ) : logoCollapsed || /* @__PURE__ */ jsxRuntimeExports.jsx(
50676
50708
  XerticaXLogo,
50677
50709
  {
50678
50710
  className: "h-5 w-auto",
@@ -69229,6 +69261,12 @@ const MapContent = React__default.forwardRef(
69229
69261
  }
69230
69262
  }, []);
69231
69263
  useEffect(() => {
69264
+ if (!isLoaded && apiKey && !loadError) {
69265
+ const { load } = useGoogleMapsLoader();
69266
+ if (load) {
69267
+ load(apiKey).catch(console.error);
69268
+ }
69269
+ }
69232
69270
  if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
69233
69271
  isInitializedRef.current = true;
69234
69272
  const map2 = new google.maps.Map(mapContainerRef.current, {
@@ -69250,7 +69288,7 @@ const MapContent = React__default.forwardRef(
69250
69288
  isInitializedRef.current = false;
69251
69289
  mapRef.current = null;
69252
69290
  };
69253
- }, [isLoaded]);
69291
+ }, [isLoaded, apiKey]);
69254
69292
  useEffect(() => {
69255
69293
  var _a, _b;
69256
69294
  const map2 = mapRef.current;
@@ -69525,6 +69563,12 @@ const RouteMapContent = React__default.forwardRef(
69525
69563
  const isInitializedRef = useRef(false);
69526
69564
  const isCalculatingRef = useRef(false);
69527
69565
  useEffect(() => {
69566
+ if (!isLoaded && apiKey && !loadError) {
69567
+ const { load } = useGoogleMapsLoader();
69568
+ if (load) {
69569
+ load(apiKey).catch(console.error);
69570
+ }
69571
+ }
69528
69572
  if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
69529
69573
  isInitializedRef.current = true;
69530
69574
  const map2 = new google.maps.Map(mapContainerRef.current, {
@@ -69557,7 +69601,7 @@ const RouteMapContent = React__default.forwardRef(
69557
69601
  isInitializedRef.current = false;
69558
69602
  mapRef.current = null;
69559
69603
  };
69560
- }, [isLoaded]);
69604
+ }, [isLoaded, apiKey]);
69561
69605
  useEffect(() => {
69562
69606
  const map2 = mapRef.current;
69563
69607
  const renderer = directionsRendererRef.current;
package/dist/index.umd.js CHANGED
@@ -47754,7 +47754,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
47754
47754
  const GOOGLE_MAPS_ID = "xertica-google-map-script";
47755
47755
  const GoogleMapsContext = React.createContext({
47756
47756
  isLoaded: false,
47757
- loadError: void 0
47757
+ loadError: void 0,
47758
+ load: () => Promise.resolve()
47758
47759
  });
47759
47760
  function getInitialApiKey() {
47760
47761
  if (typeof window === "undefined") return void 0;
@@ -47875,7 +47876,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
47875
47876
  window.__XERTICA_GOOGLE_MAPS_LOADER__ = {
47876
47877
  isLoaded: isPreloaded,
47877
47878
  loadError: void 0,
47878
- listeners: /* @__PURE__ */ new Set()
47879
+ listeners: /* @__PURE__ */ new Set(),
47880
+ scriptElement: void 0
47879
47881
  };
47880
47882
  }
47881
47883
  return window.__XERTICA_GOOGLE_MAPS_LOADER__;
@@ -47885,16 +47887,40 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
47885
47887
  if (!singleton) return;
47886
47888
  if (state.isLoaded !== void 0) singleton.isLoaded = state.isLoaded;
47887
47889
  if (state.loadError !== void 0) singleton.loadError = state.loadError;
47888
- const newState = { isLoaded: singleton.isLoaded, loadError: singleton.loadError };
47890
+ const newState = {
47891
+ isLoaded: singleton.isLoaded,
47892
+ loadError: singleton.loadError,
47893
+ load: async (apiKey) => {
47894
+ if (singleton.isLoaded) return;
47895
+ try {
47896
+ await loadGoogleMapsScript(apiKey);
47897
+ updateSingleton({ isLoaded: true, loadError: void 0 });
47898
+ } catch (error) {
47899
+ updateSingleton({ isLoaded: false, loadError: error });
47900
+ throw error;
47901
+ }
47902
+ }
47903
+ };
47889
47904
  singleton.listeners.forEach((listener) => listener(newState));
47890
47905
  }
47891
47906
  const SingletonLoaderWrapper = ({ children }) => {
47892
47907
  const [state, setState] = React.useState(() => {
47893
47908
  const singleton = getOrCreateSingleton();
47894
- if (!singleton) return { isLoaded: false, loadError: void 0 };
47909
+ const loadFn = async (apiKey) => {
47910
+ if (singleton == null ? void 0 : singleton.isLoaded) return;
47911
+ try {
47912
+ await loadGoogleMapsScript(apiKey);
47913
+ updateSingleton({ isLoaded: true, loadError: void 0 });
47914
+ } catch (error) {
47915
+ updateSingleton({ isLoaded: false, loadError: error });
47916
+ throw error;
47917
+ }
47918
+ };
47919
+ if (!singleton) return { isLoaded: false, loadError: void 0, load: loadFn };
47895
47920
  return {
47896
47921
  isLoaded: singleton.isLoaded,
47897
- loadError: singleton.loadError
47922
+ loadError: singleton.loadError,
47923
+ load: loadFn
47898
47924
  };
47899
47925
  });
47900
47926
  React.useEffect(() => {
@@ -47904,14 +47930,18 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
47904
47930
  setState(newState);
47905
47931
  };
47906
47932
  singleton.listeners.add(listener);
47907
- listener({ isLoaded: singleton.isLoaded, loadError: singleton.loadError });
47933
+ listener({
47934
+ isLoaded: singleton.isLoaded,
47935
+ loadError: singleton.loadError,
47936
+ load: state.load
47937
+ });
47908
47938
  return () => {
47909
47939
  singleton.listeners.delete(listener);
47910
47940
  };
47911
47941
  }, []);
47912
47942
  return /* @__PURE__ */ jsxRuntimeExports.jsx(GoogleMapsContext.Provider, { value: state, children });
47913
47943
  };
47914
- const LoaderInitializer = () => {
47944
+ const LoaderInitializer = ({ apiKey }) => {
47915
47945
  const hasInitializedRef = React.useRef(false);
47916
47946
  React.useEffect(() => {
47917
47947
  if (hasInitializedRef.current) {
@@ -47925,8 +47955,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
47925
47955
  return;
47926
47956
  }
47927
47957
  hasInitializedRef.current = true;
47928
- const apiKey = getInitialApiKey();
47929
- if (!apiKey) {
47958
+ const keyToUse = apiKey || getInitialApiKey();
47959
+ if (!keyToUse) {
47930
47960
  updateSingleton({
47931
47961
  isLoaded: false,
47932
47962
  loadError: void 0
@@ -47934,15 +47964,15 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
47934
47964
  });
47935
47965
  return;
47936
47966
  }
47937
- loadGoogleMapsScript(apiKey).then(() => {
47967
+ loadGoogleMapsScript(keyToUse).then(() => {
47938
47968
  updateSingleton({ isLoaded: true, loadError: void 0 });
47939
47969
  }).catch((error) => {
47940
47970
  updateSingleton({ isLoaded: false, loadError: error });
47941
47971
  });
47942
- }, []);
47972
+ }, [apiKey]);
47943
47973
  return null;
47944
47974
  };
47945
- const GoogleMapsLoaderProvider = ({ children }) => {
47975
+ const GoogleMapsLoaderProvider = ({ children, apiKey }) => {
47946
47976
  const [shouldInitialize] = React.useState(() => {
47947
47977
  const singleton = getOrCreateSingleton();
47948
47978
  if (!singleton) return false;
@@ -47953,7 +47983,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
47953
47983
  return true;
47954
47984
  });
47955
47985
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
47956
- shouldInitialize && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderInitializer, {}),
47986
+ shouldInitialize && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderInitializer, { apiKey }),
47957
47987
  /* @__PURE__ */ jsxRuntimeExports.jsx(SingletonLoaderWrapper, { children })
47958
47988
  ] });
47959
47989
  };
@@ -50528,7 +50558,9 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
50528
50558
  onLogout,
50529
50559
  location: location2,
50530
50560
  navigate,
50531
- routes: routes2
50561
+ routes: routes2,
50562
+ logo,
50563
+ logoCollapsed
50532
50564
  }) {
50533
50565
  const navRef = React.useRef(null);
50534
50566
  const [hasOverflow, setHasOverflow] = React.useState(false);
@@ -50685,13 +50717,13 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
50685
50717
  "div",
50686
50718
  {
50687
50719
  className: `flex items-center h-10 ${expanded ? "justify-center" : "justify-center"}`,
50688
- children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(
50720
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: expanded ? logo || /* @__PURE__ */ jsxRuntimeExports.jsx(
50689
50721
  XerticaLogo,
50690
50722
  {
50691
50723
  className: "h-5 w-auto",
50692
50724
  variant: "white"
50693
50725
  }
50694
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
50726
+ ) : logoCollapsed || /* @__PURE__ */ jsxRuntimeExports.jsx(
50695
50727
  XerticaXLogo,
50696
50728
  {
50697
50729
  className: "h-5 w-auto",
@@ -69248,6 +69280,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert-
69248
69280
  }
69249
69281
  }, []);
69250
69282
  React.useEffect(() => {
69283
+ if (!isLoaded && apiKey && !loadError) {
69284
+ const { load } = useGoogleMapsLoader();
69285
+ if (load) {
69286
+ load(apiKey).catch(console.error);
69287
+ }
69288
+ }
69251
69289
  if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
69252
69290
  isInitializedRef.current = true;
69253
69291
  const map2 = new google.maps.Map(mapContainerRef.current, {
@@ -69269,7 +69307,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert-
69269
69307
  isInitializedRef.current = false;
69270
69308
  mapRef.current = null;
69271
69309
  };
69272
- }, [isLoaded]);
69310
+ }, [isLoaded, apiKey]);
69273
69311
  React.useEffect(() => {
69274
69312
  var _a, _b;
69275
69313
  const map2 = mapRef.current;
@@ -69544,6 +69582,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert-
69544
69582
  const isInitializedRef = React.useRef(false);
69545
69583
  const isCalculatingRef = React.useRef(false);
69546
69584
  React.useEffect(() => {
69585
+ if (!isLoaded && apiKey && !loadError) {
69586
+ const { load } = useGoogleMapsLoader();
69587
+ if (load) {
69588
+ load(apiKey).catch(console.error);
69589
+ }
69590
+ }
69547
69591
  if (!isLoaded || !mapContainerRef.current || isInitializedRef.current) return;
69548
69592
  isInitializedRef.current = true;
69549
69593
  const map2 = new google.maps.Map(mapContainerRef.current, {
@@ -69576,7 +69620,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/alert-
69576
69620
  isInitializedRef.current = false;
69577
69621
  mapRef.current = null;
69578
69622
  };
69579
- }, [isLoaded]);
69623
+ }, [isLoaded, apiKey]);
69580
69624
  React.useEffect(() => {
69581
69625
  const map2 = mapRef.current;
69582
69626
  const renderer = directionsRendererRef.current;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xertica-ui",
3
- "version": "1.3.7",
3
+ "version": "1.3.8",
4
4
  "description": "Xertica UI - Design System completo com componentes React e Tailwind CSS",
5
5
  "type": "module",
6
6
  "main": "./dist/index.umd.js",