@abpjs/theme-shared 2.7.0 → 3.0.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/index.mjs CHANGED
@@ -1,14 +1,3 @@
1
- // src/models/toaster.ts
2
- var Toaster;
3
- ((Toaster2) => {
4
- let Status;
5
- ((Status2) => {
6
- Status2["confirm"] = "confirm";
7
- Status2["reject"] = "reject";
8
- Status2["dismiss"] = "dismiss";
9
- })(Status = Toaster2.Status || (Toaster2.Status = {}));
10
- })(Toaster || (Toaster = {}));
11
-
12
1
  // src/models/confirmation.ts
13
2
  var Confirmation;
14
3
  ((Confirmation2) => {
@@ -21,6 +10,7 @@ var Confirmation;
21
10
  })(Confirmation || (Confirmation = {}));
22
11
 
23
12
  // src/constants/styles.ts
13
+ var BOOTSTRAP = "bootstrap-{{dir}}.min.css";
24
14
  var DEFAULT_STYLES = `
25
15
  .is-invalid .form-control {
26
16
  border-color: #dc3545;
@@ -36,6 +26,11 @@ var DEFAULT_STYLES = `
36
26
  text-align: right;
37
27
  }
38
28
 
29
+ /* RTL support - @since 2.9.0 */
30
+ [dir=rtl] .data-tables-filter {
31
+ text-align: left;
32
+ }
33
+
39
34
  .pointer {
40
35
  cursor: pointer;
41
36
  }
@@ -217,10 +212,19 @@ function useHttpErrorConfig() {
217
212
  return context ?? httpErrorConfigFactory();
218
213
  }
219
214
 
215
+ // src/tokens/lazy-styles.token.ts
216
+ import { createContext as createContext3, useContext as useContext2 } from "react";
217
+ var DEFAULT_LAZY_STYLES = [BOOTSTRAP];
218
+ var LazyStylesContext = createContext3(DEFAULT_LAZY_STYLES);
219
+ function useLazyStyles() {
220
+ return useContext2(LazyStylesContext);
221
+ }
222
+ var LAZY_STYLES = DEFAULT_LAZY_STYLES;
223
+
220
224
  // src/contexts/toaster.context.tsx
