@admin-layout/tailwind-design-pro 12.0.16-alpha.7 → 12.0.16-alpha.71

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.
Files changed (182) hide show
  1. package/README.md +20 -0
  2. package/lib/cdm-locales/en/menu.json +2 -1
  3. package/lib/cdm-locales/es/menu.json +2 -1
  4. package/lib/cdm-locales/index.d.ts +2 -0
  5. package/lib/cdm-locales/index.d.ts.map +1 -0
  6. package/lib/cdm-locales/index.ts +1 -0
  7. package/lib/components/LanguageMenu/LanguageMenu.js.map +1 -1
  8. package/lib/components/Layout/BasicLayout/index.d.ts +2 -1
  9. package/lib/components/Layout/BasicLayout/index.d.ts.map +1 -1
  10. package/lib/components/Layout/BasicLayout/index.js +134 -44
  11. package/lib/components/Layout/BasicLayout/index.js.map +1 -1
  12. package/lib/components/Layout/BasicLayout/utils.d.ts +2 -0
  13. package/lib/components/Layout/BasicLayout/utils.d.ts.map +1 -1
  14. package/lib/components/Layout/BasicLayout/utils.js +16 -13
  15. package/lib/components/Layout/BasicLayout/utils.js.map +1 -1
  16. package/lib/components/Layout/GlobalFooter/Account.d.ts +4 -0
  17. package/lib/components/Layout/GlobalFooter/Account.d.ts.map +1 -0
  18. package/lib/components/Layout/GlobalFooter/BottomMenuDropdown.d.ts.map +1 -1
  19. package/lib/components/Layout/GlobalFooter/BottomMenuDropdown.js +7 -12
  20. package/lib/components/Layout/GlobalFooter/BottomMenuDropdown.js.map +1 -1
  21. package/lib/components/Layout/GlobalHeader/Header.d.ts.map +1 -1
  22. package/lib/components/Layout/GlobalHeader/Header.js +31 -8
  23. package/lib/components/Layout/GlobalHeader/Header.js.map +1 -1
  24. package/lib/components/Layout/GlobalHeader/MainHeader.d.ts +0 -2
  25. package/lib/components/Layout/GlobalHeader/MainHeader.d.ts.map +1 -1
  26. package/lib/components/Layout/GlobalHeader/MainHeader.js +54 -85
  27. package/lib/components/Layout/GlobalHeader/MainHeader.js.map +1 -1
  28. package/lib/components/Layout/GlobalHeader/OrganizationDropdown.js +1 -1
  29. package/lib/components/Layout/GlobalHeader/OrganizationDropdown.js.map +1 -1
  30. package/lib/components/Layout/GlobalHeader/RightContent.d.ts +1 -0
  31. package/lib/components/Layout/GlobalHeader/RightContent.d.ts.map +1 -1
  32. package/lib/components/Layout/GlobalHeader/RightContent.js +73 -6
  33. package/lib/components/Layout/GlobalHeader/RightContent.js.map +1 -1
  34. package/lib/components/Layout/GlobalHeader/RightMenu.d.ts.map +1 -1
  35. package/lib/components/Layout/GlobalHeader/RightMenu.js +2 -4
  36. package/lib/components/Layout/GlobalHeader/RightMenu.js.map +1 -1
  37. package/lib/components/Layout/GlobalHeader/SearchBar.js.map +1 -1
  38. package/lib/components/Layout/GlobalHeader/index.d.ts +0 -1
  39. package/lib/components/Layout/GlobalHeader/index.d.ts.map +1 -1
  40. package/lib/components/Layout/ProTailwindLayout.d.ts +2 -2
  41. package/lib/components/Layout/ProTailwindLayout.d.ts.map +1 -1
  42. package/lib/components/Layout/ProTailwindLayout.js +69 -7
  43. package/lib/components/Layout/ProTailwindLayout.js.map +1 -1
  44. package/lib/components/Layout/Sidebar/BottomMenu.d.ts +4 -0
  45. package/lib/components/Layout/Sidebar/BottomMenu.d.ts.map +1 -0
  46. package/lib/components/Layout/Sidebar/BottomMenu.js +330 -0
  47. package/lib/components/Layout/Sidebar/BottomMenu.js.map +1 -0
  48. package/lib/components/Layout/Sidebar/Divider.js.map +1 -1
  49. package/lib/components/Layout/Sidebar/DynamicIcon.js.map +1 -1
  50. package/lib/components/Layout/Sidebar/MainSidebar.d.ts +5 -0
  51. package/lib/components/Layout/Sidebar/MainSidebar.d.ts.map +1 -0
  52. package/lib/components/Layout/Sidebar/{Sidebar.js → MainSidebar.js} +94 -34
  53. package/lib/components/Layout/Sidebar/MainSidebar.js.map +1 -0
  54. package/lib/components/Layout/Sidebar/MainSidebarMenu.d.ts +4 -0
  55. package/lib/components/Layout/Sidebar/MainSidebarMenu.d.ts.map +1 -0
  56. package/lib/components/Layout/Sidebar/MainSidebarMenu.js +291 -0
  57. package/lib/components/Layout/Sidebar/MainSidebarMenu.js.map +1 -0
  58. package/lib/components/Layout/Sidebar/PerplexSidebar.d.ts +5 -0
  59. package/lib/components/Layout/Sidebar/PerplexSidebar.d.ts.map +1 -0
  60. package/lib/components/Layout/Sidebar/PerplexSidebar.js +277 -0
  61. package/lib/components/Layout/Sidebar/PerplexSidebar.js.map +1 -0
  62. package/lib/components/Layout/Sidebar/PerplexSidebarMenu.d.ts +4 -0
  63. package/lib/components/Layout/Sidebar/PerplexSidebarMenu.d.ts.map +1 -0
  64. package/lib/components/Layout/Sidebar/PerplexSidebarMenu.js +330 -0
  65. package/lib/components/Layout/Sidebar/PerplexSidebarMenu.js.map +1 -0
  66. package/lib/components/Layout/TailwindLayout.d.ts.map +1 -1
  67. package/lib/components/Layout/TailwindLayout.js +37 -10
  68. package/lib/components/Layout/TailwindLayout.js.map +1 -1
  69. package/lib/components/Layout/getPageTitle.js.map +1 -1
  70. package/lib/components/Layout/slot-fill/AdditionalSettings.js.map +1 -1
  71. package/lib/components/Layout/slot-fill/Footer.js.map +1 -1
  72. package/lib/components/Layout/slot-fill/HeaderSearchBar.js.map +1 -1
  73. package/lib/components/Layout/slot-fill/HeaderSearchButton.js.map +1 -1
  74. package/lib/components/Layout/slot-fill/Logo.d.ts +4 -0
  75. package/lib/components/Layout/slot-fill/Logo.d.ts.map +1 -0
  76. package/lib/components/Layout/slot-fill/Logo.js +7 -0
  77. package/lib/components/Layout/slot-fill/Logo.js.map +1 -0
  78. package/lib/components/Layout/slot-fill/RightContent.js.map +1 -1
  79. package/lib/components/Layout/slot-fill/SideMenuLogo.d.ts +4 -0
  80. package/lib/components/Layout/slot-fill/SideMenuLogo.d.ts.map +1 -0
  81. package/lib/components/Layout/slot-fill/SideMenuLogo.js +7 -0
  82. package/lib/components/Layout/slot-fill/SideMenuLogo.js.map +1 -0
  83. package/lib/components/Layout/slot-fill/index.d.ts +2 -0
  84. package/lib/components/Layout/slot-fill/index.d.ts.map +1 -1
  85. package/lib/components/Layout/util.js +1 -1
  86. package/lib/components/Layout/util.js.map +1 -1
  87. package/lib/components/SettingDrawer/CheckBoxTheme.d.ts.map +1 -1
  88. package/lib/components/SettingDrawer/CheckBoxTheme.js +13 -3
  89. package/lib/components/SettingDrawer/CheckBoxTheme.js.map +1 -1
  90. package/lib/components/SettingDrawer/InvitationSettings.d.ts.map +1 -1
  91. package/lib/components/SettingDrawer/InvitationSettings.js +10 -6
  92. package/lib/components/SettingDrawer/InvitationSettings.js.map +1 -1
  93. package/lib/components/SettingDrawer/LayoutChange.d.ts.map +1 -1
  94. package/lib/components/SettingDrawer/LayoutChange.js +23 -16
  95. package/lib/components/SettingDrawer/LayoutChange.js.map +1 -1
  96. package/lib/components/SettingDrawer/MenuVisibilitySettings.d.ts +20 -0
  97. package/lib/components/SettingDrawer/MenuVisibilitySettings.d.ts.map +1 -0
  98. package/lib/components/SettingDrawer/MenuVisibilitySettings.js +120 -0
  99. package/lib/components/SettingDrawer/MenuVisibilitySettings.js.map +1 -0
  100. package/lib/components/SettingDrawer/NavigationsModes.d.ts +1 -1
  101. package/lib/components/SettingDrawer/NavigationsModes.d.ts.map +1 -1
  102. package/lib/components/SettingDrawer/NavigationsModes.js +90 -39
  103. package/lib/components/SettingDrawer/NavigationsModes.js.map +1 -1
  104. package/lib/components/SettingDrawer/RegionalSettings.d.ts.map +1 -1
  105. package/lib/components/SettingDrawer/RegionalSettings.js +54 -177
  106. package/lib/components/SettingDrawer/RegionalSettings.js.map +1 -1
  107. package/lib/components/SettingDrawer/SettingDrawer.d.ts.map +1 -1
  108. package/lib/components/SettingDrawer/SettingDrawer.js +404 -66
  109. package/lib/components/SettingDrawer/SettingDrawer.js.map +1 -1
  110. package/lib/components/SettingDrawer/Switch/index.js.map +1 -1
  111. package/lib/components/SettingDrawer/ThemeColor.d.ts.map +1 -1
  112. package/lib/components/SettingDrawer/ThemeColor.js +15 -3
  113. package/lib/components/SettingDrawer/ThemeColor.js.map +1 -1
  114. package/lib/components/SettingDrawer/types.d.ts +12 -0
  115. package/lib/components/SettingDrawer/types.d.ts.map +1 -1
  116. package/lib/components/UpdateSettingsResource/UpdateSettingsResource.server.d.ts +10 -5
  117. package/lib/components/UpdateSettingsResource/UpdateSettingsResource.server.d.ts.map +1 -1
  118. package/lib/components/UpdateSettingsResource/UpdateSettingsResource.server.js +97 -4
  119. package/lib/components/UpdateSettingsResource/UpdateSettingsResource.server.js.map +1 -1
  120. package/lib/components/index.js +1 -1
  121. package/lib/components/typings.d.ts +20 -1
  122. package/lib/components/typings.d.ts.map +1 -1
  123. package/lib/compute.d.ts.map +1 -1
  124. package/lib/compute.js +10 -2
  125. package/lib/compute.js.map +1 -1
  126. package/lib/config/constants.js.map +1 -1
  127. package/lib/config/env-config.d.ts +3 -0
  128. package/lib/config/env-config.d.ts.map +1 -1
  129. package/lib/config/env-config.js +10 -0
  130. package/lib/config/env-config.js.map +1 -1
  131. package/lib/helpers/DynamicIcon.js.map +1 -1
  132. package/lib/hooks/useMediaQuery.js.map +1 -1
  133. package/lib/hooks/useScrollThreshold.js.map +1 -1
  134. package/lib/hooks/useTailwindTheme.js +82 -0
  135. package/lib/hooks/useTailwindTheme.js.map +1 -0
  136. package/lib/icons.d.ts +2 -0
  137. package/lib/icons.d.ts.map +1 -1
  138. package/lib/icons.js +4 -2
  139. package/lib/icons.js.map +1 -1
  140. package/lib/index.d.ts +1 -0
  141. package/lib/index.d.ts.map +1 -1
  142. package/lib/index.js +1 -1
  143. package/lib/index.js.map +1 -1
  144. package/lib/machines/selectors.d.ts +118 -0
  145. package/lib/machines/selectors.d.ts.map +1 -0
  146. package/lib/machines/settingsMachine.d.ts +25 -2
  147. package/lib/machines/settingsMachine.d.ts.map +1 -1
  148. package/lib/machines/settingsMachine.js +174 -163
  149. package/lib/machines/settingsMachine.js.map +1 -1
  150. package/lib/machines/settingsMachine.test.d.ts +2 -0
  151. package/lib/machines/settingsMachine.test.d.ts.map +1 -0
  152. package/lib/machines/types.d.ts +106 -9
  153. package/lib/machines/types.d.ts.map +1 -1
  154. package/lib/machines/types.js.map +1 -1
  155. package/lib/module.js.map +1 -1
  156. package/lib/redux/searchReducer.js.map +1 -1
  157. package/lib/routes.json +9 -1
  158. package/lib/tailwindConfig.js.map +1 -1
  159. package/lib/utils/__tests__/configOverrides.test.d.ts +2 -0
  160. package/lib/utils/__tests__/configOverrides.test.d.ts.map +1 -0
  161. package/lib/utils/configOverrides.d.ts +213 -0
  162. package/lib/utils/configOverrides.d.ts.map +1 -0
  163. package/lib/utils/configOverrides.js +91 -0
  164. package/lib/utils/configOverrides.js.map +1 -0
  165. package/lib/utils/isBrowser/index.js.map +1 -1
  166. package/lib/utils/settingsUtils.d.ts +20 -0
  167. package/lib/utils/settingsUtils.d.ts.map +1 -0
  168. package/lib/utils/settingsUtils.js +74 -0
  169. package/lib/utils/settingsUtils.js.map +1 -0
  170. package/lib/utils/utils/index.js.map +1 -1
  171. package/package.json +6 -6
  172. package/lib/components/Layout/GlobalHeader/Logo.d.ts +0 -4
  173. package/lib/components/Layout/GlobalHeader/Logo.d.ts.map +0 -1
  174. package/lib/components/Layout/GlobalHeader/Logo.js +0 -141
  175. package/lib/components/Layout/GlobalHeader/Logo.js.map +0 -1
  176. package/lib/components/Layout/Sidebar/Sidebar.d.ts +0 -5
  177. package/lib/components/Layout/Sidebar/Sidebar.d.ts.map +0 -1
  178. package/lib/components/Layout/Sidebar/Sidebar.js.map +0 -1
  179. package/lib/components/Layout/Sidebar/SidebarMenu.d.ts +0 -4
  180. package/lib/components/Layout/Sidebar/SidebarMenu.d.ts.map +0 -1
  181. package/lib/components/Layout/Sidebar/SidebarMenu.js +0 -176
  182. package/lib/components/Layout/Sidebar/SidebarMenu.js.map +0 -1
