@tker-react/layout 0.2.6 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -39,6 +39,10 @@ interface MenuAdapterProps {
39
39
  mode: "side" | "top";
40
40
  width: string;
41
41
  onSelect: (path: string) => void;
42
+ /** 当前展开的子菜单路径集合(side-menu 模式使用) */
43
+ openKeys: Set<string>;
44
+ /** 统一菜单点击入口,自动处理展开/折叠/导航,替代 onSelect 时 adapter 无需自行判断菜单类型 */
45
+ onMenuItemClick: (path: string) => void;
42
46
  }
43
47
  interface BreadcrumbAdapterProps {
44
48
  breadcrumbData: BreadcrumbItem[];
@@ -77,17 +81,11 @@ interface LayoutContextValue {
77
81
  setUserAvatarAdapter: (component: ComponentType<UserAvatarAdapterProps>) => void;
78
82
  menuData: MenuItem[];
79
83
  activePath: string;
80
- collapsed: boolean;
81
84
  expandedWidth: string;
82
85
  collapsedWidth: string;
83
86
  layoutMode: "side-menu" | "top-menu";
84
87
  setMenus: (data: MenuItem[]) => void;
85
88
  setActivePath: (path: string, fullPath?: string) => void;
86
- toggleCollapse: () => void;
87
- setCollapsed: (collapsed: boolean) => void;
88
- openKeys: Set<string>;
89
- toggleMenuOpen: (path: string, forceOpen?: boolean) => void;
90
- menuItemClick: (path: string) => void;
91
89
  setExpandedWidth: (width: string) => void;
92
90
  setCollapsedWidth: (width: string) => void;
93
91
  setLayoutMode: (mode: "side-menu" | "top-menu") => void;
@@ -105,5 +103,5 @@ declare function LayoutProvider({ children }: {
105
103
  children: ReactNode;
106
104
  }): react_jsx_runtime.JSX.Element;
107
105
 
108
- export { Layout, LayoutProvider, useLayoutContext as useLayout, useLayoutContext };
106
+ export { Layout, LayoutProvider, useLayoutContext as useLayout };
109
107
  export type { BreadcrumbAdapterProps, BreadcrumbItem, LayoutAdapters, LogoAdapterProps, MenuAdapterProps, MenuItem, TabAdapterProps, TabItem, UserAvatarAdapterProps };
package/dist/index.d.ts CHANGED
@@ -39,6 +39,10 @@ interface MenuAdapterProps {
39
39
  mode: "side" | "top";
40
40
  width: string;
41
41
  onSelect: (path: string) => void;
42
+ /** 当前展开的子菜单路径集合(side-menu 模式使用) */
43
+ openKeys: Set<string>;
44
+ /** 统一菜单点击入口,自动处理展开/折叠/导航,替代 onSelect 时 adapter 无需自行判断菜单类型 */
45
+ onMenuItemClick: (path: string) => void;
42
46
  }
43
47
  interface BreadcrumbAdapterProps {
44
48
  breadcrumbData: BreadcrumbItem[];
@@ -77,17 +81,11 @@ interface LayoutContextValue {
77
81
  setUserAvatarAdapter: (component: ComponentType<UserAvatarAdapterProps>) => void;
78
82
  menuData: MenuItem[];
79
83
  activePath: string;
80
- collapsed: boolean;
81
84
  expandedWidth: string;
82
85
  collapsedWidth: string;
83
86
  layoutMode: "side-menu" | "top-menu";
84
87
  setMenus: (data: MenuItem[]) => void;
85
88
  setActivePath: (path: string, fullPath?: string) => void;
86
- toggleCollapse: () => void;
87
- setCollapsed: (collapsed: boolean) => void;
88
- openKeys: Set<string>;
89
- toggleMenuOpen: (path: string, forceOpen?: boolean) => void;
90
- menuItemClick: (path: string) => void;
91
89
  setExpandedWidth: (width: string) => void;
92
90
  setCollapsedWidth: (width: string) => void;
93
91
  setLayoutMode: (mode: "side-menu" | "top-menu") => void;
@@ -105,5 +103,5 @@ declare function LayoutProvider({ children }: {
105
103
  children: ReactNode;
106
104
  }): react_jsx_runtime.JSX.Element;
107
105
 
108
- export { Layout, LayoutProvider, useLayoutContext as useLayout, useLayoutContext };
106
+ export { Layout, LayoutProvider, useLayoutContext as useLayout };
109
107
  export type { BreadcrumbAdapterProps, BreadcrumbItem, LayoutAdapters, LogoAdapterProps, MenuAdapterProps, MenuItem, TabAdapterProps, TabItem, UserAvatarAdapterProps };
package/dist/index.mjs CHANGED
@@ -44,6 +44,22 @@ function generateBreadcrumb(menuData, activePath) {
44
44
  }
45
45
 
46
46
  const LayoutContext = createContext(null);
47
+ const LayoutInteractionContext = createContext(null);
48
+ function useLayoutInteractionContext() {
49
+ const ctx = useContext(LayoutInteractionContext);
50
+ if (!ctx) {
51
+ throw new Error("useLayoutInteractionContext \u5FC5\u987B\u5728 <Layout> \u5185\u90E8\u4F7F\u7528");
52
+ }
53
+ return ctx;
54
+ }
55
+ const LayoutOpenKeysContext = createContext(null);
56
+ function useLayoutOpenKeysContext() {
57
+ const ctx = useContext(LayoutOpenKeysContext);
58
+ if (!ctx) {
59
+ throw new Error("useLayoutOpenKeysContext \u5FC5\u987B\u5728 <Layout> \u5185\u90E8\u4F7F\u7528");
60
+ }
61
+ return ctx;
62
+ }
47
63
  function useLayoutContext() {
48
64
  const ctx = useContext(LayoutContext);
49
65
  if (!ctx) {
@@ -187,6 +203,28 @@ function LayoutProvider({ children }) {
187
203
  const setMaxTabs = useCallback((max) => {
188
204
  setMaxTabsState(max);
189
205
  }, []);
206
+ const setCollapsed = useCallback((val) => {
207
+ if (val) {
208
+ savedOpenKeysRef.current = new Set(openKeysRef.current);
209
+ setOpenKeys(/* @__PURE__ */ new Set());
210
+ } else {
211
+ setOpenKeys(new Set(savedOpenKeysRef.current));
212
+ }
213
+ setCollapsedState(val);
214
+ }, []);
215
+ const interactionValue = useMemo(
216
+ () => ({
217
+ collapsed,
218
+ toggleCollapse,
219
+ setCollapsed,
220
+ menuItemClick
221
+ }),
222
+ [collapsed, toggleCollapse, setCollapsed, menuItemClick]
223
+ );
224
+ const openKeysValue = useMemo(
225
+ () => ({ openKeys, toggleMenuOpen }),
226
+ [openKeys, toggleMenuOpen]
227
+ );
190
228
  const value = useMemo(
191
229
  () => ({
192
230
  adapters,
@@ -198,26 +236,11 @@ function LayoutProvider({ children }) {
198
236
  setUserAvatarAdapter,
199
237
  menuData,
200
238
  activePath,
201
- collapsed,
202
239
  expandedWidth,
203
240
  collapsedWidth,
204
241
  layoutMode,
205
242
  setMenus,
206
243
  setActivePath,
207
- toggleCollapse,
208
- // setCollapsed 同样处理 openKeys 保存/恢复,与 toggleCollapse 逻辑一致
209
- setCollapsed: (val) => {
210
- if (val) {
211
- savedOpenKeysRef.current = new Set(openKeysRef.current);
212
- setOpenKeys(/* @__PURE__ */ new Set());
213
- } else {
214
- setOpenKeys(new Set(savedOpenKeysRef.current));
215
- }
216
- setCollapsedState(val);
217
- },
218
- openKeys,
219
- toggleMenuOpen,
220
- menuItemClick,
221
244
  setExpandedWidth,
222
245
  setCollapsedWidth,
223
246
  setLayoutMode,
@@ -240,16 +263,11 @@ function LayoutProvider({ children }) {
240
263
  setUserAvatarAdapter,
241
264
  menuData,
242
265
  activePath,
243
- collapsed,
244
266
  expandedWidth,
245
267
  collapsedWidth,
246
268
  layoutMode,
247
269
  setMenus,
248
270
  setActivePath,
249
- toggleCollapse,
250
- openKeys,
251
- toggleMenuOpen,
252
- menuItemClick,
253
271
  isConcretePage,
254
272
  getFullPath,
255
273
  setNavigateAdapter,
@@ -260,22 +278,22 @@ function LayoutProvider({ children }) {
260
278
  setMaxTabs
261
279
  ]
262
280
  );
263
- return /* @__PURE__ */ jsx(LayoutContext.Provider, { value, children });
281
+ return /* @__PURE__ */ jsx(LayoutContext.Provider, { value, children: /* @__PURE__ */ jsx(LayoutInteractionContext.Provider, { value: interactionValue, children: /* @__PURE__ */ jsx(LayoutOpenKeysContext.Provider, { value: openKeysValue, children }) }) });
264
282
  }
265
283
 
266
284
  function LayoutAside() {
267
285
  const {
268
286
  adapters,
269
- collapsed,
270
287
  expandedWidth,
271
288
  collapsedWidth,
272
289
  menuData,
273
290
  activePath,
274
291
  layoutMode,
275
292
  getFullPath,
276
- navigate,
277
- toggleCollapse
293
+ navigate
278
294
  } = useLayoutContext();
295
+ const { collapsed, toggleCollapse, menuItemClick } = useLayoutInteractionContext();
296
+ const { openKeys } = useLayoutOpenKeysContext();
279
297
  const menuMode = layoutMode === "top-menu" ? "top" : "side";
280
298
  const handleMenuSelect = useCallback(
281
299
  (path) => {
@@ -297,7 +315,9 @@ function LayoutAside() {
297
315
  collapsed,
298
316
  mode: menuMode,
299
317
  width: asideWidth,
300
- onSelect: handleMenuSelect
318
+ openKeys,
319
+ onSelect: handleMenuSelect,
320
+ onMenuItemClick: menuItemClick
301
321
  }
302
322
  ),
303
323
  /* @__PURE__ */ jsx(
@@ -488,7 +508,6 @@ function openTabInData(tabData, path, config) {
488
508
  function LayoutHeader() {
489
509
  const {
490
510
  adapters,
491
- collapsed,
492
511
  expandedWidth,
493
512
  collapsedWidth,
494
513
  menuData,
@@ -498,6 +517,7 @@ function LayoutHeader() {
498
517
  isConcretePage,
499
518
  navigate
500
519
  } = useLayoutContext();
520
+ const { collapsed, menuItemClick } = useLayoutInteractionContext();
501
521
  const isTopMenu = layoutMode === "top-menu";
502
522
  const isSideMenu = layoutMode === "side-menu";
503
523
  const breadcrumbData = useMemo(
@@ -546,7 +566,9 @@ function LayoutHeader() {
546
566
  collapsed: false,
547
567
  mode: "top",
548
568
  width: logoWidth,
549
- onSelect: handleMenuSelect
569
+ openKeys: /* @__PURE__ */ new Set(),
570
+ onSelect: handleMenuSelect,
571
+ onMenuItemClick: menuItemClick
550
572
  }
551
573
  ),
552
574
  BreadcrumbAdapter && isSideMenu && /* @__PURE__ */ jsx(
@@ -579,4 +601,4 @@ function Layout({ children }) {
579
601
  return /* @__PURE__ */ jsx(LayoutProvider, { children: /* @__PURE__ */ jsx(LayoutInner, { children }) });
580
602
  }
581
603
 
582
- export { Layout, LayoutProvider, useLayoutContext as useLayout, useLayoutContext };
604
+ export { Layout, LayoutProvider, useLayoutContext as useLayout };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tker-react/layout",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "type": "module",