nfx-ui 0.6.2 → 0.7.1

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 (116) hide show
  1. package/dist/animations.cjs +2 -2
  2. package/dist/animations.d.ts +0 -101
  3. package/dist/animations.mjs +9 -11
  4. package/dist/apis.cjs +2 -2
  5. package/dist/apis.cjs.map +1 -1
  6. package/dist/apis.d.ts +0 -6
  7. package/dist/apis.mjs +8 -9
  8. package/dist/apis.mjs.map +1 -1
  9. package/dist/{chunk-BounceLoading-B54QEw0n.mjs → chunk-BounceLoading-C5XE8DKc.mjs} +62 -65
  10. package/dist/{chunk-BounceLoading-B54QEw0n.mjs.map → chunk-BounceLoading-C5XE8DKc.mjs.map} +1 -1
  11. package/dist/chunk-BounceLoading-CwvDT5HF.cjs +11 -0
  12. package/dist/{chunk-BounceLoading-C6n4BZVJ.cjs.map → chunk-BounceLoading-CwvDT5HF.cjs.map} +1 -1
  13. package/dist/chunk-animations-CEZ01ALd.mjs +740 -0
  14. package/dist/chunk-animations-CEZ01ALd.mjs.map +1 -0
  15. package/dist/chunk-animations-CO7zKbti.cjs +3 -0
  16. package/dist/chunk-animations-CO7zKbti.cjs.map +1 -0
  17. package/dist/chunk-i18n-BCDF-skF.cjs +3 -0
  18. package/dist/{chunk-i18n-daHSL0Nm.cjs.map → chunk-i18n-BCDF-skF.cjs.map} +1 -1
  19. package/dist/{chunk-i18n-BBPhh6MT.mjs → chunk-i18n-BsyWvA9c.mjs} +44 -69
  20. package/dist/{chunk-i18n-BBPhh6MT.mjs.map → chunk-i18n-BsyWvA9c.mjs.map} +1 -1
  21. package/dist/{chunk-types-SD4MzUGp.mjs → chunk-language-B8sfGadQ.mjs} +2 -2
  22. package/dist/chunk-language-B8sfGadQ.mjs.map +1 -0
  23. package/dist/{chunk-types-BE3JCLff.cjs → chunk-language-Bqmpuf2W.cjs} +1 -1
  24. package/dist/chunk-language-Bqmpuf2W.cjs.map +1 -0
  25. package/dist/{chunk-types-DNPBKfmx.mjs → chunk-layout-C2uqDEMJ.mjs} +2 -2
  26. package/dist/chunk-layout-C2uqDEMJ.mjs.map +1 -0
  27. package/dist/{chunk-types-C_opkZGr.cjs → chunk-layout-D728gccQ.cjs} +1 -1
  28. package/dist/chunk-layout-D728gccQ.cjs.map +1 -0
  29. package/dist/{chunk-lucide-BhgnmTNo.mjs → chunk-lucide-C54WenI6.mjs} +2 -2
  30. package/dist/{chunk-lucide-BhgnmTNo.mjs.map → chunk-lucide-C54WenI6.mjs.map} +1 -1
  31. package/dist/chunk-preference-BWEpbZgC.mjs +50 -0
  32. package/dist/{chunk-preference-By58ZcJ_.mjs.map → chunk-preference-BWEpbZgC.mjs.map} +1 -1
  33. package/dist/chunk-preference-Dbugm0iQ.cjs +3 -0
  34. package/dist/{chunk-preference-C144GkCD.cjs.map → chunk-preference-Dbugm0iQ.cjs.map} +1 -1
  35. package/dist/chunk-theme-9dcwRKw8.mjs +17 -0
  36. package/dist/chunk-theme-9dcwRKw8.mjs.map +1 -0
  37. package/dist/chunk-theme-BFvDRCYS.cjs +3 -0
  38. package/dist/chunk-theme-BFvDRCYS.cjs.map +1 -0
  39. package/dist/components.cjs +3 -3
  40. package/dist/components.cjs.map +1 -1
  41. package/dist/components.d.ts +0 -412
  42. package/dist/components.mjs +628 -642
  43. package/dist/components.mjs.map +1 -1
  44. package/dist/constants.cjs +1 -1
  45. package/dist/constants.d.ts +0 -129
  46. package/dist/constants.mjs +1 -1
  47. package/dist/events.cjs +1 -1
  48. package/dist/events.d.ts +0 -60
  49. package/dist/events.mjs +1 -1
  50. package/dist/hooks.cjs +1 -1
  51. package/dist/hooks.d.ts +0 -315
  52. package/dist/hooks.mjs +1 -1
  53. package/dist/icons.cjs +2 -2
  54. package/dist/icons.d.ts +0 -217
  55. package/dist/icons.mjs +2 -2
  56. package/dist/languages.cjs +2 -2
  57. package/dist/languages.cjs.map +1 -1
  58. package/dist/languages.d.ts +0 -178
  59. package/dist/languages.mjs +4 -4
  60. package/dist/languages.mjs.map +1 -1
  61. package/dist/layouts.cjs +2 -2
  62. package/dist/layouts.cjs.map +1 -1
  63. package/dist/layouts.d.ts +0 -208
  64. package/dist/layouts.mjs +201 -210
  65. package/dist/layouts.mjs.map +1 -1
  66. package/dist/navigations.cjs +1 -1
  67. package/dist/navigations.d.ts +0 -71
  68. package/dist/navigations.mjs +1 -1
  69. package/dist/pixel-blast.cjs +192 -0
  70. package/dist/pixel-blast.cjs.map +1 -0
  71. package/dist/pixel-blast.d.ts +1 -0
  72. package/dist/pixel-blast.mjs +506 -0
  73. package/dist/pixel-blast.mjs.map +1 -0
  74. package/dist/preference.cjs +2 -2
  75. package/dist/preference.d.ts +0 -95
  76. package/dist/preference.mjs +8 -11
  77. package/dist/services.cjs +2 -2
  78. package/dist/services.cjs.map +1 -1
  79. package/dist/services.d.ts +0 -7
  80. package/dist/services.mjs +9 -10
  81. package/dist/services.mjs.map +1 -1
  82. package/dist/stores.cjs +2 -2
  83. package/dist/stores.cjs.map +1 -1
  84. package/dist/stores.d.ts +1 -101
  85. package/dist/stores.mjs +53 -53
  86. package/dist/stores.mjs.map +1 -1
  87. package/dist/themes.cjs +2 -2
  88. package/dist/themes.cjs.map +1 -1
  89. package/dist/themes.d.ts +0 -232
  90. package/dist/themes.mjs +888 -721
  91. package/dist/themes.mjs.map +1 -1
  92. package/dist/types.cjs +1 -1
  93. package/dist/types.d.ts +0 -180
  94. package/dist/types.mjs +1 -1
  95. package/dist/utils.cjs +2 -2
  96. package/dist/utils.cjs.map +1 -1
  97. package/dist/utils.d.ts +0 -485
  98. package/dist/utils.mjs +143 -156
  99. package/dist/utils.mjs.map +1 -1
  100. package/package.json +45 -29
  101. package/dist/chunk-BounceLoading-C6n4BZVJ.cjs +0 -11
  102. package/dist/chunk-animations-Brp-bsaE.mjs +0 -1243
  103. package/dist/chunk-animations-Brp-bsaE.mjs.map +0 -1
  104. package/dist/chunk-animations-e2F3zuP9.cjs +0 -190
  105. package/dist/chunk-animations-e2F3zuP9.cjs.map +0 -1
  106. package/dist/chunk-i18n-daHSL0Nm.cjs +0 -3
  107. package/dist/chunk-preference-By58ZcJ_.mjs +0 -51
  108. package/dist/chunk-preference-C144GkCD.cjs +0 -3
  109. package/dist/chunk-types-BE3JCLff.cjs.map +0 -1
  110. package/dist/chunk-types-BNUlgEkq.cjs +0 -3
  111. package/dist/chunk-types-BNUlgEkq.cjs.map +0 -1
  112. package/dist/chunk-types-BudGuDCK.mjs +0 -20
  113. package/dist/chunk-types-BudGuDCK.mjs.map +0 -1
  114. package/dist/chunk-types-C_opkZGr.cjs.map +0 -1
  115. package/dist/chunk-types-DNPBKfmx.mjs.map +0 -1
  116. package/dist/chunk-types-SD4MzUGp.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"layouts.cjs","names":[],"sources":["../src/designs/layouts/utils/layoutStorage.ts","../src/designs/layouts/components/Sidebar/styles.module.css","../src/designs/layouts/components/Sidebar/index.tsx","../src/designs/layouts/components/Footer/styles.module.css","../src/designs/layouts/components/Footer/index.tsx","../src/designs/layouts/components/Header/styles.module.css","../src/designs/layouts/components/Header/index.tsx","../src/designs/layouts/components/MainWrapper/styles.module.css","../src/designs/layouts/components/MainWrapper/index.tsx","../src/designs/layouts/components/SideHideLayout/styles.module.css","../src/designs/layouts/components/SideHideLayout/index.tsx","../src/designs/layouts/components/SideShowLayout/styles.module.css","../src/designs/layouts/components/SideShowLayout/index.tsx","../src/designs/layouts/components/Background/styles.module.css","../src/designs/layouts/components/Background/index.tsx","../src/designs/layouts/components/LayoutFrame/index.tsx","../src/designs/layouts/hooks/useSet.ts","../src/designs/layouts/hooks/useAction.ts","../src/designs/layouts/providers/index.tsx"],"sourcesContent":["/**\n * 布局相关 localStorage 读写与移除,统一走 utils/lstorage。\n * Layout localStorage get/set/remove via utils/lstorage.\n */\nimport type { Nilable } from \"@/types/utils\";\nimport { getItem, removeItem, setItem } from \"@/utils/lstorage\";\n\nimport { LAYOUT_STORAGE_KEY } from \"../types\";\n\nexport function getLayoutStorage(): Nilable<string> {\n return getItem(LAYOUT_STORAGE_KEY);\n}\n\nexport function setLayoutStorage(value: string): void {\n setItem(LAYOUT_STORAGE_KEY, value);\n}\n\nexport function removeLayoutStorage(): void {\n removeItem(LAYOUT_STORAGE_KEY);\n}\n","/* ===== Sidebar Component ===== */\r\n\r\n.sidebar {\r\n height: 100%;\r\n min-height: 0;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n}\r\n\r\n.sidebarContent {\r\n padding-top: 1rem;\r\n height: 100%;\r\n min-height: 0;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n}\r\n\r\n.menuWrapper {\r\n flex: 1;\r\n min-height: 0;\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n}\r\n\r\n/* 自定义滚动条样式 - 隐藏但保持滚动功能 */\r\n.sidebarContent::-webkit-scrollbar {\r\n width: 0px;\r\n}\r\n\r\n.sidebarContent::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.sidebarContent::-webkit-scrollbar-thumb {\r\n background: transparent;\r\n}\r\n\r\n.sidebarContent::-webkit-scrollbar-thumb:hover {\r\n background: transparent;\r\n}\r\n\r\n/* 内部 a 元素左边距为 0 */\r\n.sidebar :global(a) {\r\n margin-left: 0;\r\n}\r\n\r\n/* 覆盖 react-pro-sidebar 默认样式 */\r\n.sidebar :global(.ps-sidebar-root) {\r\n height: 100% !important;\r\n min-height: 0 !important;\r\n overflow: hidden !important;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n background-color: var(--color-bg-2) !important;\r\n border-right: 1px solid var(--color-separator) !important;\r\n}\r\n\r\n.sidebar :global(.ps-sidebar-container) {\r\n height: 100% !important;\r\n min-height: 0 !important;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n flex: 1 !important;\r\n overflow: hidden !important;\r\n background-color: var(--color-bg-2) !important;\r\n color: var(--color-fg-text) !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button) {\r\n padding: 0.5rem 0.75rem !important;\r\n margin: 0.125rem 0.5rem !important;\r\n border-radius: 0.375rem !important;\r\n transition: all 0.2s ease !important;\r\n color: var(--color-fg-text) !important;\r\n font-size: 0.875rem !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button:hover) {\r\n background-color: var(--color-bg-3) !important;\r\n color: var(--color-fg-text) !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button.ps-active) {\r\n background-color: var(--color-primary) !important;\r\n color: #ffffff !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button.ps-active *) {\r\n color: #ffffff !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button.ps-active .ps-menu-icon) {\r\n color: #ffffff !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button.ps-active .ps-menu-label) {\r\n color: #ffffff !important;\r\n}\r\n\r\n/* 菜单图标样式 */\r\n.sidebar :global(.ps-menu-icon) {\r\n margin-right: 0.5rem !important;\r\n width: 1.25rem !important;\r\n height: 1.25rem !important;\r\n color: var(--color-fg-text) !important;\r\n}\r\n\r\n/* 子菜单样式 */\r\n.sidebar :global(.ps-submenu-content) {\r\n background-color: var(--color-bg-3) !important;\r\n padding-left: 0.5rem !important;\r\n overflow: hidden !important;\r\n}\r\n\r\n.sidebar :global(.ps-submenu-content .ps-menu-button) {\r\n padding: 0.375rem 0.5rem !important;\r\n margin: 0.125rem 0.25rem !important;\r\n font-size: 0.8125rem !important;\r\n transition: all 0.2s ease !important;\r\n}\r\n\r\n/* 子菜单标题样式 */\r\n.sidebar :global(.ps-menu-label) {\r\n color: var(--color-fg-text) !important;\r\n font-weight: 500 !important;\r\n}\r\n\r\n/* 强制选中状态的所有子元素为白色 */\r\n.sidebar :global(.ps-menu-button.ps-active),\r\n.sidebar :global(.ps-menu-button.ps-active span),\r\n.sidebar :global(.ps-menu-button.ps-active div),\r\n.sidebar :global(.ps-menu-button.ps-active .ps-menu-icon),\r\n.sidebar :global(.ps-menu-button.ps-active .ps-menu-label) {\r\n color: #ffffff !important;\r\n}\r\n\r\n/* 退出登录按钮容器 */\r\n.logoutContainer {\r\n margin-top: auto;\r\n padding: 0.5rem;\r\n border-top: 1px solid var(--color-separator);\r\n flex-shrink: 0;\r\n writing-mode: horizontal-tb;\r\n text-orientation: mixed;\r\n}\r\n\r\n.logoutButton {\r\n width: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: flex-start;\r\n gap: 0.5rem;\r\n padding: 0.5rem 0.75rem;\r\n background: transparent;\r\n border: none;\r\n border-radius: 0.375rem;\r\n color: var(--color-fg-text);\r\n font-size: 0.875rem;\r\n cursor: pointer;\r\n transition:\r\n background-color 0.2s ease,\r\n color 0.2s ease;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n writing-mode: horizontal-tb;\r\n text-orientation: mixed;\r\n direction: ltr;\r\n}\r\n\r\n.logoutButton span {\r\n display: inline-block;\r\n writing-mode: horizontal-tb !important;\r\n text-orientation: mixed !important;\r\n direction: ltr !important;\r\n transform: none !important;\r\n transition:\r\n opacity 0.3s ease,\r\n max-width 0.3s ease;\r\n max-width: 200px;\r\n opacity: 1;\r\n}\r\n\r\n.logoutButton .hiddenText {\r\n opacity: 0;\r\n max-width: 0;\r\n width: 0;\r\n overflow: hidden;\r\n}\r\n\r\n.logoutButton .visibleText {\r\n opacity: 1;\r\n max-width: 200px;\r\n width: auto;\r\n}\r\n\r\n.logoutButton:hover {\r\n background-color: var(--color-bg-3);\r\n}\r\n\r\n.logoutButton:active {\r\n transform: scale(0.98);\r\n}\r\n\r\n.logoutButton svg {\r\n flex-shrink: 0;\r\n color: inherit;\r\n}\r\n","import type { SidebarMenuItem, SidebarProps } from \"../../types\";\n\nimport { memo, useCallback, useMemo } from \"react\";\nimport { Menu, MenuItem, Sidebar as ProSidebar, SubMenu } from \"react-pro-sidebar\";\n\nimport { LogOut } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\n/**\n * 当前路径是否命中该菜单项。\n * 若有 siblingPaths(同组子项路径),则只有当前路径精确等于 path 或匹配 path 下的详情(非其它子项)时才命中,避免 /categories 与 /categories/add 同时高亮。\n */\nfunction isPathActive(current: string, path: string, siblingPaths?: string[]): boolean {\n if (current === path) return true;\n if (!current.startsWith(path + \"/\")) return false;\n if (siblingPaths?.length) {\n const matchedSibling = siblingPaths.some((s) => s !== path && (current === s || current.startsWith(s + \"/\")));\n if (matchedSibling) return false;\n }\n return true;\n}\n\nfunction isSubMenuActive(current: string, item: SidebarMenuItem): boolean {\n if (isPathActive(current, item.path, item.children?.map((c) => c.path))) return true;\n if (!item.children) return false;\n return item.children.some((child) => isPathActive(current, child.path, item.children?.map((c) => c.path)) || isSubMenuActive(current, child));\n}\n\nconst Sidebar = memo(\n ({\n children,\n collapsed = false,\n toggled = false,\n onBackdropClick,\n breakPoint = \"all\",\n className,\n items = [],\n currentPathname = \"\",\n onNavigate,\n logoutLabel = \"Logout\",\n handleLogout,\n bottomLogoutButton,\n }: SidebarProps) => {\n const handleItemClick = useCallback(\n (path: string) => {\n onNavigate?.(path);\n },\n [onNavigate],\n );\n\n const renderItem = useCallback(\n (item: SidebarMenuItem, siblingPaths?: string[]) => {\n const active = isPathActive(currentPathname, item.path, siblingPaths);\n if (item.children?.length) {\n const subActive = isSubMenuActive(currentPathname, item);\n return (\n <SubMenu key={item.path} label={item.label} icon={item.icon} active={subActive}>\n {item.children.map((child) => renderItem(child, item.children!.map((c) => c.path)))}\n </SubMenu>\n );\n }\n return (\n <MenuItem key={item.path} icon={item.icon} onClick={() => handleItemClick(item.path)} active={active}>\n {item.label}\n </MenuItem>\n );\n },\n [currentPathname, handleItemClick],\n );\n\n const menuContent =\n items.length > 0 ? (\n <Menu\n key={`${collapsed}-${toggled}`}\n transitionDuration={300}\n closeOnClick\n menuItemStyles={{\n button: {\n color: \"var(--color-fg-text)\",\n backgroundColor: \"transparent\",\n \"&:hover\": {\n backgroundColor: \"var(--color-bg-3)\",\n color: \"var(--color-fg-text)\",\n },\n \"&.active\": {\n backgroundColor: \"var(--color-primary)\",\n color: \"#ffffff\",\n },\n },\n icon: {\n color: \"var(--color-fg-text)\",\n \"&.active\": {\n color: \"#ffffff\",\n },\n },\n label: {\n color: \"var(--color-fg-text)\",\n \"&.active\": {\n color: \"#ffffff\",\n },\n },\n }}\n >\n {items.map((item) => renderItem(item))}\n </Menu>\n ) : null;\n\n const bottomLogoutButtonContent = useMemo(() => {\n if (bottomLogoutButton != null) return bottomLogoutButton;\n if (handleLogout != null) {\n return (\n <div className={styles.logoutContainer}>\n <button type=\"button\" className={styles.logoutButton} onClick={handleLogout} title={logoutLabel}>\n <LogOut size={20} />\n <span className={collapsed ? styles.hiddenText : styles.visibleText}>{logoutLabel}</span>\n </button>\n </div>\n );\n }\n return null;\n }, [collapsed, logoutLabel, handleLogout, bottomLogoutButton]);\n\n return (\n <ProSidebar\n collapsed={collapsed}\n toggled={toggled}\n onBackdropClick={onBackdropClick}\n breakPoint={breakPoint}\n backgroundColor=\"var(--color-bg-2)\"\n rootStyles={{\n border: \"none\",\n borderRight: \"1px solid var(--color-separator)\",\n }}\n className={`${styles.sidebar} ${className || \"\"}`}\n >\n <div className={styles.sidebarContent} onWheel={(e) => e.stopPropagation()}>\n <div className={styles.menuWrapper}>{children ?? menuContent}</div>\n {bottomLogoutButtonContent}\n </div>\n </ProSidebar>\n );\n },\n);\n\nSidebar.displayName = \"Sidebar\";\nexport default Sidebar;\n","/* ===== Footer Component ===== */\r\n\r\n.footer {\r\n background: var(--color-bg-2);\r\n padding: 0 2rem;\r\n width: 100%;\r\n}\r\n\r\n.footerContent {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n max-width: 100%;\r\n margin: 0 auto;\r\n}\r\n\r\n.copyright {\r\n color: var(--color-fg-text);\r\n font-size: 0.875rem;\r\n}\r\n\r\n.links {\r\n display: flex;\r\n gap: 1.5rem;\r\n}\r\n\r\n.link {\r\n color: var(--color-fg-text);\r\n font-size: 0.875rem;\r\n text-decoration: none;\r\n transition: color 0.3s ease;\r\n}\r\n\r\n.link:hover {\r\n color: var(--color-primary);\r\n}\r\n\r\n/* ===== 响应式 ===== */\r\n@media (max-width: 768px) {\r\n .footerContent {\r\n flex-direction: column;\r\n gap: 1rem;\r\n }\r\n\r\n .links {\r\n gap: 1rem;\r\n }\r\n}\r\n","import type { FooterProps } from \"../../types\";\n\nimport { memo } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport const DefaultFooterContent = memo(() => {\n const currentYear = new Date().getFullYear();\n return (\n <div className={styles.footerContent}>\n <span className={styles.copyright}>© {currentYear}</span>\n <div className={styles.links}>\n <a href=\"#\" className={styles.link}>\n About Us\n </a>\n <a href=\"#\" className={styles.link}>\n Privacy Policy\n </a>\n <a href=\"#\" className={styles.link}>\n Terms of Service\n </a>\n </div>\n </div>\n );\n});\nDefaultFooterContent.displayName = \"DefaultFooterContent\";\n\n/** 通用 Footer:只负责布局与样式,内容由外部传入。 */\nconst Footer = memo(({ children, className }: FooterProps) => {\n return <div className={`${styles.footer} ${className || \"\"}`}>{children ?? <DefaultFooterContent />}</div>;\n});\n\nFooter.displayName = \"Footer\";\n\nexport default Footer;\n","/* ===== Header - 主容器样式 ===== */\r\n\r\n.header {\r\n display: flex;\r\n width: 100%;\r\n padding: 0.5rem 2rem;\r\n}\r\n\r\n/* 左侧容器:占一半,左对齐 */\r\n.header> :first-child {\r\n flex: 1;\r\n display: flex;\r\n justify-content: flex-start;\r\n align-items: center;\r\n}\r\n\r\n/* 右侧容器:占一半,右对齐 */\r\n.header> :last-child {\r\n flex: 1;\r\n display: flex;\r\n justify-content: flex-end;\r\n align-items: center;\r\n}","import type { HeaderProps } from \"../../types\";\n\nimport { memo } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\n/** 通用 Header:只负责布局左右两栏,内容全部由外部传入,内部不获取数据。Generic header: layout only; all content from props. */\nconst Header = memo(({ leftContent, rightContent }: HeaderProps) => {\n return (\n <div className={styles.header}>\n <div>{leftContent}</div>\n <div>{rightContent}</div>\n </div>\n );\n});\n\nHeader.displayName = \"Header\";\nexport default Header;\n","/* ===== One Column Layout ===== */\r\n\r\n.layout {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100vh;\r\n width: 100%;\r\n background: var(--color-bg);\r\n position: relative;\r\n}\r\n\r\n/* ===== Header ===== */\r\n.header {\r\n position: fixed;\r\n top: 0;\r\n z-index: 100;\r\n background: var(--color-bg);\r\n width: 100%;\r\n box-shadow: 0 0.125rem 0.25rem 0 rgba(44, 51, 73, 0.1);\r\n}\r\n\r\n\r\n/* ===== Footer ===== */\r\n.footer {\r\n position: fixed;\r\n bottom: 0;\r\n width: 100%;\r\n z-index: 100;\r\n}\r\n","import type { MainWrapperProps } from \"../../types\";\n\nimport { memo, useCallback, useLayoutEffect, useRef, useState } from \"react\";\n\nimport Footer from \"../Footer\";\nimport Header from \"../Header\";\nimport styles from \"./styles.module.css\";\n\nfunction useElementHeight<T extends HTMLElement>() {\n const ref = useRef<T | null>(null);\n const [height, setHeight] = useState(0);\n\n useLayoutEffect(() => {\n const node = ref.current;\n if (!node) return;\n\n const observer = new ResizeObserver(([entry]) => {\n const nextHeight = entry?.contentRect.height ?? 0;\n setHeight((prev) => (prev !== nextHeight ? nextHeight : prev));\n });\n\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const callbackRef = useCallback((instance: T | null) => {\n if (instance) {\n ref.current = instance;\n }\n }, []);\n\n return [callbackRef, height] as const;\n}\n\nconst MainWrapper = memo(({ children, headerLeft, headerRight, footerContent }: MainWrapperProps) => {\n const [headerRef, headerHeight] = useElementHeight<HTMLDivElement>();\n const [footerRef, footerHeight] = useElementHeight<HTMLDivElement>();\n\n return (\n <div className={styles.layout}>\n <header ref={headerRef} className={styles.header}>\n <Header leftContent={headerLeft} rightContent={headerRight} />\n </header>\n\n {children(headerHeight, footerHeight)}\n\n {/* Footer */}\n <footer ref={footerRef} className={styles.footer}>\n <Footer>{footerContent}</Footer>\n </footer>\n </div>\n );\n});\n\nMainWrapper.displayName = \"MainWrapper\";\nexport default MainWrapper;\n",".mainWrapper {\n display: flex;\n flex: 1;\n position: relative;\n}\n\n.sidebar {\n position: fixed;\n top: 0;\n}\n\n.content {\n flex: 1;\n background: var(--color-bg);\n overflow-y: auto;\n overflow-x: hidden;\n min-height: calc(100vh - 10rem);\n padding-top: 0;\n padding-bottom: 0;\n margin: 0;\n}\n\n@media (max-width: 768px) {\n .content {\n width: 100%;\n }\n .sidebar {\n position: fixed;\n top: 0;\n left: 0;\n height: 100vh;\n z-index: 999;\n }\n}\n","import type { SideHideLayoutProps } from \"../../types\";\n\nimport { memo, useCallback } from \"react\";\n\nimport useLayout from \"../../hooks/useLayout\";\nimport Sidebar from \"../Sidebar\";\nimport styles from \"./styles.module.css\";\n\nconst SideHideLayout = memo(\n ({\n children,\n headerHeight,\n footerHeight,\n sidebarItems,\n sidebarCurrentPathname,\n onSidebarNavigate,\n sidebarLogoutLabel,\n onSidebarLogout,\n }: SideHideLayoutProps) => {\n const { sidebarOpen, closeSidebar } = useLayout();\n\n const handleBackdropClick = useCallback(() => {\n closeSidebar();\n }, [closeSidebar]);\n\n return (\n <main\n className={styles.mainWrapper}\n style={{\n marginTop: `${headerHeight}px`,\n marginBottom: `${footerHeight}px`,\n }}\n >\n <Sidebar\n toggled={sidebarOpen}\n onBackdropClick={handleBackdropClick}\n breakPoint=\"all\"\n className={styles.sidebar}\n items={sidebarItems}\n currentPathname={sidebarCurrentPathname}\n onNavigate={onSidebarNavigate}\n logoutLabel={sidebarLogoutLabel}\n handleLogout={onSidebarLogout}\n />\n <div className={styles.content} data-lenis-prevent>\n {children}\n </div>\n </main>\n );\n },\n);\n\nSideHideLayout.displayName = \"SideHideLayout\";\n\nexport default SideHideLayout;\n","/* ===== Main Wrapper (Sidebar + Content) ===== */\n.mainWrapper {\n display: flex;\n flex: 1;\n position: relative;\n flex-direction: row;\n}\n\n.sidebarContainer {\n position: fixed;\n left: 0;\n z-index: 99;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.sidebar {\n top: 0;\n left: 0;\n flex-shrink: 0;\n}\n\n.content {\n flex: 1;\n background: var(--color-bg);\n overflow-y: auto;\n overflow-x: hidden;\n padding-top: 0;\n padding-bottom: 0;\n margin: 0;\n}\n\n@media (max-width: 1024px) {\n .content {\n padding: 1.5rem;\n }\n}\n\n@media (max-width: 768px) {\n .content {\n width: 100%;\n }\n .sidebar {\n position: fixed;\n top: 0;\n left: 0;\n height: 100vh;\n z-index: 999;\n }\n}\n","import type { SideShowLayoutProps } from \"../../types\";\n\nimport { memo, useCallback, useLayoutEffect, useRef, useState } from \"react\";\n\nimport useLayout from \"../../hooks/useLayout\";\nimport Sidebar from \"../Sidebar\";\nimport styles from \"./styles.module.css\";\n\nfunction useElementWidth<T extends HTMLElement>() {\n const ref = useRef<T | null>(null);\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n const node = ref.current;\n if (!node) return;\n\n const observer = new ResizeObserver(([entry]) => {\n const nextWidth = entry?.contentRect.width ?? 0;\n setWidth((prev) => (prev !== nextWidth ? nextWidth : prev));\n });\n\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const callbackRef = useCallback((instance: T | null) => {\n if (instance) {\n ref.current = instance;\n }\n }, []);\n\n return [callbackRef, width] as const;\n}\n\nconst SideShowLayout = memo(\n ({\n children,\n headerHeight,\n footerHeight,\n sidebarItems,\n sidebarCurrentPathname,\n onSidebarNavigate,\n sidebarLogoutLabel,\n onSidebarLogout,\n }: SideShowLayoutProps) => {\n const { sidebarOpen, closeSidebar } = useLayout();\n const [sidebarRef, sidebarWidth] = useElementWidth<HTMLDivElement>();\n\n const handleBackdropClick = () => {\n closeSidebar();\n };\n\n return (\n <>\n <div\n ref={sidebarRef}\n className={styles.sidebarContainer}\n style={{\n top: `${headerHeight}px`,\n height: `calc(100vh - ${headerHeight + footerHeight}px)`,\n }}\n >\n <Sidebar\n collapsed={sidebarOpen}\n toggled={sidebarOpen}\n onBackdropClick={handleBackdropClick}\n breakPoint=\"xs\"\n className={styles.sidebar}\n items={sidebarItems}\n currentPathname={sidebarCurrentPathname}\n onNavigate={onSidebarNavigate}\n logoutLabel={sidebarLogoutLabel}\n handleLogout={onSidebarLogout}\n />\n </div>\n <main\n className={styles.mainWrapper}\n style={{\n marginTop: `${headerHeight}px`,\n marginBottom: `${footerHeight}px`,\n marginLeft: `${sidebarWidth}px`,\n width: `calc(100% - ${sidebarWidth}px)`,\n }}\n >\n <div className={styles.content} data-lenis-prevent>\n {children}\n </div>\n </main>\n </>\n );\n },\n);\n\nSideShowLayout.displayName = \"SideShowLayout\";\nexport default SideShowLayout;\n",".wavesWrapper {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 0;\n overflow: hidden;\n}\n\n.wavesWrapper > * {\n pointer-events: auto;\n}\n\n.squaresWrapper {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 0;\n overflow: hidden;\n}\n\n.squaresWrapper > * {\n pointer-events: auto;\n}\n\n.letterGlitchWrapper {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 0;\n overflow: hidden;\n}\n\n.letterGlitchWrapper > * {\n pointer-events: auto;\n}\n\n.pixelBlastWrapper {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 0;\n overflow: hidden;\n}\n\n.pixelBlastWrapper > * {\n pointer-events: auto;\n}\n","import type { ReactNode } from \"react\";\n\nimport { memo } from \"react\";\n\nimport { LetterGlitchBackground, PixelBlastBackground, SquareBackground, WaveBackground } from \"@/designs/animations\";\nimport { DashboardBackgroundEnum } from \"@/preference\";\n\nimport styles from \"./styles.module.css\";\n\ninterface BackgroundProps {\n children: ReactNode;\n /** 可选:外部传入的偏好,有则优先使用;否则从 profile.preference 解析。Optional: preference from parent; otherwise parsed from profile. */\n background?: DashboardBackgroundEnum | null;\n}\n\n/** 与 NFX-Identity/console 一致:仪表盘背景由用户偏好(可外部传入或从 profile 解析) */\nconst Background = memo(({ children, background }: BackgroundProps) => {\n const renderBackground = () => {\n switch (background) {\n case DashboardBackgroundEnum.WAVES:\n return (\n <div className={styles.wavesWrapper}>\n <WaveBackground />\n </div>\n );\n case DashboardBackgroundEnum.SQUARES:\n return (\n <div className={styles.squaresWrapper}>\n <SquareBackground />\n </div>\n );\n case DashboardBackgroundEnum.LETTER_GLITCH:\n return (\n <div className={styles.letterGlitchWrapper}>\n <LetterGlitchBackground />\n </div>\n );\n case DashboardBackgroundEnum.PIXEL_BLAST:\n return (\n <div className={styles.pixelBlastWrapper}>\n <PixelBlastBackground />\n </div>\n );\n case DashboardBackgroundEnum.NONE:\n default:\n return null;\n }\n };\n\n return (\n <>\n {children}\n {renderBackground()}\n </>\n );\n});\n\nBackground.displayName = \"Background\";\nexport default Background;\nexport type { BackgroundProps };\n","import type { LayoutFrameProps } from \"../../types\";\n\nimport { memo } from \"react\";\n\nimport useLayout from \"../../hooks/useLayout\";\nimport { LayoutModeEnum } from \"../../types\";\nimport MainWrapper from \"../MainWrapper\";\nimport SideHideLayout from \"../SideHideLayout\";\nimport SideShowLayout from \"../SideShowLayout\";\n\nexport const LayoutFrame = memo(\n ({\n children,\n headerLeft,\n headerRight,\n footerContent,\n sidebarItems,\n sidebarCurrentPathname,\n onSidebarNavigate,\n sidebarLogoutLabel,\n onSidebarLogout,\n bottomLogoutButton,\n }: LayoutFrameProps) => {\n const { layoutMode } = useLayout();\n return (\n <MainWrapper headerLeft={headerLeft} headerRight={headerRight} footerContent={footerContent}>\n {(headerHeight, footerHeight) => {\n if (layoutMode === LayoutModeEnum.HIDE) {\n return (\n <SideHideLayout\n headerHeight={headerHeight}\n footerHeight={footerHeight}\n sidebarItems={sidebarItems}\n sidebarCurrentPathname={sidebarCurrentPathname}\n onSidebarNavigate={onSidebarNavigate}\n sidebarLogoutLabel={sidebarLogoutLabel}\n onSidebarLogout={onSidebarLogout}\n bottomLogoutButton={bottomLogoutButton}\n >\n {children}\n </SideHideLayout>\n );\n } else {\n return (\n <SideShowLayout\n headerHeight={headerHeight}\n footerHeight={footerHeight}\n sidebarItems={sidebarItems}\n sidebarCurrentPathname={sidebarCurrentPathname}\n onSidebarNavigate={onSidebarNavigate}\n sidebarLogoutLabel={sidebarLogoutLabel}\n onSidebarLogout={onSidebarLogout}\n bottomLogoutButton={bottomLogoutButton}\n >\n {children}\n </SideShowLayout>\n );\n }\n }}\n </MainWrapper>\n );\n },\n);\n\nLayoutFrame.displayName = \"LayoutFrame\";\nexport default LayoutFrame;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { getLayoutStorage, setLayoutStorage } from \"../utils\";\nimport { LayoutModeEnum } from \"../types\";\n\ninterface UseSetProps {\n defaultLayoutMode: LayoutModeEnum;\n sidebarOpen: boolean;\n}\n\nconst useSet = ({ defaultLayoutMode, sidebarOpen }: UseSetProps) => {\n const [layoutMode, setLayoutModeState] = useState<LayoutModeEnum>(() => {\n const saved = getLayoutStorage();\n if (saved) {\n try {\n const parsed = JSON.parse(saved);\n const mode = parsed.state?.layoutMode ?? parsed.layoutMode;\n return mode === LayoutModeEnum.SHOW || mode === LayoutModeEnum.HIDE ? mode : defaultLayoutMode;\n } catch {\n return defaultLayoutMode;\n }\n }\n return defaultLayoutMode;\n });\n\n useEffect(() => {\n const storage = {\n state: {\n sidebarOpen,\n layoutMode,\n },\n };\n setLayoutStorage(JSON.stringify(storage));\n }, [sidebarOpen, layoutMode]);\n\n const setLayoutMode = useCallback((mode: LayoutModeEnum) => {\n setLayoutModeState(mode);\n }, []);\n\n return {\n layoutMode,\n setLayoutMode,\n };\n};\n\nexport default useSet;\n","import { useCallback, useState } from \"react\";\n\nimport { getLayoutStorage } from \"../utils\";\n\nconst useAction = () => {\n const [sidebarOpen, setSidebarOpenState] = useState<boolean>(() => {\n const saved = getLayoutStorage();\n if (saved) {\n try {\n const parsed = JSON.parse(saved);\n return parsed.state?.sidebarOpen ?? parsed.sidebarOpen ?? false;\n } catch {\n return false;\n }\n }\n return false;\n });\n\n const setSidebarOpen = useCallback((open: boolean) => {\n setSidebarOpenState(open);\n }, []);\n\n const toggleSidebar = useCallback(() => {\n setSidebarOpenState((prev) => !prev);\n }, []);\n\n const closeSidebar = useCallback(() => {\n setSidebarOpenState(false);\n }, []);\n\n return {\n sidebarOpen,\n setSidebarOpen,\n toggleSidebar,\n closeSidebar,\n };\n};\n\nexport default useAction;\n","/**\n * 布局提供者:提供侧栏开关与显示/隐藏模式上下文。\n * Layout provider: provides sidebar state and show/hide layout mode context.\n */\nimport type { LayoutProviderProps } from \"../types\";\n\nimport { memo } from \"react\";\n\nimport useAction from \"../hooks/useAction\";\nimport { LayoutContext } from \"../hooks/useLayout\";\nimport useSet from \"../hooks/useSet\";\nimport { DEFAULT_LAYOUT_MODE } from \"../types\";\n\nconst LayoutProvider = memo(({ children, defaultLayoutMode = DEFAULT_LAYOUT_MODE }: LayoutProviderProps) => {\n const { sidebarOpen, setSidebarOpen, toggleSidebar, closeSidebar } = useAction();\n const { layoutMode, setLayoutMode } = useSet({ defaultLayoutMode, sidebarOpen });\n\n return (\n <LayoutContext.Provider\n value={{\n sidebarOpen,\n layoutMode,\n setSidebarOpen,\n toggleSidebar,\n closeSidebar,\n setLayoutMode,\n }}\n >\n {children}\n </LayoutContext.Provider>\n );\n});\n\nLayoutProvider.displayName = \"LayoutProvider\";\nexport default LayoutProvider;\n"],"mappings":"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"}