package/lib/icons.d.ts CHANGED
@@ -12,5 +12,7 @@ export declare const icons: {
12
12
  ChevronForwardCircleIcon: import("@react-icons/all-files/lib").IconType;
13
13
  ChevronUpIcon: import("@react-icons/all-files/lib").IconType;
14
14
  ChevronLeftIcon: import("@react-icons/all-files/lib").IconType;
15
+ PushpinLineIcon: import("@react-icons/all-files/lib").IconType;
16
+ PushpinFillIcon: import("@react-icons/all-files/lib").IconType;
15
17
  };
16
18
  //# sourceMappingURL=icons.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;CAcjB,CAAC"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;CAgBjB,CAAC"}
package/lib/icons.js CHANGED
@@ -1,4 +1,4 @@
1
- import {FaSearch}from'@react-icons/all-files/fa/FaSearch.js';import {IoMenu}from'@react-icons/all-files/io5/IoMenu.js';import'@react-icons/all-files/ai/AiOutlineDash.js';import {FaChevronDown}from'@react-icons/all-files/fa/FaChevronDown.js';import {FaChevronUp}from'@react-icons/all-files/fa/FaChevronUp.js';import {FaChevronRight}from'@react-icons/all-files/fa/FaChevronRight.js';import {FaChevronLeft}from'@react-icons/all-files/fa/FaChevronLeft.js';import {MdClose}from'@react-icons/all-files/md/MdClose.js';import {RiSettings5Fill}from'@react-icons/all-files/ri/RiSettings5Fill.js';import {IoMdCopy}from'@react-icons/all-files/io/IoMdCopy.js';import {FaCheck}from'@react-icons/all-files/fa/FaCheck.js';import'@react-icons/all-files/io5/IoChevronBackCircleOutline.js';import'@react-icons/all-files/io5/IoChevronForwardCircleOutline.js';const icons = {
1
+ import {FaSearch}from'@react-icons/all-files/fa/FaSearch.js';import {IoMenu}from'@react-icons/all-files/io5/IoMenu.js';import'@react-icons/all-files/ai/AiOutlineDash.js';import {FaChevronDown}from'@react-icons/all-files/fa/FaChevronDown.js';import {FaChevronUp}from'@react-icons/all-files/fa/FaChevronUp.js';import {FaChevronRight}from'@react-icons/all-files/fa/FaChevronRight.js';import {FaChevronLeft}from'@react-icons/all-files/fa/FaChevronLeft.js';import {MdClose}from'@react-icons/all-files/md/MdClose.js';import {RiSettings5Fill}from'@react-icons/all-files/ri/RiSettings5Fill.js';import {IoMdCopy}from'@react-icons/all-files/io/IoMdCopy.js';import {FaCheck}from'@react-icons/all-files/fa/FaCheck.js';import'@react-icons/all-files/io5/IoChevronBackCircleOutline.js';import'@react-icons/all-files/io5/IoChevronForwardCircleOutline.js';import {RiPushpinLine}from'@react-icons/all-files/ri/RiPushpinLine.js';import {RiPushpinFill}from'@react-icons/all-files/ri/RiPushpinFill.js';const icons = {
2
2
  SearchIcon: FaSearch,
3
3
  ChevronDownIcon: FaChevronDown,
4
4
  ChevronRightIcon: FaChevronRight,
@@ -8,5 +8,7 @@ import {FaSearch}from'@react-icons/all-files/fa/FaSearch.js';import {IoMenu}from
8
8
  CopyIcon: IoMdCopy,
9
9
  CheckIcon: FaCheck,
10
10
  ChevronUpIcon: FaChevronUp,
11
- ChevronLeftIcon: FaChevronLeft
11
+ ChevronLeftIcon: FaChevronLeft,
12
+ PushpinLineIcon: RiPushpinLine,
13
+ PushpinFillIcon: RiPushpinFill
12
14
  };export{icons};//# sourceMappingURL=icons.js.map
package/lib/icons.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"icons.js","sources":["../src/icons.ts"],"sourcesContent":[null],"names":[],"mappings":"u0BAca,MAAA,KAAK,GAAG;sBACP;gCACK;kCACC;kBACR;oBAEC;oCACQ;oBACT;oBACC;4BAGI;;"}
1
+ {"version":3,"file":"icons.js","sources":["../src/icons.ts"],"sourcesContent":[null],"names":[],"mappings":"q9BAgBO,MAAM,KAAK,GAAG;sBACjB;gCACA;kCACA;kBACA;oBAEA;oCACA;oBACA;oBACA;4BAGA;gCACA;gCACA;;"}
package/lib/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Feature } from '@common-stack/client-react';
2
2
  export * from './tailwindConfig';