221
225
  import {
222
- createContext as createContext3,
223
- useContext as useContext2,
226
+ createContext as createContext4,
227
+ useContext as useContext3,
224
228
  useCallback,
225
229
  useState,
226
230
  useRef,
@@ -228,7 +232,7 @@ import {
228
232
  useEffect
229
233
  } from "react";
230
234
  import { jsx } from "react/jsx-runtime";
231
- var ToasterContext = createContext3(null);
235
+ var ToasterContext = createContext4(null);
232
236
  var toastCounter = 0;
233
237
  function generateId() {
234
238
  toastCounter += 1;
@@ -321,21 +325,21 @@ function ToasterProvider({ children }) {
321
325
  return /* @__PURE__ */ jsx(ToasterContext.Provider, { value, children });
322
326
  }
323
327
  function useToaster() {
324
- const context = useContext2(ToasterContext);
328
+ const context = useContext3(ToasterContext);
325
329
  if (!context) {
326
330
  throw new Error("useToaster must be used within a ToasterProvider");
327
331
  }
328
332
  return context.service;
329
333
  }
330
334
  function useToasts() {
331
- const context = useContext2(ToasterContext);
335
+ const context = useContext3(ToasterContext);
332
336
  if (!context) {
333
337
  throw new Error("useToasts must be used within a ToasterProvider");
334
338
  }
335
339
  return context.toasts;
336
340
  }
337
341
  function useToasterContext() {
338
- const context = useContext2(ToasterContext);
342
+ const context = useContext3(ToasterContext);
339
343
  if (!context) {
340
344
  throw new Error("useToasterContext must be used within a ToasterProvider");
341
345
  }
@@ -344,8 +348,8 @@ function useToasterContext() {
344
348
 
345
349
  // src/contexts/confirmation.context.tsx
346
350
  import {
347
- createContext as createContext4,
348
- useContext as useContext3,
351
+ createContext as createContext5,
352
+ useContext as useContext4,
349
353
  useCallback as useCallback2,
350
354
  useState as useState2,
351
355
  useRef as useRef2,
@@ -353,7 +357,7 @@ import {
353
357
  useEffect as useEffect2
354
358
  } from "react";
355
359
  import { jsx as jsx2 } from "react/jsx-runtime";
356
- var ConfirmationContext = createContext4(null);
360
+ var ConfirmationContext = createContext5(null);
357
361
  function generateId2() {
358
362
  return `confirmation-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
359
363
  }
@@ -377,7 +381,7 @@ function ConfirmationProvider({ children }) {
377
381
  useEffect2(() => {
378
382
  if (!escapeListenerRef.current) return;
379
383
  const handleEscape = (event) => {
380
- if (event.key === "Escape" && confirmation && confirmation.options?.closable !== false) {
384
+ if (event.key === "Escape" && confirmation && confirmation.options?.dismissible !== false) {
381
385
  respond(Confirmation.Status.dismiss);
382
386
  }
383
387
  };
@@ -460,21 +464,21 @@ function ConfirmationProvider({ children }) {
460
464
  return /* @__PURE__ */ jsx2(ConfirmationContext.Provider, { value, children });
461
465
  }
462
466
  function useConfirmation() {
463
- const context = useContext3(ConfirmationContext);
467
+ const context = useContext4(ConfirmationContext);
464
468
  if (!context) {
465
469
  throw new Error("useConfirmation must be used within a ConfirmationProvider");
466
470
  }
467
471
  return context.service;
468
472
  }
469
473
  function useConfirmationState() {
470
- const context = useContext3(ConfirmationContext);
474
+ const context = useContext4(ConfirmationContext);
471
475
  if (!context) {
472
476
  throw new Error("useConfirmationState must be used within a ConfirmationProvider");
473
477
  }
474
478
  return { confirmation: context.confirmation, respond: context.respond };
475
479
  }
476
480
  function useConfirmationContext() {
477
- const context = useContext3(ConfirmationContext);
481
+ const context = useContext4(ConfirmationContext);
478
482
  if (!context) {
479
483
  throw new Error("useConfirmationContext must be used within a ConfirmationProvider");
480
484
  }
@@ -483,15 +487,15 @@ function useConfirmationContext() {
483
487
 
484
488
  // src/contexts/modal.context.tsx
485
489
  import {
486
- createContext as createContext5,
487
- useContext as useContext4,
490
+ createContext as createContext6,
491
+ useContext as useContext5,
488
492
  useCallback as useCallback3,
489
493
  useState as useState3,
490
494
  useRef as useRef3,
491
495
  useMemo as useMemo3
492
496
  } from "react";
493
497
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
494
- var ModalContext = createContext5(null);
498
+ var ModalContext = createContext6(null);
495
499
  function ModalProvider({ children }) {
496
500
  const [modalState, setModalState] = useState3(null);
497
501
  const [, setUpdateCounter] = useState3(0);
@@ -527,21 +531,21 @@ function ModalProvider({ children }) {
527
531
  ] });
528
532
  }
529
533
  function useModal() {
530
- const context = useContext4(ModalContext);
534
+ const context = useContext5(ModalContext);
531
535
  if (!context) {
532
536
  throw new Error("useModal must be used within a ModalProvider");
533
537
  }
534
538
  return context.service;
535
539
  }
536
540
  function useModalState() {
537
- const context = useContext4(ModalContext);
541
+ const context = useContext5(ModalContext);
538
542
  if (!context) {
539
543
  throw new Error("useModalState must be used within a ModalProvider");
540
544
  }
541
545
  return context.modalState;
542
546
  }
543
547
  function useModalContext() {
544
- const context = useContext4(ModalContext);
548
+ const context = useContext5(ModalContext);
545
549
  if (!context) {
546
550
  throw new Error("useModalContext must be used within a ModalProvider");
547
551
  }
@@ -637,8 +641,151 @@ function isHttpErrorResponse(error) {
637
641
  return typeof error === "object" && error !== null && "status" in error && typeof error.status === "number";
638
642
  }
639
643
 
644
+ // src/hooks/use-nav-items.ts
645
+ import { useState as useState5, useEffect as useEffect3 } from "react";
646
+
647
+ // src/services/nav-items.service.ts
648
+ var _NavItemsService = class _NavItemsService {
649
+ constructor() {
650
+ this._items = [];
651
+ this._listeners = /* @__PURE__ */ new Set();
652
+ }
653
+ /**
654
+ * Get singleton instance
655
+ * @since 3.0.0
656
+ */
657
+ static getInstance() {
658
+ if (!_NavItemsService._instance) {
659
+ _NavItemsService._instance = new _NavItemsService();
660
+ }
661
+ return _NavItemsService._instance;
662
+ }
663
+ /**
664
+ * Reset the singleton instance (useful for testing)
665
+ * @internal
666
+ */
667
+ static resetInstance() {
668
+ _NavItemsService._instance = null;
669
+ }
670
+ /**
671
+ * Get current items (sorted by order)
672
+ * @since 3.0.0
673
+ */
674
+ get items() {
675
+ return [...this._items].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
676
+ }
677
+ /**
678
+ * Subscribe to item changes.
679
+ * Returns an unsubscribe function.
680
+ *
681
+ * @param listener - Callback function to receive item updates
682
+ * @returns Unsubscribe function
683
+ * @since 3.0.0
684
+ */
685
+ subscribe(listener) {
686
+ this._listeners.add(listener);
687
+ listener(this.items);
688
+ return () => {
689
+ this._listeners.delete(listener);
690
+ };
691
+ }
692
+ /**
693
+ * Get items as an observable-like interface.
694
+ * Compatible with Angular's Observable pattern.
695
+ *
696
+ * @returns Object with subscribe method
697
+ * @since 3.0.0
698
+ */
699
+ get items$() {
700
+ return {
701
+ subscribe: (callback) => {
702
+ const unsubscribe = this.subscribe(callback);
703
+ return { unsubscribe };
704
+ }
705
+ };
706
+ }
707
+ /**
708
+ * Add one or more items.
709
+ * Items are automatically sorted by order.
710
+ *
711
+ * @param items - Array of items to add
712
+ * @since 3.0.0
713
+ */
714
+ addItems(items) {
715
+ const existingIds = new Set(this._items.map((item) => item.id));
716
+ const newItems = items.filter((item) => !existingIds.has(item.id));
717
+ this._items = [...this._items, ...newItems];
718
+ this.notify();
719
+ }
720
+ /**
721
+ * Remove an item by id.
722
+ *
723
+ * @param id - The id of the item to remove
724
+ * @since 3.0.0
725
+ */
726
+ removeItem(id) {
727
+ const initialLength = this._items.length;
728
+ this._items = this._items.filter((item) => item.id !== id);
729
+ if (this._items.length !== initialLength) {
730
+ this.notify();
731
+ }
732
+ }
733
+ /**
734
+ * Patch an existing item by id.
735
+ * Updates only the specified properties.
736
+ *
737
+ * @param id - The id of the item to patch
738
+ * @param patch - Partial item data to merge
739
+ * @since 3.0.0
740
+ */
741
+ patchItem(id, patch) {
742
+ const index = this._items.findIndex((item) => item.id === id);
743
+ if (index !== -1) {
744
+ this._items = [
745
+ ...this._items.slice(0, index),
746
+ { ...this._items[index], ...patch },
747
+ ...this._items.slice(index + 1)
748
+ ];
749
+ this.notify();
750
+ }
751
+ }
752
+ /**
753
+ * Clear all items.
754
+ * @since 3.0.0
755
+ */
756
+ clear() {
757
+ if (this._items.length > 0) {
758
+ this._items = [];
759
+ this.notify();
760
+ }
761
+ }
762
+ /**
763
+ * Notify all listeners of changes.
764
+ */
765
+ notify() {
766
+ const currentItems = this.items;
767
+ this._listeners.forEach((listener) => listener(currentItems));
768
+ }
769
+ };
770
+ _NavItemsService._instance = null;
771
+ var NavItemsService = _NavItemsService;
772
+ function getNavItemsService() {
773
+ return NavItemsService.getInstance();
774
+ }
775
+
776
+ // src/hooks/use-nav-items.ts
777
+ function useNavItems(service) {
778
+ const navItemsService = service || getNavItemsService();
779
+ const [items, setItems] = useState5(navItemsService.items);
780
+ useEffect3(() => {
781
+ const unsubscribe = navItemsService.subscribe(setItems);
782
+ return unsubscribe;
783
+ }, [navItemsService]);
784
+ return items;
785
+ }
786
+
640
787
  // src/components/toast/Toast.tsx
641
- import { useEffect as useEffect3, useRef as useRef4, useMemo as useMemo4 } from "react";
788
+ import { useEffect as useEffect4, useRef as useRef4, useMemo as useMemo4 } from "react";
642
789
  import {
643
790
  Toaster as ChakraToaster,
644
791
  Portal,
@@ -778,7 +925,7 @@ function ToastContainer({ position = "bottom-right", containerKey }) {
778
925
  if (!containerKey) return toasts;
779
926
  return toasts.filter((toast) => toast.options?.containerKey === containerKey);
780
927
  }, [toasts, containerKey]);
781
- useEffect3(() => {
928
+ useEffect4(() => {
782
929
  const newToasts = filteredToasts.filter((toast) => !displayedToastsRef.current.has(toast.id));
783
930
  newToasts.forEach((toast) => {
784
931
  displayedToastsRef.current.add(toast.id);
@@ -924,7 +1071,7 @@ function ConfirmationDialog({ className }) {
924
1071
  respond(Confirmation.Status.dismiss);
925
1072
  };
926
1073
  const handleOpenChange = (details) => {
927
- if (!details.open && options?.closable !== false) {
1074
+ if (!details.open && options?.dismissible !== false) {
928
1075
  handleDismiss();
929
1076
  }
930
1077
  };
@@ -1017,35 +1164,21 @@ function ErrorComponent({
1017
1164
  }
1018
1165
 
1019
1166
  // src/components/loader-bar/LoaderBar.tsx
1020
- import { useEffect as useEffect4, useRef as useRef6, useState as useState5 } from "react";
1167
+ import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef6, useState as useState6 } from "react";
1021
1168
  import { useLoader } from "@abpjs/core";
1022
1169
  import { jsx as jsx7 } from "react/jsx-runtime";
1023
1170
  function LoaderBar({
1024
1171
  containerClass = "abp-loader-bar",
1025
1172
  progressClass = "abp-progress",
1026
- filter,
1173
+ filter: _filter,
1027
1174
  intervalPeriod = 300,
1028
1175
  stopDelay = 400
1029
1176
  }) {
1030
1177
  const { loading } = useLoader();
1031
- const [isLoading, setIsLoading] = useState5(false);
1032
- const [progressLevel, setProgressLevel] = useState5(0);
1178
+ const [isLoading, setIsLoading] = useState6(false);
1179
+ const [progressLevel, setProgressLevel] = useState6(0);
1033
1180
  const intervalRef = useRef6(null);
1034
- useEffect4(() => {
1035
- if (loading) {
1036
- startLoading();
1037
- } else {
1038
- stopLoading();
1039
- }
1040
- }, [loading]);
1041
- useEffect4(() => {
1042
- return () => {
1043
- if (intervalRef.current) {
1044
- clearInterval(intervalRef.current);
1045
- }
1046
- };
1047
- }, []);
1048
- const startLoading = () => {
1181
+ const startLoading = useCallback5(() => {
1049
1182
  setIsLoading(true);
1050
1183
  setProgressLevel(0);
1051
1184
  if (intervalRef.current) {
@@ -1063,8 +1196,8 @@ function LoaderBar({
1063
1196
  return prev + 10;
1064
1197
  });
1065
1198
  }, intervalPeriod);
1066
- };
1067
- const stopLoading = () => {
1199
+ }, [intervalPeriod]);
1200
+ const stopLoading = useCallback5(() => {
1068
1201
  setProgressLevel(100);
1069
1202
  if (intervalRef.current) {
1070
1203
  clearInterval(intervalRef.current);
@@ -1074,7 +1207,21 @@ function LoaderBar({
1074
1207
  setIsLoading(false);
1075
1208
  setProgressLevel(0);
1076
1209
  }, stopDelay);
1077
- };
1210
+ }, [stopDelay]);
1211
+ useEffect5(() => {
1212
+ if (loading) {
1213
+ startLoading();
1214
+ } else {
1215
+ stopLoading();
1216
+ }
1217
+ }, [loading, startLoading, stopLoading]);
1218
+ useEffect5(() => {
1219
+ return () => {
1220
+ if (intervalRef.current) {
1221
+ clearInterval(intervalRef.current);
1222
+ }
1223
+ };
1224
+ }, []);
1078
1225
  if (!isLoading && progressLevel === 0) {
1079
1226
  return null;
1080
1227
  }
@@ -1109,7 +1256,7 @@ function LoaderBar({
1109
1256
  }
1110
1257
 
1111
1258
  // src/components/modal/Modal.tsx
1112
- import React7 from "react";
1259
+ import React6 from "react";
1113
1260
  import {
1114
1261
  Dialog as Dialog2,
1115
1262
  Portal as Portal3,
@@ -1157,12 +1304,12 @@ function Modal({
1157
1304
  preventScroll = true,
1158
1305
  onInit
1159
1306
  }) {
1160
- const prevVisibleRef = React7.useRef(false);
1161
- const onInitRef = React7.useRef(onInit);
1162
- React7.useEffect(() => {
1307
+ const prevVisibleRef = React6.useRef(false);
1308
+ const onInitRef = React6.useRef(onInit);
1309
+ React6.useEffect(() => {
1163
1310
  onInitRef.current = onInit;
1164
1311
  }, [onInit]);
1165
- React7.useEffect(() => {
1312
+ React6.useEffect(() => {
1166
1313
  if (visible && !prevVisibleRef.current && onInitRef.current) {
1167
1314
  onInitRef.current();
1168
1315
  }
@@ -1378,7 +1525,7 @@ function FormField({
1378
1525
  }
1379
1526
 
1380
1527
  // src/components/change-password/ChangePassword.tsx
1381
- import { useEffect as useEffect5 } from "react";
1528
+ import { useEffect as useEffect6 } from "react";
1382
1529
  import {
1383
1530
  Button as Button5,
1384
1531
  VStack as VStack2,
@@ -1410,7 +1557,7 @@ function ChangePassword({
1410
1557
  }
1411
1558
  });
1412
1559
  const newPassword = watch("newPassword");
1413
- useEffect5(() => {
1560
+ useEffect6(() => {
1414
1561
  if (visible) {
1415
1562
  reset();
1416
1563
  }
@@ -1530,7 +1677,7 @@ function ChangePassword({
1530
1677
  }
1531
1678
 
1532
1679
  // src/components/profile/Profile.tsx
1533
- import { useEffect as useEffect6 } from "react";
1680
+ import { useEffect as useEffect7 } from "react";
1534
1681
  import {
1535
1682
  Button as Button6,
1536
1683
  VStack as VStack3,
@@ -1564,13 +1711,13 @@ function Profile({
1564
1711
  }
1565
1712
  });
1566
1713
  const modalBusy = isSubmitting || loading;
1567
- useEffect6(() => {
1714
+ useEffect7(() => {
1568
1715
  if (visible) {
1569
1716
  fetchProfile().then(() => {
1570
1717
  });
1571
1718
  }
1572
1719
  }, [visible, fetchProfile]);
1573
- useEffect6(() => {
1720
+ useEffect7(() => {
1574
1721
  if (profile) {
1575
1722
  reset({
1576
1723
  userName: profile.userName || "",
@@ -1965,7 +2112,7 @@ var abpSystem = createAbpSystem();
1965
2112
  // src/components/ui/color-mode.tsx
1966
2113
  import { ClientOnly, IconButton, Skeleton, Span } from "@chakra-ui/react";
1967
2114
  import { ThemeProvider, useTheme } from "next-themes";
1968
- import * as React12 from "react";
2115
+ import * as React11 from "react";
1969
2116
  import { Moon, Sun } from "lucide-react";
1970
2117
  import { jsx as jsx15 } from "react/jsx-runtime";
1971
2118
  function ColorModeProvider(props) {
@@ -1987,7 +2134,7 @@ function ColorModeIcon() {
1987
2134
  const { colorMode } = useColorMode();
1988
2135
  return colorMode === "dark" ? /* @__PURE__ */ jsx15(Moon, {}) : /* @__PURE__ */ jsx15(Sun, {});
1989
2136
  }
1990
- var ColorModeButton = React12.forwardRef(function ColorModeButton2(props, ref) {
2137
+ var ColorModeButton = React11.forwardRef(function ColorModeButton2(props, ref) {
1991
2138
  const { toggleColorMode } = useColorMode();
1992
2139
  return /* @__PURE__ */ jsx15(ClientOnly, { fallback: /* @__PURE__ */ jsx15(Skeleton, { boxSize: "9" }), children: /* @__PURE__ */ jsx15(
1993
2140
  IconButton,
@@ -2008,7 +2155,7 @@ var ColorModeButton = React12.forwardRef(function ColorModeButton2(props, ref) {
2008
2155
  }
2009
2156
  ) });
2010
2157
  });
2011
- var LightMode = React12.forwardRef(
2158
+ var LightMode = React11.forwardRef(
2012
2159
  function LightMode2(props, ref) {
2013
2160
  return /* @__PURE__ */ jsx15(
2014
2161
  Span,
@@ -2024,7 +2171,7 @@ var LightMode = React12.forwardRef(
2024
2171
  );
2025
2172
  }
2026
2173
  );
2027
- var DarkMode = React12.forwardRef(
2174
+ var DarkMode = React11.forwardRef(
2028
2175
  function DarkMode2(props, ref) {
2029
2176
  return /* @__PURE__ */ jsx15(
2030
2177
  Span,
@@ -2049,23 +2196,120 @@ function ThemeSharedProvider({
2049
2196
  renderToasts = true,
2050
2197
  renderConfirmation = true,
2051
2198
  themeOverrides,
2052
- toastPosition = "bottom-right",
2199
+ toastPosition: _toastPosition = "bottom-right",
2053
2200
  enableColorMode = false,
2054
2201
  defaultColorMode = "light",
2055
2202
  locale = "en-US"
2056
2203
  }) {
2057
2204
  const system = themeOverrides ? createAbpSystem(themeOverrides) : abpSystem;
2058
2205
  const { endSide } = useDirection();
2059
- toastPosition = `bottom-${endSide}`;
2206
+ const resolvedToastPosition = endSide === "left" ? "bottom-left" : "bottom-right";
2060
2207
  const content = /* @__PURE__ */ jsx16(ToasterProvider, { children: /* @__PURE__ */ jsxs11(ConfirmationProvider, { children: [
2061
2208
  children,
2062
- renderToasts && /* @__PURE__ */ jsx16(ToastContainer, { position: toastPosition }),
2209
+ renderToasts && /* @__PURE__ */ jsx16(ToastContainer, { position: resolvedToastPosition }),
2063
2210
  renderConfirmation && /* @__PURE__ */ jsx16(ConfirmationDialog, {})
2064
2211
  ] }) });
2065
2212
  const colorModeProps = enableColorMode ? { defaultTheme: defaultColorMode } : { forcedTheme: "light" };
2066
2213
  return /* @__PURE__ */ jsx16(ChakraProvider, { value: system, children: /* @__PURE__ */ jsx16(LocaleProvider, { locale, children: /* @__PURE__ */ jsx16(ColorModeProvider, { ...colorModeProps, children: content }) }) });
2067
2214
  }
2068
2215
 
2216
+ // src/providers/route.provider.ts
2217
+ import { getRoutesService } from "@abpjs/core";
2218
+
2219
+ // src/enums/route-names.ts
2220
+ var eThemeSharedRouteNames = /* @__PURE__ */ ((eThemeSharedRouteNames2) => {
2221
+ eThemeSharedRouteNames2["Administration"] = "AbpUiNavigation::Menu:Administration";
2222
+ return eThemeSharedRouteNames2;
2223
+ })(eThemeSharedRouteNames || {});
2224
+
2225
+ // src/providers/route.provider.ts
2226
+ function configureRoutes(routes) {
2227
+ return () => {
2228
+ routes.add([
2229
+ {
2230
+ name: "AbpUiNavigation::Menu:Administration" /* Administration */,
2231
+ path: "",
2232
+ order: 100,
2233
+ iconClass: "fa fa-wrench"
2234
+ }
2235
+ ]);
2236
+ };
2237
+ }
2238
+ var THEME_SHARED_ROUTE_PROVIDERS = {
2239
+ configureRoutes
2240
+ };
2241
+ function initializeThemeSharedRoutes() {
2242
+ const routesService = getRoutesService();
2243
+ configureRoutes(routesService)();
2244
+ }
2245
+
2246
+ // src/handlers/lazy-style.handler.ts
2247
+ import { useEffect as useEffect8, useRef as useRef7, useState as useState7 } from "react";
2248
+ import { LazyLoadService } from "@abpjs/core";
2249
+ function createLazyStyleHref(style, dir) {
2250
+ return style.replace("{{dir}}", dir);
2251
+ }
2252
+ function useLazyStyleHandler(options = {}) {
2253
+ const { styles = [BOOTSTRAP], initialDirection = "ltr" } = options;
2254
+ const [direction, setDirection] = useState7(initialDirection);
2255
+ const lazyLoadRef = useRef7(new LazyLoadService());
2256
+ const loadedStylesRef = useRef7(/* @__PURE__ */ new Map());
2257
+ useEffect8(() => {
2258
+ document.body.dir = direction;
2259
+ const switchCSS = async () => {
2260
+ const lazyLoad = lazyLoadRef.current;
2261
+ for (const style of styles) {
2262
+ const href = createLazyStyleHref(style, direction);
2263
+ if (lazyLoad.isLoaded(href)) {
2264
+ continue;
2265
+ }
2266
+ const oldDir = direction === "ltr" ? "rtl" : "ltr";
2267
+ const oldHref = createLazyStyleHref(style, oldDir);
2268
+ const oldLink = loadedStylesRef.current.get(oldHref);
2269
+ if (oldLink && oldLink.parentNode) {
2270
+ oldLink.parentNode.removeChild(oldLink);
2271
+ lazyLoad.remove(oldHref);
2272
+ loadedStylesRef.current.delete(oldHref);
2273
+ }
2274
+ try {
2275
+ const link = document.createElement("link");
2276
+ link.rel = "stylesheet";
2277
+ link.href = href;
2278
+ document.head.appendChild(link);
2279
+ loadedStylesRef.current.set(href, link);
2280
+ } catch (error) {
2281
+ console.warn(`Failed to load style: ${href}`, error);
2282
+ }
2283
+ }
2284
+ };
2285
+ switchCSS();
2286
+ }, [direction, styles]);
2287
+ return {
2288
+ direction,
2289
+ setDirection
2290
+ };
2291
+ }
2292
+ function getLoadedBootstrapDirection(styles = [BOOTSTRAP]) {
2293
+ for (const style of styles) {
2294
+ const ltrHref = createLazyStyleHref(style, "ltr");
2295
+ const rtlHref = createLazyStyleHref(style, "rtl");
2296
+ const links = document.querySelectorAll('link[rel="stylesheet"]');
2297
+ for (const link of links) {
2298
+ const href = link.href;
2299
+ if (href.includes(ltrHref)) return "ltr";
2300
+ if (href.includes(rtlHref)) return "rtl";
2301
+ }
2302
+ }
2303
+ return void 0;
2304
+ }
2305
+ function initLazyStyleHandler(options = {}) {
2306
+ return () => {
2307
+ const { initialDirection = "ltr" } = options;
2308
+ document.body.dir = initialDirection;
2309
+ return { direction: initialDirection };
2310
+ };
2311
+ }
2312
+
2069
2313
  // src/utils/styles.ts
2070
2314
  var THEME_SHARED_STYLES = `
2071
2315
  /* Form validation styling */
@@ -2255,6 +2499,7 @@ export {
2255
2499
  AbpModalFooter,
2256
2500
  AbpModalHeader,
2257
2501
  Alert,
2502
+ BOOTSTRAP,
2258
2503
  Button3 as Button,
2259
2504
  Dialog2 as ChakraDialog,
2260
2505
  ChangePassword,
@@ -2262,11 +2507,14 @@ export {
2262
2507
  Confirmation,
2263
2508
  ConfirmationDialog,
2264
2509
  ConfirmationProvider,
2510
+ DEFAULT_LAZY_STYLES,
2265
2511
  DEFAULT_STYLES,
2266
2512
  ErrorComponent,
2267
2513
  FormField,
2268
2514
  HTTP_ERROR_CONFIG,
2269
2515
  HttpErrorConfigContext,
2516
+ LAZY_STYLES,
2517
+ LazyStylesContext,
2270
2518
  LoaderBar,
2271
2519
  Modal,
2272
2520
  AbpModalBody as ModalBody,
@@ -2274,20 +2522,26 @@ export {
2274
2522
  AbpModalFooter as ModalFooter,
2275
2523
  AbpModalHeader as ModalHeader,
2276
2524
  ModalProvider,
2525
+ NavItemsService,
2277
2526
  PASSWORD_SETTING_KEYS,
2278
2527
  Profile,
2279
2528
  THEME_SHARED_APPEND_CONTENT,
2529
+ THEME_SHARED_ROUTE_PROVIDERS,
2280
2530
  THEME_SHARED_STYLES,
2281
2531
  ThemeSharedAppendContentContext,
2282
2532
  ThemeSharedProvider,
2283
2533
  ToastContainer,
2284
- Toaster,
2285
2534
  ToasterProvider,
2286
2535
  abpSystem,
2536
+ configureRoutes,
2287
2537
  createAbpSystem,
2288
2538
  createErrorInterceptor,
2539
+ createLazyStyleHref,
2289
2540
  defaultAbpConfig,
2290
2541
  defineConfig,
2542
+ eThemeSharedRouteNames,
2543
+ getLoadedBootstrapDirection,
2544
+ getNavItemsService,
2291
2545
  getPasswordSettings,
2292
2546
  getPasswordValidationRules,
2293
2547
  getPasswordValidators,
@@ -2295,15 +2549,20 @@ export {
2295
2549
  getSeverityBorderColor,
2296
2550
  getSeverityColorPalette as getSeverityColorScheme,
2297
2551
  httpErrorConfigFactory,
2552
+ initLazyStyleHandler,
2553
+ initializeThemeSharedRoutes,
2298
2554
  injectThemeSharedStyles,
2299
2555
  useConfirmation,
2300
2556
  useConfirmationContext,
2301
2557
  useConfirmationState,
2302
2558
  useErrorHandler,
2303
2559
  useHttpErrorConfig,
2560
+ useLazyStyleHandler,
2561
+ useLazyStyles,
2304
2562
  useModal,
2305
2563
  useModalContext,
2306
2564
  useModalState,
2565
+ useNavItems,
2307
2566
  useToaster,
2308
2567
  useToasterContext,
2309
2568
  useToasts