nfx-ui 0.7.4 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/dist/src/apis/index.d.ts +2 -0
  2. package/dist/src/apis/ip.d.ts +4 -0
  3. package/dist/src/constants/caches.d.ts +5 -0
  4. package/dist/src/constants/enums.d.ts +18 -0
  5. package/dist/src/constants/index.d.ts +9 -0
  6. package/dist/src/constants/query.itemkeys.d.ts +31 -0
  7. package/dist/src/constants/query.listkeys.d.ts +30 -0
  8. package/dist/src/constants/querykeys.d.ts +42 -0
  9. package/dist/src/designs/animations/BounceLoading/index.d.ts +7 -0
  10. package/dist/src/designs/animations/ECGLoading/index.d.ts +6 -0
  11. package/dist/src/designs/animations/LetterGlitch/index.d.ts +12 -0
  12. package/dist/src/designs/animations/PixelBlast/index.d.ts +28 -0
  13. package/dist/src/designs/animations/Squares/index.d.ts +13 -0
  14. package/dist/src/designs/animations/TruckLoading/index.d.ts +6 -0
  15. package/dist/src/designs/animations/Waves/index.d.ts +18 -0
  16. package/dist/src/designs/animations/index.d.ts +6 -0
  17. package/dist/src/designs/components/Button/index.d.ts +20 -0
  18. package/dist/src/designs/components/Dropdown/index.d.ts +24 -0
  19. package/dist/src/designs/components/Icon/index.d.ts +9 -0
  20. package/dist/src/designs/components/Input/index.d.ts +23 -0
  21. package/dist/src/designs/components/KeyValueEditor/index.d.ts +30 -0
  22. package/dist/src/designs/components/LayoutSwitcher/index.d.ts +3 -0
  23. package/dist/src/designs/components/SearchInput/index.d.ts +12 -0
  24. package/dist/src/designs/components/ShowFilter/index.d.ts +28 -0
  25. package/dist/src/designs/components/SlideDownSwitcher/index.d.ts +16 -0
  26. package/dist/src/designs/components/Slider/index.d.ts +26 -0
  27. package/dist/src/designs/components/Suspense/SuspenseErrorBoundary.d.ts +21 -0
  28. package/dist/src/designs/components/Suspense/index.d.ts +47 -0
  29. package/dist/src/designs/components/Textarea/index.d.ts +21 -0
  30. package/dist/src/designs/components/ThemeSwitcher/index.d.ts +3 -0
  31. package/dist/src/designs/components/VirtualList/index.d.ts +41 -0
  32. package/dist/src/designs/components/VirtualWindowList/index.d.ts +41 -0
  33. package/dist/src/designs/components/index.d.ts +33 -0
  34. package/dist/src/designs/layouts/components/Background/index.d.ts +11 -0
  35. package/dist/src/designs/layouts/components/Footer/index.d.ts +5 -0
  36. package/dist/src/designs/layouts/components/Header/index.d.ts +4 -0
  37. package/dist/src/designs/layouts/components/LayoutFrame/index.d.ts +3 -0
  38. package/dist/src/designs/layouts/components/MainWrapper/index.d.ts +3 -0
  39. package/dist/src/designs/layouts/components/SideHideLayout/index.d.ts +3 -0
  40. package/dist/src/designs/layouts/components/SideShowLayout/index.d.ts +3 -0
  41. package/dist/src/designs/layouts/components/Sidebar/index.d.ts +3 -0
  42. package/dist/src/designs/layouts/components/index.d.ts +8 -0
  43. package/dist/src/designs/layouts/hooks/index.d.ts +3 -0
  44. package/dist/src/designs/layouts/hooks/useAction.d.ts +7 -0
  45. package/dist/src/designs/layouts/hooks/useLayout.d.ts +5 -0
  46. package/dist/src/designs/layouts/hooks/useSet.d.ts +10 -0
  47. package/dist/src/designs/layouts/index.d.ts +8 -0
  48. package/dist/src/designs/layouts/providers/index.d.ts +3 -0
  49. package/dist/src/designs/layouts/types/components.d.ts +117 -0
  50. package/dist/src/designs/layouts/types/context.d.ts +12 -0
  51. package/dist/src/designs/layouts/types/index.d.ts +6 -0
  52. package/dist/src/designs/layouts/types/layout.d.ts +11 -0
  53. package/dist/src/designs/layouts/utils/index.d.ts +4 -0
  54. package/dist/src/designs/layouts/utils/layoutStorage.d.ts +4 -0
  55. package/dist/src/events/EventEmitter.d.ts +48 -0
  56. package/dist/src/events/index.d.ts +5 -0
  57. package/dist/src/hooks/index.d.ts +4 -0
  58. package/dist/src/hooks/makeCursorFetchFunction.d.ts +84 -0
  59. package/dist/src/hooks/makeUnifiedInfiniteQuery.d.ts +124 -0
  60. package/dist/src/hooks/makeUnifiedQuery.d.ts +19 -0
  61. package/dist/src/hooks/type.d.ts +36 -0
  62. package/dist/src/icons/index.d.ts +1 -0
  63. package/dist/src/icons/lucide.d.ts +2 -0
  64. package/dist/src/languages/hooks/index.d.ts +8 -0
  65. package/dist/src/languages/hooks/useLanguageLabel.d.ts +6 -0
  66. package/dist/src/languages/hooks/useLayoutLabel.d.ts +6 -0
  67. package/dist/src/languages/hooks/usePreferenceLabel.d.ts +6 -0
  68. package/dist/src/languages/hooks/useThemeLabel.d.ts +6 -0
  69. package/dist/src/languages/index.d.ts +11 -0
  70. package/dist/src/languages/languages/i18n.d.ts +8 -0
  71. package/dist/src/languages/languages/i18nResources.d.ts +13 -0
  72. package/dist/src/languages/languages/index.d.ts +2 -0
  73. package/dist/src/languages/providers/index.d.ts +3 -0
  74. package/dist/src/languages/resources/index.d.ts +8 -0
  75. package/dist/src/languages/types/components.d.ts +23 -0
  76. package/dist/src/languages/types/i18n.d.ts +28 -0
  77. package/dist/src/languages/types/index.d.ts +6 -0
  78. package/dist/src/languages/types/language.d.ts +13 -0
  79. package/dist/src/languages/utils/getLocalLanguage.d.ts +2 -0
  80. package/dist/src/languages/utils/index.d.ts +5 -0
  81. package/dist/src/languages/utils/languageStorage.d.ts +5 -0
  82. package/dist/src/navigations/index.d.ts +1 -0
  83. package/dist/src/navigations/navigation.d.ts +50 -0
  84. package/dist/src/preference/constants.d.ts +12 -0
  85. package/dist/src/preference/index.d.ts +35 -0
  86. package/dist/src/services/imageService.d.ts +6 -0
  87. package/dist/src/services/index.d.ts +1 -0
  88. package/dist/src/stores/index.d.ts +1 -0
  89. package/dist/src/stores/makeStore.d.ts +92 -0
  90. package/dist/src/themes/hooks/index.d.ts +2 -0
  91. package/dist/src/themes/hooks/useTheme.d.ts +5 -0
  92. package/dist/src/themes/hooks/useThemeVariables.d.ts +10 -0
  93. package/dist/src/themes/index.d.ts +8 -0
  94. package/dist/src/themes/providers/index.d.ts +3 -0
  95. package/dist/src/themes/themes/bases/android.d.ts +4 -0
  96. package/dist/src/themes/themes/bases/default.d.ts +5 -0
  97. package/dist/src/themes/themes/bases/index.d.ts +7 -0
  98. package/dist/src/themes/themes/bases/ios.d.ts +4 -0
  99. package/dist/src/themes/themes/bases/linux.d.ts +4 -0
  100. package/dist/src/themes/themes/bases/windows.d.ts +4 -0
  101. package/dist/src/themes/themes/colors/coffee.d.ts +7 -0
  102. package/dist/src/themes/themes/colors/corporate.d.ts +7 -0
  103. package/dist/src/themes/themes/colors/cosmic.d.ts +7 -0
  104. package/dist/src/themes/themes/colors/dark.d.ts +7 -0
  105. package/dist/src/themes/themes/colors/default.d.ts +7 -0
  106. package/dist/src/themes/themes/colors/forest.d.ts +7 -0
  107. package/dist/src/themes/themes/colors/index.d.ts +12 -0
  108. package/dist/src/themes/themes/colors/light.d.ts +7 -0
  109. package/dist/src/themes/themes/colors/wheat.d.ts +8 -0
  110. package/dist/src/themes/themes/colors/wine.d.ts +7 -0
  111. package/dist/src/themes/themes/index.d.ts +2 -0
  112. package/dist/src/themes/types/components.d.ts +20 -0
  113. package/dist/src/themes/types/context.d.ts +16 -0
  114. package/dist/src/themes/types/index.d.ts +6 -0
  115. package/dist/src/themes/types/theme.d.ts +209 -0
  116. package/dist/src/themes/utils/index.d.ts +4 -0
  117. package/dist/src/themes/utils/themeStorage.d.ts +7 -0
  118. package/dist/src/types/api.d.ts +75 -0
  119. package/dist/src/types/index.d.ts +2 -0
  120. package/dist/src/types/utils.d.ts +83 -0
  121. package/dist/src/utils/address.d.ts +7 -0
  122. package/dist/src/utils/apiError.d.ts +16 -0
  123. package/dist/src/utils/array.d.ts +21 -0
  124. package/dist/src/utils/colors.d.ts +37 -0
  125. package/dist/src/utils/email.d.ts +7 -0
  126. package/dist/src/utils/form.d.ts +14 -0
  127. package/dist/src/utils/index.d.ts +23 -0
  128. package/dist/src/utils/lstorage.d.ts +4 -0
  129. package/dist/src/utils/object.d.ts +10 -0
  130. package/dist/src/utils/polling.d.ts +12 -0
  131. package/dist/src/utils/price.d.ts +28 -0
  132. package/dist/src/utils/promise.d.ts +17 -0
  133. package/dist/src/utils/result.d.ts +21 -0
  134. package/dist/src/utils/retry.d.ts +15 -0
  135. package/dist/src/utils/safe.d.ts +69 -0
  136. package/dist/src/utils/singleton.d.ts +21 -0
  137. package/dist/src/utils/suspense.d.ts +10 -0
  138. package/dist/src/utils/time.d.ts +49 -0
  139. package/dist/src/utils/types.d.ts +10 -0
  140. package/package.json +19 -22
  141. package/dist/animations.d.ts +0 -1
  142. package/dist/apis.d.ts +0 -1
  143. package/dist/components.d.ts +0 -1
  144. package/dist/constants.d.ts +0 -1
  145. package/dist/events.d.ts +0 -1
  146. package/dist/hooks.d.ts +0 -1
  147. package/dist/icons.d.ts +0 -1
  148. package/dist/languages.d.ts +0 -1
  149. package/dist/layouts.d.ts +0 -1
  150. package/dist/navigations.d.ts +0 -1
  151. package/dist/pixel-blast.d.ts +0 -1
  152. package/dist/preference.d.ts +0 -1
  153. package/dist/services.d.ts +0 -1
  154. package/dist/stores.d.ts +0 -1
  155. package/dist/themes.d.ts +0 -1
  156. package/dist/types.d.ts +0 -1
  157. package/dist/utils.d.ts +0 -1