3
3
  export * from './redux';
4
+ export * from './hooks';
4
5
  declare const _default: Feature;
5
6
  export default _default;
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC;;AAExB,wBAAqC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;;AAExB,wBAAqC"}
package/lib/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import {Feature}from'@common-stack/client-react';import settings from'./module.js';export{themeConfig}from'./tailwindConfig.js';export{SEARCH_ACTIONS,clearSearch,searchReducer,setSearchError,setSearchQuery,setSearchResult}from'./redux/searchReducer.js';// eslint-disable-next-line import/no-extraneous-dependencies
1
+ import {Feature}from'@common-stack/client-react';import settings from'./module.js';export{themeConfig}from'./tailwindConfig.js';export{SEARCH_ACTIONS,clearSearch,searchReducer,setSearchError,setSearchQuery,setSearchResult}from'./redux/searchReducer.js';export{useTailwindTheme}from'./hooks/useTailwindTheme.js';export{useMediaQuery}from'./hooks/useMediaQuery.js';// eslint-disable-next-line import/no-extraneous-dependencies
2
2
  var index = new Feature(settings);export{index as default};//# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":[null],"names":[],"mappings":"6PAAA;AAMA,YAAe,IAAI,OAAO,CAAC,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":[null],"names":[],"mappings":"2WAAA;AAOA,YAAe,IAAI,OAAO,CAAC,QAAQ,CAAC"}