1
+ {"version":3,"file":"layouts.cjs","names":[],"sources":["../src/designs/layouts/utils/layoutStorage.ts","../src/designs/layouts/components/Sidebar/styles.module.css","../src/designs/layouts/components/Sidebar/index.tsx","../src/designs/layouts/components/Footer/styles.module.css","../src/designs/layouts/components/Footer/index.tsx","../src/designs/layouts/components/Header/styles.module.css","../src/designs/layouts/components/Header/index.tsx","../src/designs/layouts/components/MainWrapper/styles.module.css","../src/designs/layouts/components/MainWrapper/index.tsx","../src/designs/layouts/components/SideHideLayout/styles.module.css","../src/designs/layouts/components/SideHideLayout/index.tsx","../src/designs/layouts/components/SideShowLayout/styles.module.css","../src/designs/layouts/components/SideShowLayout/index.tsx","../src/designs/layouts/components/Background/styles.module.css","../src/designs/layouts/components/Background/index.tsx","../src/designs/layouts/components/LayoutFrame/index.tsx","../src/designs/layouts/hooks/useSet.ts","../src/designs/layouts/hooks/useAction.ts","../src/designs/layouts/providers/index.tsx"],"sourcesContent":["/**\n * 布局相关 localStorage 读写与移除,统一走 utils/lstorage。\n * Layout localStorage get/set/remove via utils/lstorage.\n */\nimport type { Nilable } from \"@/types/utils\";\nimport { getItem, removeItem, setItem } from \"@/utils/lstorage\";\n\nimport { LAYOUT_STORAGE_KEY } from \"../types\";\n\nexport function getLayoutStorage(): Nilable<string> {\n return getItem(LAYOUT_STORAGE_KEY);\n}\n\nexport function setLayoutStorage(value: string): void {\n setItem(LAYOUT_STORAGE_KEY, value);\n}\n\nexport function removeLayoutStorage(): void {\n removeItem(LAYOUT_STORAGE_KEY);\n}\n","/* ===== Sidebar Component ===== */\r\n\r\n.sidebar {\r\n height: 100%;\r\n min-height: 0;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n}\r\n\r\n.sidebarContent {\r\n padding-top: 1rem;\r\n height: 100%;\r\n min-height: 0;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n}\r\n\r\n.menuWrapper {\r\n flex: 1;\r\n min-height: 0;\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n}\r\n\r\n/* 自定义滚动条样式 - 隐藏但保持滚动功能 */\r\n.sidebarContent::-webkit-scrollbar {\r\n width: 0px;\r\n}\r\n\r\n.sidebarContent::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.sidebarContent::-webkit-scrollbar-thumb {\r\n background: transparent;\r\n}\r\n\r\n.sidebarContent::-webkit-scrollbar-thumb:hover {\r\n background: transparent;\r\n}\r\n\r\n/* 内部 a 元素左边距为 0 */\r\n.sidebar :global(a) {\r\n margin-left: 0;\r\n}\r\n\r\n/* 覆盖 react-pro-sidebar 默认样式 */\r\n.sidebar :global(.ps-sidebar-root) {\r\n height: 100% !important;\r\n min-height: 0 !important;\r\n overflow: hidden !important;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n background-color: var(--color-bg-2) !important;\r\n border-right: 1px solid var(--color-separator) !important;\r\n}\r\n\r\n.sidebar :global(.ps-sidebar-container) {\r\n height: 100% !important;\r\n min-height: 0 !important;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n flex: 1 !important;\r\n overflow: hidden !important;\r\n background-color: var(--color-bg-2) !important;\r\n color: var(--color-fg-text) !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button) {\r\n padding: 0.5rem 0.75rem !important;\r\n margin: 0.125rem 0.5rem !important;\r\n border-radius: 0.375rem !important;\r\n transition: all 0.2s ease !important;\r\n color: var(--color-fg-text) !important;\r\n font-size: 0.875rem !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button:hover) {\r\n background-color: var(--color-bg-3) !important;\r\n color: var(--color-fg-text) !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button.ps-active) {\r\n background-color: var(--color-primary) !important;\r\n color: #ffffff !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button.ps-active *) {\r\n color: #ffffff !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button.ps-active .ps-menu-icon) {\r\n color: #ffffff !important;\r\n}\r\n\r\n.sidebar :global(.ps-menu-button.ps-active .ps-menu-label) {\r\n color: #ffffff !important;\r\n}\r\n\r\n/* 菜单图标样式 */\r\n.sidebar :global(.ps-menu-icon) {\r\n margin-right: 0.5rem !important;\r\n width: 1.25rem !important;\r\n height: 1.25rem !important;\r\n color: var(--color-fg-text) !important;\r\n}\r\n\r\n/* 子菜单样式 */\r\n.sidebar :global(.ps-submenu-content) {\r\n background-color: var(--color-bg-3) !important;\r\n padding-left: 0.5rem !important;\r\n overflow: hidden !important;\r\n}\r\n\r\n.sidebar :global(.ps-submenu-content .ps-menu-button) {\r\n padding: 0.375rem 0.5rem !important;\r\n margin: 0.125rem 0.25rem !important;\r\n font-size: 0.8125rem !important;\r\n transition: all 0.2s ease !important;\r\n}\r\n\r\n/* 子菜单标题样式 */\r\n.sidebar :global(.ps-menu-label) {\r\n color: var(--color-fg-text) !important;\r\n font-weight: 500 !important;\r\n}\r\n\r\n/* 强制选中状态的所有子元素为白色 */\r\n.sidebar :global(.ps-menu-button.ps-active),\r\n.sidebar :global(.ps-menu-button.ps-active span),\r\n.sidebar :global(.ps-menu-button.ps-active div),\r\n.sidebar :global(.ps-menu-button.ps-active .ps-menu-icon),\r\n.sidebar :global(.ps-menu-button.ps-active .ps-menu-label) {\r\n color: #ffffff !important;\r\n}\r\n\r\n/* 退出登录按钮容器 */\r\n.logoutContainer {\r\n margin-top: auto;\r\n padding: 0.5rem;\r\n border-top: 1px solid var(--color-separator);\r\n flex-shrink: 0;\r\n writing-mode: horizontal-tb;\r\n text-orientation: mixed;\r\n}\r\n\r\n.logoutButton {\r\n width: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: flex-start;\r\n gap: 0.5rem;\r\n padding: 0.5rem 0.75rem;\r\n background: transparent;\r\n border: none;\r\n border-radius: 0.375rem;\r\n color: var(--color-fg-text);\r\n font-size: 0.875rem;\r\n cursor: pointer;\r\n transition:\r\n background-color 0.2s ease,\r\n color 0.2s ease;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n writing-mode: horizontal-tb;\r\n text-orientation: mixed;\r\n direction: ltr;\r\n}\r\n\r\n.logoutButton span {\r\n display: inline-block;\r\n writing-mode: horizontal-tb !important;\r\n text-orientation: mixed !important;\r\n direction: ltr !important;\r\n transform: none !important;\r\n transition:\r\n opacity 0.3s ease,\r\n max-width 0.3s ease;\r\n max-width: 200px;\r\n opacity: 1;\r\n}\r\n\r\n.logoutButton .hiddenText {\r\n opacity: 0;\r\n max-width: 0;\r\n width: 0;\r\n overflow: hidden;\r\n}\r\n\r\n.logoutButton .visibleText {\r\n opacity: 1;\r\n max-width: 200px;\r\n width: auto;\r\n}\r\n\r\n.logoutButton:hover {\r\n background-color: var(--color-bg-3);\r\n}\r\n\r\n.logoutButton:active {\r\n transform: scale(0.98);\r\n}\r\n\r\n.logoutButton svg {\r\n flex-shrink: 0;\r\n color: inherit;\r\n}\r\n","import type { SidebarMenuItem, SidebarProps } from \"../../types\";\n\nimport { memo, useCallback, useMemo } from \"react\";\nimport { Menu, MenuItem, Sidebar as ProSidebar, SubMenu } from \"react-pro-sidebar\";\n\nimport { LogOut } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\n/**\n * 当前路径是否命中该菜单项。\n * 若有 siblingPaths(同组子项路径),则只有当前路径精确等于 path 或匹配 path 下的详情(非其它子项)时才命中,避免 /categories 与 /categories/add 同时高亮。\n */\nfunction isPathActive(current: string, path: string, siblingPaths?: string[]): boolean {\n if (current === path) return true;\n if (!current.startsWith(path + \"/\")) return false;\n if (siblingPaths?.length) {\n const matchedSibling = siblingPaths.some((s) => s !== path && (current === s || current.startsWith(s + \"/\")));\n if (matchedSibling) return false;\n }\n return true;\n}\n\nfunction isSubMenuActive(current: string, item: SidebarMenuItem): boolean {\n if (isPathActive(current, item.path, item.children?.map((c) => c.path))) return true;\n if (!item.children) return false;\n return item.children.some((child) => isPathActive(current, child.path, item.children?.map((c) => c.path)) || isSubMenuActive(current, child));\n}\n\nconst Sidebar = memo(\n ({\n children,\n collapsed = false,\n toggled = false,\n onBackdropClick,\n breakPoint = \"all\",\n className,\n items = [],\n currentPathname = \"\",\n onNavigate,\n logoutLabel = \"Logout\",\n handleLogout,\n bottomLogoutButton,\n }: SidebarProps) => {\n const handleItemClick = useCallback(\n (path: string) => {\n onNavigate?.(path);\n },\n [onNavigate],\n );\n\n const renderItem = useCallback(\n (item: SidebarMenuItem, siblingPaths?: string[]) => {\n const active = isPathActive(currentPathname, item.path, siblingPaths);\n if (item.children?.length) {\n const subActive = isSubMenuActive(currentPathname, item);\n return (\n <SubMenu key={item.path} label={item.label} icon={item.icon} active={subActive}>\n {item.children.map((child) => renderItem(child, item.children!.map((c) => c.path)))}\n </SubMenu>\n );\n }\n return (\n <MenuItem key={item.path} icon={item.icon} onClick={() => handleItemClick(item.path)} active={active}>\n {item.label}\n </MenuItem>\n );\n },\n [currentPathname, handleItemClick],\n );\n\n const menuContent =\n items.length > 0 ? (\n <Menu\n key={`${collapsed}-${toggled}`}\n transitionDuration={300}\n closeOnClick\n menuItemStyles={{\n button: {\n color: \"var(--color-fg-text)\",\n backgroundColor: \"transparent\",\n \"&:hover\": {\n backgroundColor: \"var(--color-bg-3)\",\n color: \"var(--color-fg-text)\",\n },\n \"&.active\": {\n backgroundColor: \"var(--color-primary)\",\n color: \"#ffffff\",\n },\n },\n icon: {\n color: \"var(--color-fg-text)\",\n \"&.active\": {\n color: \"#ffffff\",\n },\n },\n label: {\n color: \"var(--color-fg-text)\",\n \"&.active\": {\n color: \"#ffffff\",\n },\n },\n }}\n >\n {items.map((item) => renderItem(item))}\n </Menu>\n ) : null;\n\n const bottomLogoutButtonContent = useMemo(() => {\n if (bottomLogoutButton != null) return bottomLogoutButton;\n if (handleLogout != null) {\n return (\n <div className={styles.logoutContainer}>\n <button type=\"button\" className={styles.logoutButton} onClick={handleLogout} title={logoutLabel}>\n <LogOut size={20} />\n <span className={collapsed ? styles.hiddenText : styles.visibleText}>{logoutLabel}</span>\n </button>\n </div>\n );\n }\n return null;\n }, [collapsed, logoutLabel, handleLogout, bottomLogoutButton]);\n\n return (\n <ProSidebar\n collapsed={collapsed}\n toggled={toggled}\n onBackdropClick={onBackdropClick}\n breakPoint={breakPoint}\n backgroundColor=\"var(--color-bg-2)\"\n rootStyles={{\n border: \"none\",\n borderRight: \"1px solid var(--color-separator)\",\n }}\n className={`${styles.sidebar} ${className || \"\"}`}\n >\n <div className={styles.sidebarContent} onWheel={(e) => e.stopPropagation()}>\n <div className={styles.menuWrapper}>{children ?? menuContent}</div>\n {bottomLogoutButtonContent}\n </div>\n </ProSidebar>\n );\n },\n);\n\nSidebar.displayName = \"Sidebar\";\nexport default Sidebar;\n","/* ===== Footer Component ===== */\r\n\r\n.footer {\r\n background: var(--color-bg-2);\r\n padding: 0 2rem;\r\n width: 100%;\r\n}\r\n\r\n.footerContent {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n max-width: 100%;\r\n margin: 0 auto;\r\n}\r\n\r\n.copyright {\r\n color: var(--color-fg-text);\r\n font-size: 0.875rem;\r\n}\r\n\r\n.links {\r\n display: flex;\r\n gap: 1.5rem;\r\n}\r\n\r\n.link {\r\n color: var(--color-fg-text);\r\n font-size: 0.875rem;\r\n text-decoration: none;\r\n transition: color 0.3s ease;\r\n}\r\n\r\n.link:hover {\r\n color: var(--color-primary);\r\n}\r\n\r\n/* ===== 响应式 ===== */\r\n@media (max-width: 768px) {\r\n .footerContent {\r\n flex-direction: column;\r\n gap: 1rem;\r\n }\r\n\r\n .links {\r\n gap: 1rem;\r\n }\r\n}\r\n","import type { FooterProps } from \"../../types\";\n\nimport { memo } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport const DefaultFooterContent = memo(() => {\n const currentYear = new Date().getFullYear();\n return (\n <div className={styles.footerContent}>\n <span className={styles.copyright}>© {currentYear}</span>\n <div className={styles.links}>\n <a href=\"#\" className={styles.link}>\n About Us\n </a>\n <a href=\"#\" className={styles.link}>\n Privacy Policy\n </a>\n <a href=\"#\" className={styles.link}>\n Terms of Service\n </a>\n </div>\n </div>\n );\n});\nDefaultFooterContent.displayName = \"DefaultFooterContent\";\n\n/** 通用 Footer:只负责布局与样式,内容由外部传入。 */\nconst Footer = memo(({ children, className }: FooterProps) => {\n return <div className={`${styles.footer} ${className || \"\"}`}>{children ?? <DefaultFooterContent />}</div>;\n});\n\nFooter.displayName = \"Footer\";\n\nexport default Footer;\n","/* ===== Header - 主容器样式 ===== */\r\n\r\n.header {\r\n display: flex;\r\n width: 100%;\r\n padding: 0.5rem 2rem;\r\n}\r\n\r\n/* 左侧容器:占一半,左对齐 */\r\n.header> :first-child {\r\n flex: 1;\r\n display: flex;\r\n justify-content: flex-start;\r\n align-items: center;\r\n}\r\n\r\n/* 右侧容器:占一半,右对齐 */\r\n.header> :last-child {\r\n flex: 1;\r\n display: flex;\r\n justify-content: flex-end;\r\n align-items: center;\r\n}","import type { HeaderProps } from \"../../types\";\n\nimport { memo } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\n/** 通用 Header:只负责布局左右两栏,内容全部由外部传入,内部不获取数据。Generic header: layout only; all content from props. */\nconst Header = memo(({ leftContent, rightContent }: HeaderProps) => {\n return (\n <div className={styles.header}>\n <div>{leftContent}</div>\n <div>{rightContent}</div>\n </div>\n );\n});\n\nHeader.displayName = \"Header\";\nexport default Header;\n","/* ===== One Column Layout ===== */\r\n\r\n.layout {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100vh;\r\n width: 100%;\r\n background: var(--color-bg);\r\n position: relative;\r\n}\r\n\r\n/* ===== Header ===== */\r\n.header {\r\n position: fixed;\r\n top: 0;\r\n z-index: 100;\r\n background: var(--color-bg);\r\n width: 100%;\r\n box-shadow: 0 0.125rem 0.25rem 0 rgba(44, 51, 73, 0.1);\r\n}\r\n\r\n\r\n/* ===== Footer ===== */\r\n.footer {\r\n position: fixed;\r\n bottom: 0;\r\n width: 100%;\r\n z-index: 100;\r\n}\r\n","import type { MainWrapperProps } from \"../../types\";\n\nimport { memo, useCallback, useLayoutEffect, useRef, useState } from \"react\";\n\nimport Footer from \"../Footer\";\nimport Header from \"../Header\";\nimport styles from \"./styles.module.css\";\n\nfunction useElementHeight<T extends HTMLElement>() {\n const ref = useRef<T | null>(null);\n const [height, setHeight] = useState(0);\n\n useLayoutEffect(() => {\n const node = ref.current;\n if (!node) return;\n\n const observer = new ResizeObserver(([entry]) => {\n const nextHeight = entry?.contentRect.height ?? 0;\n setHeight((prev) => (prev !== nextHeight ? nextHeight : prev));\n });\n\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const callbackRef = useCallback((instance: T | null) => {\n if (instance) {\n ref.current = instance;\n }\n }, []);\n\n return [callbackRef, height] as const;\n}\n\nconst MainWrapper = memo(({ children, headerLeft, headerRight, footerContent }: MainWrapperProps) => {\n const [headerRef, headerHeight] = useElementHeight<HTMLDivElement>();\n const [footerRef, footerHeight] = useElementHeight<HTMLDivElement>();\n\n return (\n <div className={styles.layout}>\n <header ref={headerRef} className={styles.header}>\n <Header leftContent={headerLeft} rightContent={headerRight} />\n </header>\n\n {children(headerHeight, footerHeight)}\n\n {/* Footer */}\n <footer ref={footerRef} className={styles.footer}>\n <Footer>{footerContent}</Footer>\n </footer>\n </div>\n );\n});\n\nMainWrapper.displayName = \"MainWrapper\";\nexport default MainWrapper;\n",".mainWrapper {\n display: flex;\n flex: 1;\n position: relative;\n}\n\n.sidebar {\n position: fixed;\n top: 0;\n}\n\n.content {\n flex: 1;\n background: var(--color-bg);\n overflow-y: auto;\n overflow-x: hidden;\n min-height: calc(100vh - 10rem);\n padding-top: 0;\n padding-bottom: 0;\n margin: 0;\n}\n\n@media (max-width: 768px) {\n .content {\n width: 100%;\n }\n .sidebar {\n position: fixed;\n top: 0;\n left: 0;\n height: 100vh;\n z-index: 999;\n }\n}\n","import type { SideHideLayoutProps } from \"../../types\";\n\nimport { memo, useCallback } from \"react\";\n\nimport useLayout from \"../../hooks/useLayout\";\nimport Sidebar from \"../Sidebar\";\nimport styles from \"./styles.module.css\";\n\nconst SideHideLayout = memo(\n ({\n children,\n headerHeight,\n footerHeight,\n sidebarItems,\n sidebarCurrentPathname,\n onSidebarNavigate,\n sidebarLogoutLabel,\n onSidebarLogout,\n }: SideHideLayoutProps) => {\n const { sidebarOpen, closeSidebar } = useLayout();\n\n const handleBackdropClick = useCallback(() => {\n closeSidebar();\n }, [closeSidebar]);\n\n return (\n <main\n className={styles.mainWrapper}\n style={{\n marginTop: `${headerHeight}px`,\n marginBottom: `${footerHeight}px`,\n }}\n >\n <Sidebar\n toggled={sidebarOpen}\n onBackdropClick={handleBackdropClick}\n breakPoint=\"all\"\n className={styles.sidebar}\n items={sidebarItems}\n currentPathname={sidebarCurrentPathname}\n onNavigate={onSidebarNavigate}\n logoutLabel={sidebarLogoutLabel}\n handleLogout={onSidebarLogout}\n />\n <div className={styles.content} data-lenis-prevent>\n {children}\n </div>\n </main>\n );\n },\n);\n\nSideHideLayout.displayName = \"SideHideLayout\";\n\nexport default SideHideLayout;\n","/* ===== Main Wrapper (Sidebar + Content) ===== */\n.mainWrapper {\n display: flex;\n flex: 1;\n position: relative;\n flex-direction: row;\n}\n\n.sidebarContainer {\n position: fixed;\n left: 0;\n z-index: 99;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n.sidebar {\n top: 0;\n left: 0;\n flex-shrink: 0;\n}\n\n.content {\n flex: 1;\n background: var(--color-bg);\n overflow-y: auto;\n overflow-x: hidden;\n padding-top: 0;\n padding-bottom: 0;\n margin: 0;\n}\n\n@media (max-width: 1024px) {\n .content {\n padding: 1.5rem;\n }\n}\n\n@media (max-width: 768px) {\n .content {\n width: 100%;\n }\n .sidebar {\n position: fixed;\n top: 0;\n left: 0;\n height: 100vh;\n z-index: 999;\n }\n}\n","import type { SideShowLayoutProps } from \"../../types\";\n\nimport { memo, useCallback, useLayoutEffect, useRef, useState } from \"react\";\n\nimport useLayout from \"../../hooks/useLayout\";\nimport Sidebar from \"../Sidebar\";\nimport styles from \"./styles.module.css\";\n\nfunction useElementWidth<T extends HTMLElement>() {\n const ref = useRef<T | null>(null);\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n const node = ref.current;\n if (!node) return;\n\n const observer = new ResizeObserver(([entry]) => {\n const nextWidth = entry?.contentRect.width ?? 0;\n setWidth((prev) => (prev !== nextWidth ? nextWidth : prev));\n });\n\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const callbackRef = useCallback((instance: T | null) => {\n if (instance) {\n ref.current = instance;\n }\n }, []);\n\n return [callbackRef, width] as const;\n}\n\nconst SideShowLayout = memo(\n ({\n children,\n headerHeight,\n footerHeight,\n sidebarItems,\n sidebarCurrentPathname,\n onSidebarNavigate,\n sidebarLogoutLabel,\n onSidebarLogout,\n }: SideShowLayoutProps) => {\n const { sidebarOpen, closeSidebar } = useLayout();\n const [sidebarRef, sidebarWidth] = useElementWidth<HTMLDivElement>();\n\n const handleBackdropClick = () => {\n closeSidebar();\n };\n\n return (\n <>\n <div\n ref={sidebarRef}\n className={styles.sidebarContainer}\n style={{\n top: `${headerHeight}px`,\n height: `calc(100vh - ${headerHeight + footerHeight}px)`,\n }}\n >\n <Sidebar\n collapsed={sidebarOpen}\n toggled={sidebarOpen}\n onBackdropClick={handleBackdropClick}\n breakPoint=\"xs\"\n className={styles.sidebar}\n items={sidebarItems}\n currentPathname={sidebarCurrentPathname}\n onNavigate={onSidebarNavigate}\n logoutLabel={sidebarLogoutLabel}\n handleLogout={onSidebarLogout}\n />\n </div>\n <main\n className={styles.mainWrapper}\n style={{\n marginTop: `${headerHeight}px`,\n marginBottom: `${footerHeight}px`,\n marginLeft: `${sidebarWidth}px`,\n width: `calc(100% - ${sidebarWidth}px)`,\n }}\n >\n <div className={styles.content} data-lenis-prevent>\n {children}\n </div>\n </main>\n </>\n );\n },\n);\n\nSideShowLayout.displayName = \"SideShowLayout\";\nexport default SideShowLayout;\n",".wavesWrapper {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 0;\n overflow: hidden;\n}\n\n.wavesWrapper > * {\n pointer-events: auto;\n}\n\n.squaresWrapper {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 0;\n overflow: hidden;\n}\n\n.squaresWrapper > * {\n pointer-events: auto;\n}\n\n.letterGlitchWrapper {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 0;\n overflow: hidden;\n}\n\n.letterGlitchWrapper > * {\n pointer-events: auto;\n}\n\n.pixelBlastWrapper {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 0;\n overflow: hidden;\n}\n\n.pixelBlastWrapper > * {\n pointer-events: auto;\n}\n","import type { ReactNode } from \"react\";\n\nimport { Suspense, lazy, memo } from \"react\";\n\nimport { LetterGlitchBackground, SquareBackground, WaveBackground } from \"@/designs/animations\";\nimport { DashboardBackgroundEnum } from \"@/preference\";\n\nimport styles from \"./styles.module.css\";\n\nconst LazyPixelBlast = lazy(() => import(\"@/designs/animations/PixelBlast\"));\n\ninterface BackgroundProps {\n children: ReactNode;\n /** 可选:外部传入的偏好,有则优先使用;否则从 profile.preference 解析。Optional: preference from parent; otherwise parsed from profile. */\n background?: DashboardBackgroundEnum | null;\n}\n\n/** 与 NFX-Identity/console 一致:仪表盘背景由用户偏好(可外部传入或从 profile 解析) */\nconst Background = memo(({ children, background }: BackgroundProps) => {\n const renderBackground = () => {\n switch (background) {\n case DashboardBackgroundEnum.WAVES:\n return (\n <div className={styles.wavesWrapper}>\n <WaveBackground />\n </div>\n );\n case DashboardBackgroundEnum.SQUARES:\n return (\n <div className={styles.squaresWrapper}>\n <SquareBackground />\n </div>\n );\n case DashboardBackgroundEnum.LETTER_GLITCH:\n return (\n <div className={styles.letterGlitchWrapper}>\n <LetterGlitchBackground />\n </div>\n );\n case DashboardBackgroundEnum.PIXEL_BLAST:\n return (\n <Suspense fallback={null}>\n <div className={styles.pixelBlastWrapper}>\n <LazyPixelBlast />\n </div>\n </Suspense>\n );\n case DashboardBackgroundEnum.NONE:\n default:\n return null;\n }\n };\n\n return (\n <>\n {children}\n {renderBackground()}\n </>\n );\n});\n\nBackground.displayName = \"Background\";\nexport default Background;\nexport type { BackgroundProps };\n","import type { LayoutFrameProps } from \"../../types\";\n\nimport { memo } from \"react\";\n\nimport useLayout from \"../../hooks/useLayout\";\nimport { LayoutModeEnum } from \"../../types\";\nimport MainWrapper from \"../MainWrapper\";\nimport SideHideLayout from \"../SideHideLayout\";\nimport SideShowLayout from \"../SideShowLayout\";\n\nexport const LayoutFrame = memo(\n ({\n children,\n headerLeft,\n headerRight,\n footerContent,\n sidebarItems,\n sidebarCurrentPathname,\n onSidebarNavigate,\n sidebarLogoutLabel,\n onSidebarLogout,\n bottomLogoutButton,\n }: LayoutFrameProps) => {\n const { layoutMode } = useLayout();\n return (\n <MainWrapper headerLeft={headerLeft} headerRight={headerRight} footerContent={footerContent}>\n {(headerHeight, footerHeight) => {\n if (layoutMode === LayoutModeEnum.HIDE) {\n return (\n <SideHideLayout\n headerHeight={headerHeight}\n footerHeight={footerHeight}\n sidebarItems={sidebarItems}\n sidebarCurrentPathname={sidebarCurrentPathname}\n onSidebarNavigate={onSidebarNavigate}\n sidebarLogoutLabel={sidebarLogoutLabel}\n onSidebarLogout={onSidebarLogout}\n bottomLogoutButton={bottomLogoutButton}\n >\n {children}\n </SideHideLayout>\n );\n } else {\n return (\n <SideShowLayout\n headerHeight={headerHeight}\n footerHeight={footerHeight}\n sidebarItems={sidebarItems}\n sidebarCurrentPathname={sidebarCurrentPathname}\n onSidebarNavigate={onSidebarNavigate}\n sidebarLogoutLabel={sidebarLogoutLabel}\n onSidebarLogout={onSidebarLogout}\n bottomLogoutButton={bottomLogoutButton}\n >\n {children}\n </SideShowLayout>\n );\n }\n }}\n </MainWrapper>\n );\n },\n);\n\nLayoutFrame.displayName = \"LayoutFrame\";\nexport default LayoutFrame;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { getLayoutStorage, setLayoutStorage } from \"../utils\";\nimport { LayoutModeEnum } from \"../types\";\n\ninterface UseSetProps {\n defaultLayoutMode: LayoutModeEnum;\n sidebarOpen: boolean;\n}\n\nconst useSet = ({ defaultLayoutMode, sidebarOpen }: UseSetProps) => {\n const [layoutMode, setLayoutModeState] = useState<LayoutModeEnum>(() => {\n const saved = getLayoutStorage();\n if (saved) {\n try {\n const parsed = JSON.parse(saved);\n const mode = parsed.state?.layoutMode ?? parsed.layoutMode;\n return mode === LayoutModeEnum.SHOW || mode === LayoutModeEnum.HIDE ? mode : defaultLayoutMode;\n } catch {\n return defaultLayoutMode;\n }\n }\n return defaultLayoutMode;\n });\n\n useEffect(() => {\n const storage = {\n state: {\n sidebarOpen,\n layoutMode,\n },\n };\n setLayoutStorage(JSON.stringify(storage));\n }, [sidebarOpen, layoutMode]);\n\n const setLayoutMode = useCallback((mode: LayoutModeEnum) => {\n setLayoutModeState(mode);\n }, []);\n\n return {\n layoutMode,\n setLayoutMode,\n };\n};\n\nexport default useSet;\n","import { useCallback, useState } from \"react\";\n\nimport { getLayoutStorage } from \"../utils\";\n\nconst useAction = () => {\n const [sidebarOpen, setSidebarOpenState] = useState<boolean>(() => {\n const saved = getLayoutStorage();\n if (saved) {\n try {\n const parsed = JSON.parse(saved);\n return parsed.state?.sidebarOpen ?? parsed.sidebarOpen ?? false;\n } catch {\n return false;\n }\n }\n return false;\n });\n\n const setSidebarOpen = useCallback((open: boolean) => {\n setSidebarOpenState(open);\n }, []);\n\n const toggleSidebar = useCallback(() => {\n setSidebarOpenState((prev) => !prev);\n }, []);\n\n const closeSidebar = useCallback(() => {\n setSidebarOpenState(false);\n }, []);\n\n return {\n sidebarOpen,\n setSidebarOpen,\n toggleSidebar,\n closeSidebar,\n };\n};\n\nexport default useAction;\n","/**\n * 布局提供者:提供侧栏开关与显示/隐藏模式上下文。\n * Layout provider: provides sidebar state and show/hide layout mode context.\n */\nimport type { LayoutProviderProps } from \"../types\";\n\nimport { memo } from \"react\";\n\nimport useAction from \"../hooks/useAction\";\nimport { LayoutContext } from \"../hooks/useLayout\";\nimport useSet from \"../hooks/useSet\";\nimport { DEFAULT_LAYOUT_MODE } from \"../types\";\n\nconst LayoutProvider = memo(({ children, defaultLayoutMode = DEFAULT_LAYOUT_MODE }: LayoutProviderProps) => {\n const { sidebarOpen, setSidebarOpen, toggleSidebar, closeSidebar } = useAction();\n const { layoutMode, setLayoutMode } = useSet({ defaultLayoutMode, sidebarOpen });\n\n return (\n <LayoutContext.Provider\n value={{\n sidebarOpen,\n layoutMode,\n setSidebarOpen,\n toggleSidebar,\n closeSidebar,\n setLayoutMode,\n }}\n >\n {children}\n </LayoutContext.Provider>\n );\n});\n\nLayoutProvider.displayName = \"LayoutProvider\";\nexport default LayoutProvider;\n"],"mappings":"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"}
package/dist/layouts.d.ts CHANGED
@@ -1,209 +1 @@
1
- import { Context } from 'react';
2
- import { JSX } from 'react/jsx-runtime';
3
- import { MemoExoticComponent } from 'react';
4
- import { ReactNode } from 'react';
5
- import { SidebarProps as SidebarProps_2 } from 'react-pro-sidebar';
6
-
7
- /** 与 NFX-Identity/console 一致:仪表盘背景由用户偏好(可外部传入或从 profile 解析) */
8
- export declare const Background: MemoExoticComponent<({ children, background }: BackgroundProps) => JSX.Element>;
9
-
10
- declare interface BackgroundProps {
11
- children: ReactNode;
12
- /** 可选:外部传入的偏好,有则优先使用;否则从 profile.preference 解析。Optional: preference from parent; otherwise parsed from profile. */
13
- background?: DashboardBackgroundEnum | null;
14
- }
15
-
16
- /** 仪表盘背景枚举。Dashboard background enum. */
17
- declare enum DashboardBackgroundEnum {
18
- NONE = "none",
19
- WAVES = "waves",
20
- SQUARES = "squares",
21
- LETTER_GLITCH = "letterGlitch",
22
- PIXEL_BLAST = "pixelBlast"
23
- }
24
-
25
- export declare const DEFAULT_LAYOUT_MODE = LayoutModeEnum.SHOW;
26
-
27
- /** 通用 Footer:只负责布局与样式,内容由外部传入。 */
28
- export declare const Footer: MemoExoticComponent<({ children, className }: FooterProps) => JSX.Element>;
29
-
30
- /** Footer props. */
31
- export declare interface FooterProps {
32
- /** 页脚内容由使用方传入。Footer content passed from parent. */
33
- children?: ReactNode;
34
- className?: string;
35
- }
36
-
37
- export declare function getLayoutStorage(): Nilable<string>;
38
-
39
- /** 通用 Header:只负责布局左右两栏,内容全部由外部传入,内部不获取数据。Generic header: layout only; all content from props. */
40
- export declare const Header: MemoExoticComponent<({ leftContent, rightContent }: HeaderProps) => JSX.Element>;
41
-
42
- /** Header props. */
43
- export declare interface HeaderProps {
44
- /** 左侧内容(如 Logo、SlideDownSwitcher 等),由使用方传入。Left slot; passed from parent. */
45
- leftContent?: ReactNode;
46
- /** 右侧内容(如语言切换、用户菜单等),由使用方传入。Right slot; passed from parent. */
47
- rightContent?: ReactNode;
48
- }
49
-
50
- export declare const LAYOUT_MODE_VALUES: LayoutModeEnum[];
51
-
52
- export declare const LAYOUT_STORAGE_KEY = "layout-storage";
53
-
54
- export declare const LayoutContext: Context<LayoutContextType | undefined>;
55
-
56
- /** useLayout 返回值类型。Return type of useLayout. */
57
- export declare interface LayoutContextType {
58
- /** 侧栏是否展开。Whether sidebar is open. */
59
- sidebarOpen: boolean;
60
- /** 当前布局模式(显示/隐藏)。Current layout mode (show/hide). */
61
- layoutMode: LayoutModeEnum;
62
- setSidebarOpen: (open: boolean) => void;
63
- toggleSidebar: () => void;
64
- closeSidebar: () => void;
65
- setLayoutMode: (mode: LayoutModeEnum) => void;
66
- }
67
-
68
- export declare const LayoutFrame: MemoExoticComponent<({ children, headerLeft, headerRight, footerContent, sidebarItems, sidebarCurrentPathname, onSidebarNavigate, sidebarLogoutLabel, onSidebarLogout, bottomLogoutButton, }: LayoutFrameProps) => JSX.Element>;
69
-
70
- /** LayoutFrame props. */
71
- export declare interface LayoutFrameProps {
72
- children: ReactNode;
73
- /** 可选:Header 左侧内容(如 Logo、SlideDownSwitcher),使用方传入。Optional: header left slot. */
74
- headerLeft?: ReactNode;
75
- /** 可选:Header 右侧内容(如语言、用户菜单),使用方传入。Optional: header right slot. */
76
- headerRight?: ReactNode;
77
- /** 可选:Footer 内容(children),使用方传入。Optional: footer content. */
78
- footerContent?: ReactNode;
79
- /** 可选:侧栏菜单项。Optional: sidebar menu items. */
80
- sidebarItems?: SidebarMenuItem[];
81
- /** 可选:当前路径,用于高亮。传 useLocation().pathname。Optional: current pathname for active state. */
82
- sidebarCurrentPathname?: string;
83
- /** 可选:点击菜单项时调用。Optional: called when a sidebar item is clicked. */
84
- onSidebarNavigate?: (path: string) => void;
85
- /** 可选:侧栏底部登出按钮文案。Optional: logout button label. */
86
- sidebarLogoutLabel?: string;
87
- /** 可选:侧栏登出回调。Optional: logout handler. */
88
- onSidebarLogout?: () => void;
89
- /** 可选:侧栏底部登出按钮。Optional: bottom logout button. */
90
- bottomLogoutButton?: ReactNode;
91
- }
92
-
93
- /**
94
- * 布局模式枚举与常量。Layout mode enum and constants.
95
- */
96
- export declare enum LayoutModeEnum {
97
- SHOW = "show",
98
- HIDE = "hide"
99
- }
100
-
101
- export declare const LayoutProvider: MemoExoticComponent<({ children, defaultLayoutMode }: LayoutProviderProps) => JSX.Element>;
102
-
103
- /** 布局 Provider 的 props。LayoutProvider props. */
104
- export declare interface LayoutProviderProps {
105
- /** 子节点。Children. */
106
- children: ReactNode;
107
- /** 默认布局模式(显示/隐藏侧栏)。Default layout mode (show/hide sidebar). */
108
- defaultLayoutMode?: LayoutModeEnum;
109
- }
110
-
111
- /** 布局切换器 props。LayoutSwitcher props. */
112
- export declare interface LayoutSwitcherProps {
113
- /** 样式状态。Visual status. */
114
- status?: "primary" | "default";
115
- /** 显示模式标签(未传 getLayoutDisplayName 且无内置翻译时使用)。Show mode label. */
116
- showLabel?: string;
117
- /** 隐藏模式标签(未传 getLayoutDisplayName 且无内置翻译时使用)。Hide mode label. */
118
- hideLabel?: string;
119
- /** 根据布局模式返回展示名;未传则使用 showLabel / hideLabel。Display name for layout mode; default uses showLabel/hideLabel. */
120
- getLayoutDisplayName?: (mode: LayoutModeEnum) => string;
121
- /** 处理布局模式改变。Handle layout mode change. */
122
- handleChangeLayoutMode?: (mode: LayoutModeEnum) => void;
123
- }
124
-
125
- export declare const MainWrapper: MemoExoticComponent<({ children, headerLeft, headerRight, footerContent }: MainWrapperProps) => JSX.Element>;
126
-
127
- /** MainWrapper props. */
128
- export declare interface MainWrapperProps {
129
- children: (headerHeight: number, footerHeight: number) => ReactNode;
130
- headerLeft?: ReactNode;
131
- headerRight?: ReactNode;
132
- footerContent?: ReactNode;
133
- }
134
-
135
- /**
136
- * 可为 null 或 undefined。Nilable: T | null | undefined.
137
- * @example Nilable<boolean> => boolean | null | undefined
138
- */
139
- declare type Nilable<T> = T | null | undefined;
140
-
141
- export declare function removeLayoutStorage(): void;
142
-
143
- export declare function setLayoutStorage(value: string): void;
144
-
145
- export declare const Sidebar: MemoExoticComponent<({ children, collapsed, toggled, onBackdropClick, breakPoint, className, items, currentPathname, onNavigate, logoutLabel, handleLogout, bottomLogoutButton, }: SidebarProps) => JSX.Element>;
146
-
147
- /** 侧栏菜单项。Sidebar menu item. */
148
- export declare interface SidebarMenuItem {
149
- label: string;
150
- path: string;
151
- icon: ReactNode;
152
- /** Sub-items for SubMenu. Omit for a leaf item. */
153
- children?: SidebarMenuItem[];
154
- }
155
-
156
- /** Sidebar props(扩展 react-pro-sidebar). */
157
- export declare interface SidebarProps extends SidebarProps_2 {
158
- children?: ReactNode;
159
- collapsed?: boolean;
160
- toggled?: boolean;
161
- onBackdropClick?: () => void;
162
- className?: string;
163
- /** Menu items. Rendered when no children. */
164
- items?: SidebarMenuItem[];
165
- /** Current pathname for active state. Pass from useLocation().pathname. */
166
- currentPathname?: string;
167
- /** Called when a menu item is clicked. Parent should navigate to path. */
168
- onNavigate?: (path: string) => void;
169
- /** Logout label. */
170
- logoutLabel?: string;
171
- /** Handle logout. */
172
- handleLogout?: () => void;
173
- /** Bottom Logout Button. */
174
- bottomLogoutButton?: ReactNode;
175
- }
176
-
177
- export declare const SideHideLayout: MemoExoticComponent<({ children, headerHeight, footerHeight, sidebarItems, sidebarCurrentPathname, onSidebarNavigate, sidebarLogoutLabel, onSidebarLogout, }: SideHideLayoutProps) => JSX.Element>;
178
-
179
- /** SideHideLayout props. */
180
- export declare interface SideHideLayoutProps {
181
- children: ReactNode;
182
- headerHeight: number;
183
- footerHeight: number;
184
- sidebarItems?: SidebarMenuItem[];
185
- sidebarCurrentPathname?: string;
186
- onSidebarNavigate?: (path: string) => void;
187
- sidebarLogoutLabel?: string;
188
- onSidebarLogout?: () => void;
189
- bottomLogoutButton?: ReactNode;
190
- }
191
-
192
- export declare const SideShowLayout: MemoExoticComponent<({ children, headerHeight, footerHeight, sidebarItems, sidebarCurrentPathname, onSidebarNavigate, sidebarLogoutLabel, onSidebarLogout, }: SideShowLayoutProps) => JSX.Element>;
193
-
194
- /** SideShowLayout props. */
195
- export declare interface SideShowLayoutProps {
196
- children: ReactNode;
197
- headerHeight: number;
198
- footerHeight: number;
199
- sidebarItems?: SidebarMenuItem[];
200
- sidebarCurrentPathname?: string;
201
- onSidebarNavigate?: (path: string) => void;
202
- sidebarLogoutLabel?: string;
203
- onSidebarLogout?: () => void;
204
- bottomLogoutButton?: ReactNode;
205
- }
206
-
207
- export declare const useLayout: () => LayoutContextType;
208
-
209
1
  export { }