@@ -0,0 +1,41 @@
1
+ import { VirtualizerOptions } from '@tanstack/react-virtual';
2
+ import { ReactNode } from 'react';
3
+ export interface VirtualWindowListProps<T> extends Partial<Omit<VirtualizerOptions<Window, Element>, "count" | "getScrollElement" | "observeElementRect" | "observeElementOffset" | "scrollToFn" | "estimateSize" | "getItemKey">> {
4
+ /** 数据列表。Data array. */
5
+ data: T[];
6
+ /** 是否有下一页。Has next page. */
7
+ hasNextPage?: boolean;
8
+ /** 是否正在拉取下一页。Is fetching next page. */
9
+ isFetchingNextPage?: boolean;
10
+ /** 拉取下一页。Fetch next page. */
11
+ fetchNextPage?: () => void;
12
+ /** 单项渲染。Render item. */
13
+ renderItem: (item: T, index: number) => ReactNode;
14
+ /** 单项高度估计。Estimate item size. */
15
+ estimateSize?: number | ((index: number) => number);
16
+ /** 列表高度。List height. */
17
+ height?: string | number;
18
+ /** 单项 key。Get item key. */
19
+ getItemKey: (item: T, index: number) => string | number;
20
+ /** 空状态自定义节点。Empty state node. */
21
+ emptyState?: ReactNode;
22
+ /** 加载更多指示器。Loading indicator node. */
23
+ loadingIndicator?: ReactNode;
24
+ /** 列表底指示器。End of list indicator node. */
25
+ endOfListIndicator?: ReactNode;
26
+ /** 空状态文案(未提供 emptyState 时)。Empty text. */
27
+ emptyText?: string;
28
+ /** 加载更多文案。Loading more text. */
29
+ loadingMoreText?: string;
30
+ /** 列表底文案。End of list text. */
31
+ endOfListText?: string;
32
+ /** 列表项容器 className。Flex container class. */
33
+ flexClass?: string;
34
+ /** 外层容器 className。Outer class. */
35
+ outerClass?: string;
36
+ /** 内层容器 className。Inner class. */
37
+ innerClass?: string;
38
+ }
39
+ declare function VirtualWindowListComponent<T>({ data, hasNextPage, isFetchingNextPage, fetchNextPage, renderItem, estimateSize, overscan, height, getItemKey, emptyState, loadingIndicator, endOfListIndicator, emptyText, loadingMoreText, endOfListText, flexClass, outerClass, innerClass, ...virtualizerOptions }: VirtualWindowListProps<T>): import("react/jsx-runtime").JSX.Element;
40
+ declare const VirtualWindowList: typeof VirtualWindowListComponent;
41
+ export default VirtualWindowList;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 组件统一入口:所有组件及类型在底部集中导出。Components barrel; all components and types exported at bottom.
3
+ */
4
+ export { default as Button } from './Button';
5
+ export type { ButtonProps } from './Button';
6
+ export { default as Dropdown } from './Dropdown';
7
+ export type { DropdownOption, DropdownProps } from './Dropdown';
8
+ export { default as Icon } from './Icon';
9
+ export type { IconName, IconProps } from './Icon';
10
+ export { default as Input } from './Input';
11
+ export type { InputProps } from './Input';
12
+ export { default as KeyValueEditor } from './KeyValueEditor';
13
+ export type { KeyValueEditorProps, KeyValuePair } from './KeyValueEditor';
14
+ export { default as SearchInput } from './SearchInput';
15
+ export type { SearchInputProps } from './SearchInput';
16
+ export { default as ShowFilter } from './ShowFilter';
17
+ export type { ShowFilterProps, ShowFilterValue } from './ShowFilter';
18
+ export { default as SlideDownSwitcher } from './SlideDownSwitcher';
19
+ export type { SlideDownSwitcherProps } from './SlideDownSwitcher';
20
+ export { default as ThemeSwitcher } from './ThemeSwitcher';
21
+ export type { ThemeSwitcherProps } from '../../../themes/types';
22
+ export { default as LayoutSwitcher } from './LayoutSwitcher';
23
+ export type { LayoutSwitcherProps } from '../../../designs/layouts/types';
24
+ export { default as Slider } from './Slider';
25
+ export type { SliderProps } from './Slider';
26
+ export { default as Suspense } from './Suspense';
27
+ export type { SuspenseProps } from './Suspense';
28
+ export { default as Textarea } from './Textarea';
29
+ export type { TextareaProps } from './Textarea';
30
+ export { default as VirtualList } from './VirtualList';
31
+ export type { VirtualListProps } from './VirtualList';
32
+ export { default as VirtualWindowList } from './VirtualWindowList';
33
+ export type { VirtualWindowListProps } from './VirtualWindowList';
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from 'react';
2
+ import { DashboardBackgroundEnum } from '../../../../../preference';
3
+ interface BackgroundProps {
4
+ children: ReactNode;
5
+ /** 可选:外部传入的偏好,有则优先使用;否则从 profile.preference 解析。Optional: preference from parent; otherwise parsed from profile. */
6
+ background?: DashboardBackgroundEnum | null;
7
+ }
8
+ /** 与 NFX-Identity/console 一致:仪表盘背景由用户偏好(可外部传入或从 profile 解析) */
9
+ declare const Background: import('react').MemoExoticComponent<({ children, background }: BackgroundProps) => import("react/jsx-runtime").JSX.Element>;
10
+ export default Background;
11
+ export type { BackgroundProps };
@@ -0,0 +1,5 @@
1
+ import { FooterProps } from '../../types';
2
+ export declare const DefaultFooterContent: import('react').MemoExoticComponent<() => import("react/jsx-runtime").JSX.Element>;
3
+ /** 通用 Footer:只负责布局与样式,内容由外部传入。 */
4
+ declare const Footer: import('react').MemoExoticComponent<({ children, className }: FooterProps) => import("react/jsx-runtime").JSX.Element>;
5
+ export default Footer;
@@ -0,0 +1,4 @@
1
+ import { HeaderProps } from '../../types';
2
+ /** 通用 Header:只负责布局左右两栏,内容全部由外部传入,内部不获取数据。Generic header: layout only; all content from props. */
3
+ declare const Header: import('react').MemoExoticComponent<({ leftContent, rightContent }: HeaderProps) => import("react/jsx-runtime").JSX.Element>;
4
+ export default Header;
@@ -0,0 +1,3 @@
1
+ import { LayoutFrameProps } from '../../types';
2
+ export declare const LayoutFrame: import('react').MemoExoticComponent<({ children, headerLeft, headerRight, footerContent, sidebarItems, sidebarCurrentPathname, onSidebarNavigate, sidebarLogoutLabel, onSidebarLogout, bottomLogoutButton, }: LayoutFrameProps) => import("react/jsx-runtime").JSX.Element>;
3
+ export default LayoutFrame;
@@ -0,0 +1,3 @@
1
+ import { MainWrapperProps } from '../../types';
2
+ declare const MainWrapper: import('react').MemoExoticComponent<({ children, headerLeft, headerRight, footerContent }: MainWrapperProps) => import("react/jsx-runtime").JSX.Element>;
3
+ export default MainWrapper;
@@ -0,0 +1,3 @@
1
+ import { SideHideLayoutProps } from '../../types';
2
+ declare const SideHideLayout: import('react').MemoExoticComponent<({ children, headerHeight, footerHeight, sidebarItems, sidebarCurrentPathname, onSidebarNavigate, sidebarLogoutLabel, onSidebarLogout, }: SideHideLayoutProps) => import("react/jsx-runtime").JSX.Element>;
3
+ export default SideHideLayout;
@@ -0,0 +1,3 @@
1
+ import { SideShowLayoutProps } from '../../types';
2
+ declare const SideShowLayout: import('react').MemoExoticComponent<({ children, headerHeight, footerHeight, sidebarItems, sidebarCurrentPathname, onSidebarNavigate, sidebarLogoutLabel, onSidebarLogout, }: SideShowLayoutProps) => import("react/jsx-runtime").JSX.Element>;
3
+ export default SideShowLayout;
@@ -0,0 +1,3 @@
1
+ import { SidebarProps } from '../../types';
2
+ declare const Sidebar: import('react').MemoExoticComponent<({ children, collapsed, toggled, onBackdropClick, breakPoint, className, items, currentPathname, onNavigate, logoutLabel, handleLogout, bottomLogoutButton, }: SidebarProps) => import("react/jsx-runtime").JSX.Element>;
3
+ export default Sidebar;
@@ -0,0 +1,8 @@
1
+ export { default as Sidebar } from './Sidebar';
2
+ export { default as MainWrapper } from './MainWrapper';
3
+ export { default as SideHideLayout } from './SideHideLayout';
4
+ export { default as SideShowLayout } from './SideShowLayout';
5
+ export { default as Footer } from './Footer';
6
+ export { default as Header } from './Header';
7
+ export { default as Background } from './Background';
8
+ export { default as LayoutFrame } from './LayoutFrame';
@@ -0,0 +1,3 @@
1
+ export * from './useLayout';
2
+ export * from './useSet';
3
+ export * from './useAction';
@@ -0,0 +1,7 @@
1
+ declare const useAction: () => {
2
+ sidebarOpen: boolean;
3
+ setSidebarOpen: (open: boolean) => void;
4
+ toggleSidebar: () => void;
5
+ closeSidebar: () => void;
6
+ };
7
+ export default useAction;
@@ -0,0 +1,5 @@
1
+ import { LayoutContextType } from '../types';
2
+ declare const LayoutContext: import('react').Context<LayoutContextType | undefined>;
3
+ declare const useLayout: () => LayoutContextType;
4
+ export default useLayout;
5
+ export { LayoutContext, useLayout };
@@ -0,0 +1,10 @@
1
+ import { LayoutModeEnum } from '../types';
2
+ interface UseSetProps {
3
+ defaultLayoutMode: LayoutModeEnum;
4
+ sidebarOpen: boolean;
5
+ }
6
+ declare const useSet: ({ defaultLayoutMode, sidebarOpen }: UseSetProps) => {
7
+ layoutMode: LayoutModeEnum;
8
+ setLayoutMode: (mode: LayoutModeEnum) => void;
9
+ };
10
+ export default useSet;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 布局模块统一导出。Layouts module barrel exports.
3
+ */
4
+ export * from './types';
5
+ export * from './utils';
6
+ export * from './components';
7
+ export * from './hooks';
8
+ export { default as LayoutProvider } from './providers';
@@ -0,0 +1,3 @@
1
+ import { LayoutProviderProps } from '../types';
2
+ declare const LayoutProvider: import('react').MemoExoticComponent<({ children, defaultLayoutMode }: LayoutProviderProps) => import("react/jsx-runtime").JSX.Element>;
3
+ export default LayoutProvider;
@@ -0,0 +1,117 @@
1
+ import { ReactNode } from 'react';
2
+ import { SidebarProps as ProSidebarProps } from 'react-pro-sidebar';
3
+ import { LayoutModeEnum } from './layout';
4
+ /** 侧栏菜单项。Sidebar menu item. */
5
+ export interface SidebarMenuItem {
6
+ label: string;
7
+ path: string;
8
+ icon: ReactNode;
9
+ /** Sub-items for SubMenu. Omit for a leaf item. */
10
+ children?: SidebarMenuItem[];
11
+ }
12
+ /** 布局 Provider 的 props。LayoutProvider props. */
13
+ export interface LayoutProviderProps {
14
+ /** 子节点。Children. */
15
+ children: ReactNode;
16
+ /** 默认布局模式(显示/隐藏侧栏)。Default layout mode (show/hide sidebar). */
17
+ defaultLayoutMode?: LayoutModeEnum;
18
+ }
19
+ /** 布局切换器 props。LayoutSwitcher props. */
20
+ export interface LayoutSwitcherProps {
21
+ /** 样式状态。Visual status. */
22
+ status?: "primary" | "default";
23
+ /** 显示模式标签(未传 getLayoutDisplayName 且无内置翻译时使用)。Show mode label. */
24
+ showLabel?: string;
25
+ /** 隐藏模式标签(未传 getLayoutDisplayName 且无内置翻译时使用)。Hide mode label. */
26
+ hideLabel?: string;
27
+ /** 根据布局模式返回展示名;未传则使用 showLabel / hideLabel。Display name for layout mode; default uses showLabel/hideLabel. */
28
+ getLayoutDisplayName?: (mode: LayoutModeEnum) => string;
29
+ /** 处理布局模式改变。Handle layout mode change. */
30
+ handleChangeLayoutMode?: (mode: LayoutModeEnum) => void;
31
+ }
32
+ /** LayoutFrame props. */
33
+ export interface LayoutFrameProps {
34
+ children: ReactNode;
35
+ /** 可选:Header 左侧内容(如 Logo、SlideDownSwitcher),使用方传入。Optional: header left slot. */
36
+ headerLeft?: ReactNode;
37
+ /** 可选:Header 右侧内容(如语言、用户菜单),使用方传入。Optional: header right slot. */
38
+ headerRight?: ReactNode;
39
+ /** 可选:Footer 内容(children),使用方传入。Optional: footer content. */
40
+ footerContent?: ReactNode;
41
+ /** 可选:侧栏菜单项。Optional: sidebar menu items. */
42
+ sidebarItems?: SidebarMenuItem[];
43
+ /** 可选:当前路径,用于高亮。传 useLocation().pathname。Optional: current pathname for active state. */
44
+ sidebarCurrentPathname?: string;
45
+ /** 可选:点击菜单项时调用。Optional: called when a sidebar item is clicked. */
46
+ onSidebarNavigate?: (path: string) => void;
47
+ /** 可选:侧栏底部登出按钮文案。Optional: logout button label. */
48
+ sidebarLogoutLabel?: string;
49
+ /** 可选:侧栏登出回调。Optional: logout handler. */
50
+ onSidebarLogout?: () => void;
51
+ /** 可选:侧栏底部登出按钮。Optional: bottom logout button. */
52
+ bottomLogoutButton?: ReactNode;
53
+ }
54
+ /** Sidebar props(扩展 react-pro-sidebar). */
55
+ export interface SidebarProps extends ProSidebarProps {
56
+ children?: ReactNode;
57
+ collapsed?: boolean;
58
+ toggled?: boolean;
59
+ onBackdropClick?: () => void;
60
+ className?: string;
61
+ /** Menu items. Rendered when no children. */
62
+ items?: SidebarMenuItem[];
63
+ /** Current pathname for active state. Pass from useLocation().pathname. */
64
+ currentPathname?: string;
65
+ /** Called when a menu item is clicked. Parent should navigate to path. */
66
+ onNavigate?: (path: string) => void;
67
+ /** Logout label. */
68
+ logoutLabel?: string;
69
+ /** Handle logout. */
70
+ handleLogout?: () => void;
71
+ /** Bottom Logout Button. */
72
+ bottomLogoutButton?: ReactNode;
73
+ }
74
+ /** MainWrapper props. */
75
+ export interface MainWrapperProps {
76
+ children: (headerHeight: number, footerHeight: number) => ReactNode;
77
+ headerLeft?: ReactNode;
78
+ headerRight?: ReactNode;
79
+ footerContent?: ReactNode;
80
+ }
81
+ /** SideHideLayout props. */
82
+ export interface SideHideLayoutProps {
83
+ children: ReactNode;
84
+ headerHeight: number;
85
+ footerHeight: number;
86
+ sidebarItems?: SidebarMenuItem[];
87
+ sidebarCurrentPathname?: string;
88
+ onSidebarNavigate?: (path: string) => void;
89
+ sidebarLogoutLabel?: string;
90
+ onSidebarLogout?: () => void;
91
+ bottomLogoutButton?: ReactNode;
92
+ }
93
+ /** SideShowLayout props. */
94
+ export interface SideShowLayoutProps {
95
+ children: ReactNode;
96
+ headerHeight: number;
97
+ footerHeight: number;
98
+ sidebarItems?: SidebarMenuItem[];
99
+ sidebarCurrentPathname?: string;
100
+ onSidebarNavigate?: (path: string) => void;
101
+ sidebarLogoutLabel?: string;
102
+ onSidebarLogout?: () => void;
103
+ bottomLogoutButton?: ReactNode;
104
+ }
105
+ /** Footer props. */
106
+ export interface FooterProps {
107
+ /** 页脚内容由使用方传入。Footer content passed from parent. */
108
+ children?: ReactNode;
109
+ className?: string;
110
+ }
111
+ /** Header props. */
112
+ export interface HeaderProps {
113
+ /** 左侧内容(如 Logo、SlideDownSwitcher 等),由使用方传入。Left slot; passed from parent. */
114
+ leftContent?: ReactNode;
115
+ /** 右侧内容(如语言切换、用户菜单等),由使用方传入。Right slot; passed from parent. */
116
+ rightContent?: ReactNode;
117
+ }
@@ -0,0 +1,12 @@
1
+ import { LayoutModeEnum } from './layout';
2
+ /** useLayout 返回值类型。Return type of useLayout. */
3
+ export interface LayoutContextType {
4
+ /** 侧栏是否展开。Whether sidebar is open. */
5
+ sidebarOpen: boolean;
6
+ /** 当前布局模式(显示/隐藏)。Current layout mode (show/hide). */
7
+ layoutMode: LayoutModeEnum;
8
+ setSidebarOpen: (open: boolean) => void;
9
+ toggleSidebar: () => void;
10
+ closeSidebar: () => void;
11
+ setLayoutMode: (mode: LayoutModeEnum) => void;
12
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 布局模块类型统一导出。All layout module types re-exported.
3
+ */
4
+ export * from './layout';
5
+ export * from './context';
6
+ export * from './components';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 布局模式枚举与常量。Layout mode enum and constants.
3
+ */
4
+ declare enum LayoutModeEnum {
5
+ SHOW = "show",
6
+ HIDE = "hide"
7
+ }
8
+ declare const DEFAULT_LAYOUT_MODE = LayoutModeEnum.SHOW;
9
+ declare const LAYOUT_MODE_VALUES: LayoutModeEnum[];
10
+ declare const LAYOUT_STORAGE_KEY = "layout-storage";
11
+ export { LayoutModeEnum, DEFAULT_LAYOUT_MODE, LAYOUT_MODE_VALUES, LAYOUT_STORAGE_KEY };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * 布局模块工具函数。Layout module utils.
3
+ */
4
+ export { getLayoutStorage, removeLayoutStorage, setLayoutStorage, } from './layoutStorage';
@@ -0,0 +1,4 @@
1
+ import { Nilable } from '../../../../types/utils';
2
+ export declare function getLayoutStorage(): Nilable<string>;
3
+ export declare function setLayoutStorage(value: string): void;
4
+ export declare function removeLayoutStorage(): void;
@@ -0,0 +1,48 @@
1
+ import { Defined } from '../../types';
2
+ /** 回调类型:内部存储与 on/off 默认(unknown)时均用此,任意函数即可,无需 as 断言。 */
3
+ type EventCallback = (...args: any[]) => void;
4
+ /**
5
+ * 将 PayloadMap[K] 规范为参数元组。
6
+ * void→[];unknown(默认)→ [] | [unknown];单类型 T→[T];元组→不变。
7
+ */
8
+ type ToArgs<P> = P extends void ? [] : unknown extends P ? [] | [P] : P extends unknown[] ? P : [P];
9
+ /** 由 defineEvents 返回的「已规范事件名对象」类型;constructor 只接受此类型。 */
10
+ type DefinedEvents<T extends Record<string, string>> = Defined<T, "events">;
11
+ /** 从 events 对象推导出事件名联合类型。Event name union from an events key-value object. */
12
+ type EventNamesOf<T> = T extends Defined<infer O, "events"> ? O[keyof O] : T extends Record<string, string> ? T[keyof T] : never;
13
+ /**
14
+ * 规范创建「一级 key-value」事件名对象:仅允许 key → 字符串 value,禁止嵌套(类型约束)。
15
+ * 返回 DefinedEvents<T>,供 EventEmitter 构造使用。
16
+ * Define events object: one-level key-value (string values), no nested objects (type-only). Returns DefinedEvents<T> for EventEmitter.
17
+ *
18
+ * @param events - 事件名 key-value 对象。Event name key-value object (e.g. { FOO: "DOMAIN:FOO" }).
19
+ * @returns DefinedEvents<E>,仅此类型可传入 EventEmitter 构造。DefinedEvents<E>; only this type is accepted by EventEmitter constructor.
20
+ * @example
21
+ * ```ts
22
+ * const routerEvents = defineEvents({ NAVIGATE: "ROUTER:NAVIGATE", NAVIGATE_BACK: "ROUTER:NAVIGATE_BACK" });
23
+ * class RouterEmitter extends EventEmitter<EventNamesOf<typeof routerEvents>> { constructor() { super(routerEvents); } }
24
+ * ```
25
+ */
26
+ declare function defineEvents<E extends Record<string, string>>(events: E): DefinedEvents<E>;
27
+ /**
28
+ * 泛型 EventEmitter:构造函数仅接受 defineEvents 返回的 DefinedEvents 类型,提供 on / off / emit。
29
+ * PayloadMap[K] 可为 void(无参)、单类型 T(单参)、或元组 [A, B, ...](多参),统一规范为参数列表。
30
+ * PayloadMap[K] can be void (no args), single type T (one arg), or tuple [A, B, ...] (multi arg).
31
+ *
32
+ * @param events - 须为 defineEvents(...) 的返回值(DefinedEvents)。Must be the return value of defineEvents(...) (DefinedEvents).
33
+ */
34
+ declare class EventEmitter<E extends string, PayloadMap extends Record<E, unknown> = Record<E, unknown>> {
35
+ private listeners;
36
+ constructor(events: DefinedEvents<Record<string, E>>);
37
+ /** 注册事件监听;回调为任意函数,由 emit 时传入的参数决定实际类型。 */
38
+ on<K extends E>(event: K, callback: EventCallback): void;
39
+ /** 移除事件监听(需与 on 时同一引用)。 */
40
+ off<K extends E>(event: K, callback: EventCallback): void;
41
+ /**
42
+ * 触发事件;参数与 PayloadMap[K] 一致:void 无参,T 单参,[A,B] 多参。
43
+ * Emit an event; args match PayloadMap[K]: void → no args, T → one arg, [A,B] → spread.
44
+ */
45
+ emit<K extends E>(event: K, ...args: ToArgs<PayloadMap[K]>): void;
46
+ }
47
+ export { EventEmitter, defineEvents };
48
+ export type { EventCallback, DefinedEvents, EventNamesOf };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 事件模块:仅导出通用 EventEmitter。各域发射器请直接按路径引用(如 @/events/router)。
3
+ * Events module: exports only the generic EventEmitter. Use direct paths for domain emitters (e.g. @/events/router).
4
+ */
5
+ export * from './EventEmitter';
@@ -0,0 +1,4 @@
1
+ export * from './makeUnifiedInfiniteQuery';
2
+ export * from './makeCursorFetchFunction';
3
+ export * from './makeUnifiedQuery';
4
+ export * from './type';
@@ -0,0 +1,84 @@
1
+ import { ListDTOWithNextCursor, ListDTOWithTotalNumber } from '../../types/api';
2
+ import { FetchNumberListParams, FetchStringListParams } from './type';
3
+ /**
4
+ * 创建基于游标(Cursor)的分页获取函数
5
+ *
6
+ * 将标准的分页 API(基于 offset/limit)转换为游标分页函数,用于无限查询。
7
+ * 自动计算下一页游标,并支持数据后处理。
8
+ *
9
+ * @template T - 数据项类型
10
+ * @template F - 过滤器对象类型,必须是对象类型,默认为 Record<string, unknown>
11
+ *
12
+ * @param {Function} fetchFunc - 远程数据获取函数,接收 FetchListParams 参数,返回包含 items 和 total 的结果
13
+ * @param {number} [pageSize=20] - 每页数据条数,默认 20
14
+ * @param {Function} [postProcess] - 可选的数据后处理函数,在每次数据获取后调用
15
+ *
16
+ * @returns {Function} 返回一个游标分页函数,接收 pageParam(页码)和 filter(过滤器)参数
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * * 定义标准的分页 API
21
+ * const fetchProductsAPI = async (params: { offset: number; limit: number; category?: string }) => {
22
+ * const response = await fetch('/api/products?' + new URLSearchParams(params));
23
+ * const { items, total } = await response.json();
24
+ * return { items, total };
25
+ * };
26
+ *
27
+ * * 创建游标分页函数
28
+ * const fetchProducts = makeCursorFetchFunction(
29
+ * fetchProductsAPI,
30
+ * 20,
31
+ * (data) => {
32
+ * * 数据后处理:为每个商品添加缓存
33
+ * data.forEach(product => cache.set(product.id, product));
34
+ * }
35
+ * );
36
+ *
37
+ * * 使用游标函数
38
+ * const firstPage = await fetchProducts(0, { category: "electronics" });
39
+ * * 返回: ListDTOWithTotalNumber<Product> = { items, total }
40
+ * * getNextPageParam 由 makeUnifiedInfiniteQuery 根据 total 与 pageSize 计算
41
+ * ```
42
+ *
43
+ * @remarks
44
+ * **为什么需要游标转换?**
45
+ * - React Query 的无限查询使用 pageParam(游标)来跟踪分页位置
46
+ * - 后端 API 通常使用 offset/limit 分页,两者需要转换才能配合使用
47
+ * - 游标模式更适合无限滚动,避免在组件中手动计算 offset
48
+ *
49
+ * **游标计算逻辑:**
50
+ * - **offset 计算**:`offset = pageParam × pageSize`
51
+ * - 示例:pageParam=0 → offset=0(第一页)
52
+ * - 示例:pageParam=2, pageSize=20 → offset=40(第三页,跳过前 40 条)
53
+ * - **nextCursor 判断**:`(pageParam + 1) × pageSize < total ? pageParam + 1 : undefined`
54
+ * - 如果下一页的起始位置小于总数,返回下一页页码
55
+ * - 否则返回 undefined,告知 React Query 没有更多数据
56
+ *
57
+ * **为什么 pageParam 从 0 开始?**
58
+ * - 符合数组索引习惯,第 0 页、第 1 页...
59
+ * - 计算 offset 时公式更简洁:`offset = pageParam × pageSize`
60
+ * - 避免使用 1-based 索引时需要额外的 -1 运算
61
+ *
62
+ * **postProcess 的作用:**
63
+ * - 在数据返回后、缓存前执行,适合进行副作用操作
64
+ * - 常见用途:更新单项缓存、触发分析事件、数据预处理
65
+ * - 不影响返回值,保持数据流的纯净性
66
+ */
67
+ declare function makeCursorFetchFunction<T, F extends object = Record<string, unknown>>(fetchFunc: (params: FetchNumberListParams<F>) => Promise<ListDTOWithTotalNumber<T>>, pageSize?: number, postProcess?: (data: T[]) => void): (pageParam?: number, filter?: F) => Promise<ListDTOWithTotalNumber<T>>;
68
+ /**
69
+ * 创建基于字符串游标的分页获取函数(用于 nextCursor 为 string 的 API)。
70
+ * Creates cursor-based fetch function for string cursor (API returns nextCursor: string).
71
+ *
72
+ * @param fetchFunc - 远程获取函数,参数含 offset: string, limit,返回 { items, nextCursor }。Fetch (params: FetchStringListParams<F>) => Promise<ListDTOWithNextCursor<T>>.
73
+ * @param pageSize - 每页条数,默认 20。Page size.
74
+ * @param postProcess - 可选,数据返回后调用。Optional post-process (data: T[]) => void.
75
+ * @returns 返回 (pageParam: string, filter?: F) => Promise<ListDTOWithNextCursor<T>>。Returns async cursor fetcher.
76
+ * @example
77
+ * ```ts
78
+ * const fetch = makeStringCursorFetchFunction(fetchByToken, 20);
79
+ * const page = await fetch("", { q: "x" });
80
+ * if (page.nextCursor) await fetch(page.nextCursor, { q: "x" });
81
+ * ```
82
+ */
83
+ declare function makeStringCursorFetchFunction<T, F extends object = Record<string, unknown>>(fetchFunc: (params: FetchStringListParams<F>) => Promise<ListDTOWithNextCursor<T>>, pageSize?: number, postProcess?: (data: T[]) => void): (pageParam?: string, filter?: F) => Promise<ListDTOWithNextCursor<T>>;
84
+ export { makeCursorFetchFunction, makeStringCursorFetchFunction };
@@ -0,0 +1,124 @@
1
+ import { QueryKey, UseInfiniteQueryResult, UseSuspenseInfiniteQueryResult } from '@tanstack/react-query';
2
+ import { AxiosError } from 'axios';
3
+ import { ListDTOWithTotalNumber } from '../../types/api';
4
+ import { FetchNumberListParams, InfiniteQueryOptions, SuspenseInfiniteQueryOptions } from './type';
5
+ /**
6
+ * 创建统一的无限查询 Hook(Suspense 模式)
7
+ *
8
+ * 这是一个高阶函数工厂,用于创建支持无限滚动的数据查询 Hook。
9
+ * 它自动处理分页、缓存、错误重试等常见场景,并支持 Suspense 模式。
10
+ *
11
+ * @template T - 数据项类型
12
+ * @template F - 过滤器对象类型,必须是对象类型,默认为 Record<string, unknown>
13
+ *
14
+ * @param {Function} fetchRemote - 远程数据获取函数,接收分页参数和过滤器,返回 Promise
15
+ * @param {string} mode - 查询模式,设置为 "suspense" 启用 React Suspense 支持
16
+ * @param {number} [pageSize=20] - 每页数据条数,默认 20
17
+ * @param {Function} [postProcess] - 可选的数据后处理函数,在数据返回后调用
18
+ *
19
+ * @returns {Function} 返回一个 Hook 函数,接收 queryKey、filter 和 options 参数
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * * 定义 API 获取函数
24
+ * const fetchProducts = async (params: FetchListParams<ProductFilter>) => {
25
+ * const { items, total } = await api.getProducts(params);
26
+ * return { items, total };
27
+ * };
28
+ *
29
+ * * 创建 Hook(Suspense 模式)
30
+ * const useProductList = makeUnifiedInfiniteQuery(
31
+ * fetchProducts,
32
+ * "suspense",
33
+ * 20,
34
+ * (data) => console.warn('数据已加载:', data.length)
35
+ * );
36
+ *
37
+ * * 在组件中使用
38
+ * function ProductList() {
39
+ * const { data, fetchNextPage, hasNextPage } = useProductList(
40
+ * ["products"],
41
+ * { category: "electronics" },
42
+ * { staleTime: 60000 }
43
+ * );
44
+ *
45
+ * return (
46
+ * <div>
47
+ * {data.map(product => <ProductCard key={product.id} {...product} />)}
48
+ * {hasNextPage && <button onClick={() => fetchNextPage()}>加载更多</button>}
49
+ * </div>
50
+ * );
51
+ * }
52
+ * ```
53
+ *
54
+ * @remarks
55
+ * **为什么需要这个函数?**
56
+ * - React Query 的无限查询 API 较为底层,需要手动配置 queryFn、initialPageParam、getNextPageParam 等
57
+ * - 大多数列表查询都有相似的分页逻辑(offset/limit),重复编写这些配置容易出错
58
+ * - 通过工厂函数统一封装,确保分页逻辑的一致性,减少样板代码
59
+ *
60
+ * **为什么区分 Suspense 和普通模式?**
61
+ * - Suspense 模式:数据未就绪时会挂起组件渲染,适合配合 React Suspense 边界使用
62
+ * - 普通模式:提供 isLoading 状态,需要手动处理加载状态,更灵活
63
+ * - 两种模式的 Hook 返回类型不同,TypeScript 需要通过函数重载区分
64
+ *
65
+ * **内部实现原理:**
66
+ * 1. **游标转换**:使用 makeCursorFetchFunction 将 offset/limit 转换为页码游标
67
+ * 2. **查询键构造**:自动将 filter 合并到 queryKey 中,确保不同过滤条件有独立缓存
68
+ * 3. **数据扁平化**:通过 select 将分页数据 pages 扁平化为单一数组,简化组件使用
69
+ * 4. **智能重试**:仅对 5xx 服务器错误和网络错误重试,避免对 4xx 客户端错误无意义重试
70
+ * 5. **选项合并**:使用 spread 运算符允许外部覆盖默认配置(如 staleTime、retry)
71
+ */
72
+ declare function makeUnifiedInfiniteQuery<T, F extends object = Record<string, unknown>>(fetchRemote: (params: FetchNumberListParams<F>) => Promise<ListDTOWithTotalNumber<T>>, mode: "suspense", pageSize?: number, postProcess?: (data: T[]) => void): (queryKey: QueryKey, filter?: F, options?: SuspenseInfiniteQueryOptions<T>) => UseSuspenseInfiniteQueryResult<T[], AxiosError>;
73
+ /**
74
+ * 创建统一的无限查询 Hook(普通模式)
75
+ *
76
+ * 这是一个高阶函数工厂,用于创建支持无限滚动的数据查询 Hook。
77
+ * 它自动处理分页、缓存、错误重试等常见场景,普通模式不使用 Suspense。
78
+ *
79
+ * @template T - 数据项类型
80
+ * @template F - 过滤器对象类型,必须是对象类型,默认为 Record<string, unknown>
81
+ *
82
+ * @param {Function} fetchRemote - 远程数据获取函数,接收分页参数和过滤器,返回 Promise
83
+ * @param {string} [mode="normal"] - 查询模式,设置为 "normal" 或省略使用普通模式
84
+ * @param {number} [pageSize=20] - 每页数据条数,默认 20
85
+ * @param {Function} [postProcess] - 可选的数据后处理函数,在数据返回后调用
86
+ *
87
+ * @returns {Function} 返回一个 Hook 函数,接收 queryKey、filter 和 options 参数
88
+ *
89
+ * @example
90
+ * ```tsx
91
+ * * 定义 API 获取函数
92
+ * const fetchProducts = async (params: FetchListParams<ProductFilter>) => {
93
+ * const { items, total } = await api.getProducts(params);
94
+ * return { items, total };
95
+ * };
96
+ *
97
+ * * 创建 Hook(普通模式)
98
+ * const useProductList = makeUnifiedInfiniteQuery(
99
+ * fetchProducts,
100
+ * "normal", * 或省略此参数
101
+ * 20
102
+ * );
103
+ *
104
+ * * 在组件中使用
105
+ * function ProductList() {
106
+ * const { data, fetchNextPage, hasNextPage, isLoading } = useProductList(
107
+ * ["products"],
108
+ * { category: "electronics" },
109
+ * { staleTime: 60000 }
110
+ * );
111
+ *
112
+ * if (isLoading) return <Loading />;
113
+ *
114
+ * return (
115
+ * <div>
116
+ * {data?.map(product => <ProductCard key={product.id} {...product} />)}
117
+ * {hasNextPage && <button onClick={() => fetchNextPage()}>加载更多</button>}
118
+ * </div>
119
+ * );
120
+ * }
121
+ * ```
122
+ */
123
+ declare function makeUnifiedInfiniteQuery<T, F extends object = Record<string, unknown>>(fetchRemote: (params: FetchNumberListParams<F>) => Promise<ListDTOWithTotalNumber<T>>, mode?: "normal", pageSize?: number, postProcess?: (data: T[]) => void): (queryKey: QueryKey, filter?: F, options?: InfiniteQueryOptions<T>) => UseInfiniteQueryResult<T[], AxiosError>;
124
+ export { makeUnifiedInfiniteQuery };
@@ -0,0 +1,19 @@
1
+ import { QueryKey, UseQueryOptions, UseQueryResult, UseSuspenseQueryOptions, UseSuspenseQueryResult } from '@tanstack/react-query';
2
+ import { AxiosError } from 'axios';
3
+ /**
4
+ * 创建统一的单条查询 Hook 工厂(支持 normal / suspense 模式)。
5
+ * Creates a unified single-item query Hook factory (normal or suspense mode).
6
+ *
7
+ * @param fetchRemote - 拉取函数,接收 filter 返回 Promise<T>。Fetch function (params: F) => Promise<T>.
8
+ * @param mode - "suspense" 或 "normal"(默认)。Query mode.
9
+ * @param postProcess - 可选,数据返回后调用。Optional post-process (data: T) => void.
10
+ * @returns 返回一个 Hook:(queryKey, filter?, options?) => UseQueryResult 或 UseSuspenseQueryResult。Returns a Hook.
11
+ * @example
12
+ * ```ts
13
+ * const useProfile = makeUnifiedQuery(fetchProfile, "normal");
14
+ * const { data } = useProfile(profileKey, { id }, { enabled: !!id });
15
+ * ```
16
+ */
17
+ declare function makeUnifiedQuery<T, F extends object = Record<string, unknown>>(fetchRemote: (params: F) => Promise<T>, mode: "suspense", postProcess?: (data: T) => void): (queryKey: QueryKey, filter?: F, options?: Omit<UseSuspenseQueryOptions<T, AxiosError, T>, "queryKey" | "queryFn">) => UseSuspenseQueryResult<T, AxiosError>;
18
+ declare function makeUnifiedQuery<T, F extends object = Record<string, unknown>>(fetchRemote: (params: F) => Promise<T>, mode?: "normal", postProcess?: (data: T) => void): (queryKey: QueryKey, filter?: F, options?: Omit<UseQueryOptions<T, AxiosError, T>, "queryKey" | "queryFn">) => UseQueryResult<T, AxiosError>;
19
+ export { makeUnifiedQuery };