@@ -0,0 +1,118 @@
1
+ import { UISettings } from './types';
2
+ /**
3
+ * XSTATE SELECTORS
4
+ *
5
+ * These selector functions provide STABLE references to state values,
6
+ * preventing unnecessary re-renders and eliminating infinite loop possibilities.
7
+ *
8
+ * IMPORTANT RULES:
9
+ * 1. Components should ONLY use these selectors to access state
10
+ * 2. NEVER access state.context directly
11
+ * 3. Selectors only return PUBLIC settings - internal state is never exposed
12
+ * 4. XState's useSelector hook memoizes these, ensuring stable references
13
+ *
14
+ * WHY THIS WORKS:
15
+ * - Even if context.internal.configModel changes (new reference),
16
+ * context.public remains stable (same values = same reference after JSON comparison)
17
+ * - useSelector only triggers re-render if the RETURNED value changes
18
+ * - No manual filtering needed - separation is built into the structure
19
+ */
20
+ /**
21
+ * Select all UI settings (excludes internal machine state)
22
+ *
23
+ * This is the primary selector for getting user-facing settings.
24
+ * XState's useSelector will automatically memoize this, so it only
25
+ * re-renders when the UI settings actually change.
26
+ *
27
+ * @example
28
+ * const settings = useSelector(actor, selectPublicSettings);
29
+ */
30
+ export declare const selectPublicSettings: (state: any) => UISettings;
31
+ /**
32
+ * Select only changed settings (for save button state).
33
+ * Use this to check if there are unsaved changes.
34
+ *
35
+ * @example
36
+ * const changedSettings = useSelector(actor, selectChangedSettings);
37
+ * const hasChanges = Object.keys(changedSettings).length > 0;
38
+ */
39
+ export declare const selectChangedSettings: (state: any) => Record<string, any>;
40
+ /**
41
+ * Select current device type (desktop/mobile).
42
+ * Use this to check which device mode is active.
43
+ *
44
+ * @example
45
+ * const deviceType = useSelector(actor, selectDeviceType);
46
+ */
47
+ export declare const selectDeviceType: (state: any) => "desktop" | "mobile";
48
+ /**
49
+ * Select current route path.
50
+ * Use this to check which route is active.
51
+ *
52
+ * @example
53
+ * const currentRoute = useSelector(actor, selectCurrentRoute);
54
+ */
55
+ export declare const selectCurrentRoute: (state: any) => string;
56
+ /**
57
+ * Select a specific setting by key.
58
+ * Returns a selector function that extracts a specific setting value.
59
+ *
60
+ * @example
61
+ * const navTheme = useSelector(actor, selectSetting('navTheme'));
62
+ * const primaryColor = useSelector(actor, selectSetting('primaryColor'));
63
+ */
64
+ export declare const selectSetting: (key: keyof UISettings) => (state: any) => any;
65
+ /**
66
+ * Select navigation theme specifically.
67
+ * Commonly used setting, provided as convenience.
68
+ *
69
+ * @example
70
+ * const navTheme = useSelector(actor, selectNavTheme);
71
+ */
72
+ export declare const selectNavTheme: (state: any) => "light" | "dark" | "realDark";
73
+ /**
74
+ * Select primary color specifically.
75
+ * Commonly used setting, provided as convenience.
76
+ *
77
+ * @example
78
+ * const primaryColor = useSelector(actor, selectPrimaryColor);
79
+ */
80
+ export declare const selectPrimaryColor: (state: any) => string;
81
+ /**
82
+ * Select whether settings panel should be shown.
83
+ * Use this to control settings drawer visibility.
84
+ *
85
+ * @example
86
+ * const showSettingPanel = useSelector(actor, selectShowSettingPanel);
87
+ */
88
+ export declare const selectShowSettingPanel: (state: any) => boolean;
89
+ /**
90
+ * Select menu visibility settings.
91
+ * Returns both hiddenMenuKeys and hiddenMenuCategories.
92
+ *
93
+ * @example
94
+ * const { hiddenMenuKeys, hiddenMenuCategories } = useSelector(actor, selectMenuVisibility);
95
+ */
96
+ export declare const selectMenuVisibility: (state: any) => {
97
+ hiddenMenuKeys: string[];
98
+ hiddenMenuCategories: string[];
99
+ };
100
+ /**
101
+ * Check if there are unsaved changes.
102
+ * Use this for save button disabled state.
103
+ *
104
+ * @example
105
+ * const hasUnsavedChanges = useSelector(actor, selectHasUnsavedChanges);
106
+ */
107
+ export declare const selectHasUnsavedChanges: (state: any) => boolean;
108
+ /**
109
+ * COMPARISON HELPER
110
+ *
111
+ * Use this to compare settings between renders without triggering infinite loops.
112
+ * This performs a deep comparison of UI settings only.
113
+ *
114
+ * @example
115
+ * const settingsChanged = !areUISettingsEqual(prevSettings, currentSettings);
116
+ */
117
+ export declare const areUISettingsEqual: (a: UISettings, b: UISettings) => boolean;
118
+ //# sourceMappingURL=selectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../src/machines/selectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,UAAU,EAAwB,MAAM,SAAS,CAAC;AAE5E;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,GAAG,KAAG,UAGjD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,GAAG,KAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAGpE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,GAAG,KAAG,SAAS,GAAG,QAGzD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,GAAG,KAAG,MAG/C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACrB,KAAK,MAAM,UAAU,MACrB,OAAO,GAAG,KAAG,GAGb,CAAC;AAEN;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,GAAG,KAAG,OAAO,GAAG,MAAM,GAAG,UAG9D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,GAAG,KAAG,MAG/C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,GAAG,KAAG,OAGnD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC7B,OAAO,GAAG,KACX;IACC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAOlC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAAI,OAAO,GAAG,KAAG,OAGpD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,GAAG,UAAU,EAAE,GAAG,UAAU,KAAG,OASjE,CAAC"}
@@ -1,6 +1,29 @@
1
1
  import { MachineEvent, SettingsContext } from './types';
2
+ /**
3
+ * SETTINGS MACHINE - COMPLETELY REFACTORED
4
+ *
5
+ * DESIGN PHILOSOPHY:
6
+ * This machine has been completely rewritten to eliminate any possibility of infinite loops
7
+ * by enforcing a strict separation between:
8
+ * 1. PUBLIC STATE: User-facing settings (stable, exposed to consumers)
9
+ * 2. INTERNAL STATE: Machine logic state (may have reference changes, never exposed)
10
+ *
11
+ * ARCHITECTURE:
12
+ * - Context is split into `public` and `internal` namespaces
13
+ * - Components ONLY access `context.public` via selectors
14
+ * - NO filtering is needed - separation is built into the structure
15
+ * - ConfigurationModel reference changes are isolated to `context.internal`
16
+ * - Redux receives ONLY `context.public` - no manual filtering required
17
+ *
18
+ * WHY THIS WORKS:
19
+ * - Reference changes in `context.internal.configModel` don't affect `context.public`
20
+ * - Components using selectors get stable references to `context.public`
21
+ * - No manual filtering means no chance of accidentally exposing internal state
22
+ * - Type system enforces the separation at compile time
23
+ */
2
24
  export declare const settingsMachine: import("xstate").StateMachine<SettingsContext, MachineEvent, Record<string, import("xstate").AnyActorRef>, import("xstate").ProvidedActor, import("xstate").ParameterizedObject, import("xstate").ParameterizedObject, string, import("xstate").StateValue, string, {
3
- settings: SettingsContext;
4
- routeSettings?: Record<string, Partial<SettingsContext>>;
25
+ settings: any;
26
+ currentRoute?: string;
27
+ routePattern?: string;
5
28
  }, {}, import("xstate").EventObject, import("xstate").MetaObject, any>;
6
29
  //# sourceMappingURL=settingsMachine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"settingsMachine.d.ts","sourceRoot":"","sources":["../../src/machines/settingsMachine.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,YAAY,EACZ,eAAe,EAMlB,MAAM,SAAS,CAAC;AAyFjB,eAAO,MAAM,eAAe;cAMN,eAAe;oBACT,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;sEAsIlE,CAAC"}
1
+ {"version":3,"file":"settingsMachine.d.ts","sourceRoot":"","sources":["../../src/machines/settingsMachine.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAoC,MAAM,SAAS,CAAC;AAE1F;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,eAAO,MAAM,eAAe;cAMN,GAAG;mBACE,MAAM;mBACN,MAAM;sEAkO/B,CAAC"}
@@ -1,85 +1,25 @@
1
- import {defaultSettings}from'@admin-layout/client';import {createMachine,assign}from'xstate';import {SearchBarBehavior}from'./types.js';import {cloneDeep,set,merge}from'lodash-es';// Default route settings template
2
- const DEFAULT_LAYOUT = {
3
- navigationMode: 'mixed',
4
- sideMenuType: 'expanded',
5
- contentWidth: 'fluid',
6
- fixedHeader: true,
7
- fixedSidebar: true,
8
- splitMenus: false,
9
- upperMenuDividerName: 'Navigation',
10
- middleMenuDividerName: 'Dashboard',
11
- lowerMenuDividerName: 'Admin'
12
- };
13
- // Default background settings
14
- const DEFAULT_BACKGROUND = {
15
- type: 'color',
16
- color: 'inherit',
17
- image: '',
18
- video: '',
19
- videoThumbnail: ''
20
- };
21
- const DEFAULT_HEADER = {
22
- showLogo: true,
23
- showSearchSlot: true,
24
- showRightContent: true,
25
- showMenuToggle: true,
26
- showBackButton: true,
27
- showPageTitle: true,
28
- showActionButtons: true,
29
- position: 'fixed',
30
- height: '64px',
31
- elevation: 2,
32
- showHeader: true,
33
- showMenu: true,
34
- menuHeaderRender: true,
35
- searchBarRender: true,
36
- searchBarBehavior: SearchBarBehavior.PERMANENT,
37
- searchBarOverlay: true,
38
- scrollThreshold: 50
39
- };
40
- // Shared view configuration similar to client's defaultSettings
41
- const SHARED_VIEW_CONFIG = {
42
- layout: DEFAULT_LAYOUT,
43
- regions: {
44
- header: DEFAULT_HEADER,
45
- footer: {
46
- showFooter: true
47
- },
48
- background: DEFAULT_BACKGROUND
49
- }
50
- };
51
- const defaultRouteSettings = {
52
- layout: {
53
- desktop: SHARED_VIEW_CONFIG.layout,
54
- mobile: SHARED_VIEW_CONFIG.layout
55
- },
56
- regions: {
57
- desktop: {
58
- header: SHARED_VIEW_CONFIG.regions.header,
59
- footer: SHARED_VIEW_CONFIG.regions.footer,
60
- background: SHARED_VIEW_CONFIG.regions.background
61
- },
62
- mobile: {
63
- header: SHARED_VIEW_CONFIG.regions.header,
64
- footer: SHARED_VIEW_CONFIG.regions.footer,
65
- background: SHARED_VIEW_CONFIG.regions.background
66
- }
67
- }
68
- };
69
- // Helper function to deep merge objects
70
- const deepMerge = (target, source) => {
71
- const result = {
72
- ...target
73
- };
74
- for (const key in source) {
75
- if (source[key] instanceof Object && key in target) {
76
- result[key] = deepMerge(target[key], source[key]);
77
- } else {
78
- result[key] = source[key];
79
- }
80
- }
81
- return result;
82
- };
1
+ import {cloneDeep,set}from'lodash-es';import {createMachine,assign}from'xstate';import {extractConfigurationWithModel}from'@adminide-stack/core';/**
2
+ * SETTINGS MACHINE - COMPLETELY REFACTORED
3
+ *
4
+ * DESIGN PHILOSOPHY:
5
+ * This machine has been completely rewritten to eliminate any possibility of infinite loops
6
+ * by enforcing a strict separation between:
7
+ * 1. PUBLIC STATE: User-facing settings (stable, exposed to consumers)
8
+ * 2. INTERNAL STATE: Machine logic state (may have reference changes, never exposed)
9
+ *
10
+ * ARCHITECTURE:
11
+ * - Context is split into `public` and `internal` namespaces
12
+ * - Components ONLY access `context.public` via selectors
13
+ * - NO filtering is needed - separation is built into the structure
14
+ * - ConfigurationModel reference changes are isolated to `context.internal`
15
+ * - Redux receives ONLY `context.public` - no manual filtering required
16
+ *
17
+ * WHY THIS WORKS:
18
+ * - Reference changes in `context.internal.configModel` don't affect `context.public`
19
+ * - Components using selectors get stable references to `context.public`
20
+ * - No manual filtering means no chance of accidentally exposing internal state
21
+ * - Type system enforces the separation at compile time
22
+ */
83
23
  const settingsMachine = createMachine({
84
24
  id: 'settings',
85
25
  types: {},
@@ -87,115 +27,186 @@ const settingsMachine = createMachine({
87
27
  context: ({
88
28
  input
89
29
  }) => {
90
- return merge({}, {
91
- navTheme: defaultSettings.navTheme || 'light',
92
- primaryColor: defaultSettings.primaryColor || '#1890ff',
93
- secondaryColor: defaultSettings.secondaryColor || '#1890ff',
94
- theme: defaultSettings.theme || 'default',
95
- logo: defaultSettings.logo,
96
- title: defaultSettings.title,
97
- showSettingPanel: defaultSettings.showSettingPanel,
98
- titleColor: defaultSettings.titleColor,
99
- language: defaultSettings.language,
100
- fontFamily: defaultSettings.fontFamily,
101
- titleFontWeight: defaultSettings.titleFontWeight,
102
- titleHeight: defaultSettings.titleHeight,
103
- titleFontSize: defaultSettings.titleFontSize,
104
- letterSpacings: defaultSettings.letterSpacings,
105
- siderBgColor: defaultSettings.siderBgColor,
106
- headerBgColor: defaultSettings.headerBgColor,
107
- textColor: defaultSettings.textColor,
108
- themeType: defaultSettings.themeType,
109
- loginThemeColor: defaultSettings.loginThemeColor,
110
- loginFormPosition: defaultSettings.loginFormPosition,
111
- loginSocials: defaultSettings.loginSocials,
112
- loginBackgroundImage: defaultSettings.loginBackgroundImage,
113
- verifyFormLayout: defaultSettings.verifyFormLayout,
114
- verifyFormImageUrl: defaultSettings.verifyFormImageUrl,
115
- verifyFormBackgroundStyle: defaultSettings.verifyFormBackgroundStyle,
116
- verifyFormVisibleFields: defaultSettings.verifyFormVisibleFields,
117
- verifyFormShowSkipButton: defaultSettings.verifyFormShowSkipButton,
118
- components: [],
119
- activeComponent: null,
120
- currentRoute: input?.settings?.currentRoute || '/',
121
- routeSettings: {
122
- '/': defaultRouteSettings
123
- }
124
- }, input?.settings);
30
+ // Input settings are now flat: { logo: '...', theme: '...', [/route][device]: {...}, ... }
31
+ const rawSettings = input?.settings || {};
32
+ console.log('🔍 Context Init - Raw settings:', {
33
+ hasRawSettings: !!rawSettings,
34
+ rawSettingsKeys: `${Object.keys(rawSettings).length} keys`
35
+ });
36
+ // ConfigurationModel handles ALL bracket patterns automatically
37
+ const {
38
+ model: configModel
39
+ } = extractConfigurationWithModel(rawSettings);
40
+ // Get current route from input (passed from component) or default to '/'
41
+ const currentRoute = input?.currentRoute || '/';
42
+ const routePattern = input?.routePattern;
43
+ const deviceType = 'desktop'; // Default, will be updated by component
44
+ // Build override keys with fallback logic - use route pattern if available
45
+ const routeForBracket = routePattern || currentRoute;
46
+ const routeDeviceKey = [routeForBracket, deviceType];
47
+ // Apply overrides by chaining: base -> device -> route+device
48
+ const routeOverride = configModel.override(routeDeviceKey, {
49
+ strict: true
50
+ });
51
+ // Extract final merged settings (already flat, no uilayout wrapper)
52
+ const mergedContents = routeOverride.getValue('');
53
+ const effectiveSettings = mergedContents;
54
+ // Build PUBLIC settings (exposed to consumers)
55
+ // Build the UI settings object from all potential sources
56
+ const publicSettings = effectiveSettings;
57
+ // Build INTERNAL state (machine only, never exposed)
58
+ const internalState = {
59
+ configModel,
60
+ deviceType,
61
+ currentRoute,
62
+ changedSettings: {},
63
+ routePattern: input?.routePattern
64
+ };
65
+ // Return context with EXPLICIT separation
66
+ const context = {
67
+ public: publicSettings,
68
+ internal: internalState
69
+ };
70
+ console.log('🔍 Context Init - Final structure:', {
71
+ hasPublic: !!context.public,
72
+ hasInternal: !!context.internal,
73
+ publicKeys: `${Object.keys(context.public).length} keys`,
74
+ internalKeys: Object.keys(context.internal)
75
+ });
76
+ return context;
125
77
  },
126
78
  states: {
127
79
  idle: {
80
+ entry: ['updateReduxSettings'],
128
81
  on: {
129
- UPDATE: {
82
+ UISETTING_UPDATE: {
130
83
  actions: [assign(({
131
84
  context,
132
85
  event
133
86
  }) => {
134
87
  if (!event.value) return context;
135
- const newContext = cloneDeep({
136
- ...context
137
- });
138
- // Handle top-level updates
139
- if (event.value.navTheme !== undefined) {
140
- newContext.navTheme = event.value.navTheme;
141
- }
142
- if (event.value.primaryColor !== undefined) {
143
- newContext.primaryColor = event.value.primaryColor;
144
- }
145
- if (event.value.theme !== undefined) {
146
- newContext.theme = event.value.theme;
147
- }
148
- // Add any new keys from event.value that don't exist in context
88
+ console.log('🔧 Machine UPDATE event:', event);
89
+ // Clone context to avoid mutations
90
+ const newContext = cloneDeep(context);
91
+ // Process each changed setting
149
92
  Object.keys(event.value).forEach(key => {
150
- set(newContext, key, event.value[key]);
93
+ const newValue = event.value[key];
94
+ console.log('🔧 Processing key:', key, 'value:', newValue);
95
+ // Update ConfigurationModel
96
+ newContext.internal.configModel.setValue(key, newValue);
97
+ // Track in changedSettings
98
+ newContext.internal.changedSettings[key] = newValue;
99
+ // If it's a bracket key, check if it applies to current context
100
+ if (key.startsWith('[')) {
101
+ const bracketPattern = key.match(/^(\[[^\]]+\])+/);
102
+ if (bracketPattern) {
103
+ const identifier = bracketPattern[0];
104
+ // Use route pattern if available, otherwise fall back to current route
105
+ const routeForBracket = newContext.internal.routePattern || newContext.internal.currentRoute;
106
+ const currentIdentifier = `[${routeForBracket}][${newContext.internal.deviceType}]`;
107
+ const deviceOnlyIdentifier = `[${newContext.internal.deviceType}]`;
108
+ // If this override applies to current route/device, update public settings
109
+ if (identifier === currentIdentifier || identifier === deviceOnlyIdentifier) {
110
+ const remainingKey = key.substring(identifier.length);
111
+ const path = remainingKey.startsWith('.') ? remainingKey.substring(1) : remainingKey;
112
+ set(newContext.public, path, newValue);
113
+ set(newContext.public, 'routerPattern', currentIdentifier);
114
+ }
115
+ }
116
+ } else {
117
+ // Regular setting - update public settings directly
118
+ set(newContext.public, key, newValue);
119
+ }
151
120
  });
152
121
  return newContext;
153
122
  }), 'updateReduxSettings']
154
123
  },
155
- ROUTE_CHANGE: {
124
+ UISETTING_ROUTE_CHANGE: {
156
125
  actions: [assign(({
157
126
  context,
158
127
  event
159
128
  }) => {
160
- const newContext = cloneDeep({
161
- ...context
162
- });
163
129
  const routePath = event.pathname || '/';
164
- // Update current route
165
- newContext.currentRoute = routePath;
166
- // Get the route's saved settings from history or use default
167
- const routeSettings = context.routeSettings[routePath];
168
- // Initialize route settings if it doesn't exist
169
- if (!newContext.routeSettings[routePath]) {
170
- newContext.routeSettings[routePath] = cloneDeep({
171
- ...defaultRouteSettings
172
- });
173
- return newContext;
130
+ const routePattern = event.routePattern;
131
+ console.log('🔧 ROUTE_CHANGE to:', routePath, 'pattern:', routePattern);
132
+ // Clone context to avoid mutations
133
+ const newContext = cloneDeep(context);
134
+ // Update internal route and route pattern
135
+ newContext.internal.currentRoute = routePath;
136
+ if (routePattern) {
137
+ newContext.internal.routePattern = routePattern;
174
138
  }
175
- newContext.routeSettings[routePath] = cloneDeep(routeSettings);
139
+ // Build override keys using route pattern if available
140
+ const routeForBracket = routePattern || routePath;
141
+ const routeDeviceKey = [routeForBracket, context.internal.deviceType];
142
+ // Apply overrides by chaining: base -> device -> route+device
143
+ const deviceOverride = context.internal.configModel.override(routeDeviceKey, {
144
+ strict: true
145
+ });
146
+ // Extract final merged settings
147
+ const effectiveSettings = deviceOverride.getValue('');
148
+ // Rebuild PUBLIC settings from scratch (no leakage from old route)
149
+ newContext.public = effectiveSettings;
176
150
  return newContext;
177
- }), 'updateReduxSettings']
151
+ })
152
+ // 'updateReduxSettings',
153
+ ]
178
154
  },
179
- UPDATE_ROUTE_SETTINGS: {
155
+ UISETTING_UPDATE_ROUTE_SETTINGS: {
180
156
  actions: [assign(({
181
157
  context,
182
158
  event
183
159
  }) => ({
184
- ...context,
185
- routeSettings: deepMerge(context.routeSettings, event.settings)
160
+ ...context
161
+ // Route settings are now handled via uiSettings overrides
186
162
  })), 'updateReduxSettings']
187
163
  },
188
- RESET: {
189
- actions: [assign(() => ({
190
- navTheme: defaultSettings.navTheme || 'light',
191
- primaryColor: defaultSettings.primaryColor || '#1890ff',
192
- theme: 'default',
193
- components: [],
194
- activeComponent: null,
195
- routeSettings: {
196
- '/': defaultRouteSettings
197
- }
198
- })), 'updateReduxSettings']
164
+ UISETTING_RESET: {
165
+ actions: [assign(({
166
+ context
167
+ }) => {
168
+ const newContext = cloneDeep(context);
169
+ // Reset public state
170
+ newContext.public.components = [];
171
+ newContext.public.activeComponent = undefined;
172
+ // Reset internal tracking
173
+ newContext.internal.changedSettings = {};
174
+ return newContext;
175
+ }), 'updateReduxSettings']
176
+ },
177
+ UISETTING_RESET_CHANGED_SETTINGS: {
178
+ actions: [assign(({
179
+ context
180
+ }) => {
181
+ const newContext = cloneDeep(context);
182
+ newContext.internal.changedSettings = {};
183
+ return newContext;
184
+ })]
185
+ },
186
+ UISETTING_UPDATE_DEVICE_TYPE: {
187
+ actions: [assign(({
188
+ context,
189
+ event
190
+ }) => {
191
+ const deviceType = event.deviceType || 'desktop';
192
+ console.log('🔧 UPDATE_DEVICE_TYPE to:', deviceType);
193
+ // Clone context to avoid mutations
194
+ const newContext = cloneDeep(context);
195
+ // Update internal device type
196
+ newContext.internal.deviceType = deviceType;
197
+ // Build override keys using route pattern if available
198
+ const routeForBracket = context.internal.routePattern || context.internal.currentRoute;
199
+ const routeDeviceKey = [routeForBracket, deviceType];
200
+ // Apply overrides by chaining: base -> device -> route+device
201
+ const routeOverride = context.internal.configModel.override(routeDeviceKey, {
202
+ strict: true
203
+ });
204
+ // Extract final merged settings
205
+ const effectiveSettings = routeOverride.getValue('');
206
+ // Rebuild PUBLIC settings with new device overrides
207
+ newContext.public = effectiveSettings;
208
+ return newContext;
209
+ }), 'updateReduxSettings']
199
210
  }
200
211
  // SAVE: {
201
212
  // actions: ['updateReduxSettings'],