@gx-design-vue/pro-layout 0.1.0-alpha.23 → 0.1.0-alpha.25

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/ProLayout.js CHANGED
@@ -12,7 +12,7 @@ import style_default from "./style/index.js";
12
12
  import { normalizeSectionConfig } from "./utils/config.js";
13
13
  import { computed, createVNode, defineComponent, mergeDefaults, ref } from "vue";
14
14
  import { ThemeContext, useThemeContext } from "@gx-design-vue/context";
15
- import { GProConfigProvider, useProToken } from "@gx-design-vue/pro-provider";
15
+ import { GProConfigProvider, unit, useProToken } from "@gx-design-vue/pro-provider";
16
16
  import { classNames, getSlotsProps } from "@gx-design-vue/pro-utils";
17
17
  import { useDark, useMediaQuery, useVModel } from "@vueuse/core";
18
18
  import { ConfigProvider, Layout } from "antdv-next";
@@ -32,14 +32,29 @@ const InnerLayout = /* @__PURE__ */ defineComponent((props, { slots }) => {
32
32
  cssVarCls,
33
33
  rootCls
34
34
  });
35
+ const isWide = computed(() => props.layout === "wide" && !!props.wideContentWidth);
36
+ const rootStyle = computed(() => ({
37
+ ...props.proStyles?.root,
38
+ minWidth: isWide.value ? unit(props.wideContentWidth) : void 0
39
+ }));
40
+ const headerHeight = computed(() => parentCtx?.header?.value?.height);
41
+ const layoutStyle = computed(() => {
42
+ const base = {
43
+ minHeight: "100%",
44
+ flexDirection: props.showSider ? "row" : void 0
45
+ };
46
+ if (isWide.value) {
47
+ base.width = unit(props.wideContentWidth);
48
+ base.margin = "0 auto";
49
+ if (headerHeight.value) base.paddingBlockStart = `calc(${unit(headerHeight.value)} + 20px)`;
50
+ }
51
+ return base;
52
+ });
35
53
  return () => createVNode("div", {
36
54
  "class": classNames(prefixCls.value, `${prefixCls.value}-${props.layout}`, hashId.value, cssVarCls.value, rootCls.value, props.proClasses?.root),
37
- "style": props.proStyles?.root,
55
+ "style": rootStyle.value,
38
56
  "data-layout": props.layout
39
- }, [proLayoutToken.value?.bgLayout && createVNode("div", { "class": `${prefixCls.value}-bg-list` }, null), createVNode(Layout, { "style": {
40
- minHeight: "100%",
41
- flexDirection: props.showSider ? "row" : void 0
42
- } }, { default: () => [slots.default?.()] })]);
57
+ }, [proLayoutToken.value?.bgLayout && createVNode("div", { "class": `${prefixCls.value}-bg-list` }, null), createVNode(Layout, { "style": layoutStyle.value }, { default: () => [slots.default?.()] })]);
43
58
  }, {
44
59
  props: {
45
60
  layout: {
@@ -50,6 +65,10 @@ const InnerLayout = /* @__PURE__ */ defineComponent((props, { slots }) => {
50
65
  type: Boolean,
51
66
  required: true
52
67
  },
68
+ wideContentWidth: {
69
+ type: [Number, String],
70
+ required: false
71
+ },
53
72
  proClasses: {
54
73
  type: Object,
55
74
  required: false
@@ -73,7 +92,9 @@ const GProLayout = /* @__PURE__ */ defineComponent((props, { emit, expose, slots
73
92
  };
74
93
  });
75
94
  const layout = computed(() => props.layout ?? "side");
76
- const isMobile = useMediaQuery("(max-width: 768px)");
95
+ const isMobileRaw = useMediaQuery("(max-width: 768px)");
96
+ /** wide 模式禁用移动端行为 */
97
+ const isMobile = computed(() => layout.value !== "wide" && isMobileRaw.value);
77
98
  const collapsed = useVModel(props, "collapsed", emit, {
78
99
  passive: true,
79
100
  defaultValue: false
@@ -120,6 +141,12 @@ const GProLayout = /* @__PURE__ */ defineComponent((props, { emit, expose, slots
120
141
  ...DEFAULT_LAYOUT_CONFIG.pageContainer,
121
142
  ...props.pageContainer || {}
122
143
  }));
144
+ /** wide 模式整体内容宽度:取 contentWidth,无值/0 默认 1300 */
145
+ const wideContentWidth = computed(() => {
146
+ if (layout.value !== "wide") return void 0;
147
+ const contentWidth = pageContainerConfig.value.contentWidth;
148
+ return !contentWidth ? 1300 : contentWidth;
149
+ });
123
150
  const tabsConf = computed(() => normalizeSectionConfig(props.tabsConfig, DEFAULT_LAYOUT_CONFIG.tabsConfig));
124
151
  const tabsStateConfig = computed(() => tabsConf.value ?? {});
125
152
  const collapsedWidth = computed(() => collapseConfig.value?.width ?? DEFAULT_LAYOUT_CONFIG.collapse.width);
@@ -229,7 +256,8 @@ const GProLayout = /* @__PURE__ */ defineComponent((props, { emit, expose, slots
229
256
  tabsHeight,
230
257
  setTabsHeight: (value) => {
231
258
  tabsHeight.value = value;
232
- }
259
+ },
260
+ wideContentWidth
233
261
  });
234
262
  expose({ tabs: tabsState.tabsController });
235
263
  function resolveLayoutSlots() {
@@ -253,6 +281,7 @@ const GProLayout = /* @__PURE__ */ defineComponent((props, { emit, expose, slots
253
281
  }, { default: () => [createVNode(InnerLayout, {
254
282
  "layout": layout.value,
255
283
  "showSider": showSider.value,
284
+ "wideContentWidth": wideContentWidth.value,
256
285
  "proClasses": props.proClasses,
257
286
  "proStyles": props.proStyles
258
287
  }, { default: () => [showSider.value && siderWidth.value && createVNode(LayoutSider$1, {
@@ -281,7 +310,7 @@ const GProLayout = /* @__PURE__ */ defineComponent((props, { emit, expose, slots
281
310
  breadcrumb: slots.breadcrumb,
282
311
  collapseIcon: slots.collapseIcon
283
312
  }),
284
- tabsConf.value && createVNode(LayoutTabs, {
313
+ tabsConf.value && layout.value !== "wide" && createVNode(LayoutTabs, {
285
314
  "config": tabsConf.value,
286
315
  "onReloadPage": () => emit("reloadPage"),
287
316
  "onContentFullscreenChange": (val) => {
@@ -293,14 +322,20 @@ const GProLayout = /* @__PURE__ */ defineComponent((props, { emit, expose, slots
293
322
  default: () => [slots.default?.()],
294
323
  ...layoutSlots
295
324
  }),
296
- showFooter.value && createVNode(LayoutFooter$1, {
325
+ !wideContentWidth.value && showFooter.value && createVNode(LayoutFooter$1, {
297
326
  "links": footerConfig.value.links,
298
327
  "copyright": footerConfig.value.copyright
299
328
  }, {
300
329
  footer: layoutSlots.footer,
301
330
  copyright: layoutSlots.copyright
302
331
  })
303
- ])] })] })] })] });
332
+ ])] }), wideContentWidth.value && showFooter.value && createVNode(LayoutFooter$1, {
333
+ "links": footerConfig.value.links,
334
+ "copyright": footerConfig.value.copyright
335
+ }, {
336
+ footer: layoutSlots.footer,
337
+ copyright: layoutSlots.copyright
338
+ })] })] })] });
304
339
  };
305
340
  }, {
306
341
  props: /*@__PURE__*/ mergeDefaults({
@@ -40,8 +40,8 @@ declare const ProAppPage: import("vue").DefineComponent<import("vue").ExtractPro
40
40
  message: PropType<ConfigOptions>;
41
41
  notification: PropType<NotificationConfig>;
42
42
  }>> & Readonly<{}>, {
43
- indicator: CustomRender;
44
43
  spinning: AppPageSpinning;
44
+ indicator: CustomRender;
45
45
  }, SlotsType<{
46
46
  default: () => any;
47
47
  indicator: () => any;
@@ -10,16 +10,20 @@ import { useWindowScroll } from "@vueuse/core";
10
10
  import { LayoutHeader } from "antdv-next";
11
11
  //#region src/components/Header/index.tsx
12
12
  const Header = /* @__PURE__ */ defineComponent((props, { emit, slots }) => {
13
- const { header, siderWidth, layout, menuState, prefixCls, collapseConfig, collapsed, isMobile, logoConfig, logoTitle, selectedKeys, openKeys, proClasses, proStyles, breadcrumbRender, breadcrumbConfig } = useLayoutBase(props);
13
+ const { header, siderWidth, wideContentWidth, layout, menuState, prefixCls, collapseConfig, collapsed, isMobile, logoConfig, logoTitle, selectedKeys, openKeys, proClasses, proStyles, breadcrumbRender, breadcrumbConfig } = useLayoutBase(props);
14
14
  const headerMenus = computed(() => menuState?.headerMenus.value ?? []);
15
15
  const breadcrumbItems = computed(() => menuState?.breadcrumbItems.value ?? []);
16
16
  const breadcrumbRoutes = computed(() => menuState?.breadcrumbRoutes.value ?? []);
17
- const showLogo = computed(() => ["top"].includes(layout.value ?? "") || ["mix", "wide"].includes(layout.value ?? "") && !siderWidth.value);
17
+ const showLogo = computed(() => ["top", "wide"].includes(layout.value ?? "") || ["side", "mix"].includes(layout.value ?? "") && !siderWidth.value);
18
18
  const headerStyle = computed(() => {
19
19
  const style = {};
20
- if (header.value?.fixed && siderWidth.value && !isMobile.value) style.width = `calc(100% - ${unit(siderWidth.value)})`;
20
+ if (header.value?.fixed && siderWidth.value && !isMobile.value && layout.value !== "wide") style.width = `calc(100% - ${unit(siderWidth.value)})`;
21
21
  return style;
22
22
  });
23
+ /** wide 模式 header-main 宽度约束 */
24
+ const headerMainStyle = computed(() => {
25
+ if (wideContentWidth?.value) return { width: unit(wideContentWidth.value) };
26
+ });
23
27
  const headerHidden = ref(false);
24
28
  if (typeof window !== "undefined") {
25
29
  const { y: scrollY } = useWindowScroll();
@@ -71,7 +75,7 @@ const Header = /* @__PURE__ */ defineComponent((props, { emit, slots }) => {
71
75
  const logoRender = slots.logo || logoConfig.value?.render;
72
76
  const collapseRender = slots.collapse || collapseConfig.value?.render;
73
77
  const collapseIconRender = slots.collapseIcon || collapseConfig.value?.icon;
74
- return createVNode(Fragment, null, [header.value?.fixed && createVNode(LayoutHeader, { "style": {
78
+ return createVNode(Fragment, null, [layout.value !== "wide" && header.value?.fixed && createVNode(LayoutHeader, { "style": {
75
79
  background: "transparent",
76
80
  lineHeight: unit(header.value?.height),
77
81
  height: unit(header.value?.height)
@@ -81,7 +85,10 @@ const Header = /* @__PURE__ */ defineComponent((props, { emit, slots }) => {
81
85
  ...headerStyle.value,
82
86
  ...proStyles.value.header
83
87
  }
84
- }, { default: () => [createVNode("div", { "class": `${prefixCls.value}-header-main` }, [
88
+ }, { default: () => [createVNode("div", {
89
+ "class": `${prefixCls.value}-header-main`,
90
+ "style": headerMainStyle.value
91
+ }, [
85
92
  createVNode("div", { "class": `${prefixCls.value}-header-main-left` }, [
86
93
  showLogo.value && logoConfig.value && (typeof logoRender === "function" ? logoRender?.({
87
94
  collapsed: collapsed.value,
@@ -48,9 +48,9 @@ declare const GPageTransition: import("vue").DefineComponent<import("vue").Extra
48
48
  default: string;
49
49
  };
50
50
  }>> & Readonly<{}>, {
51
- direction: string;
52
51
  reverse: boolean;
53
52
  name: string;
53
+ direction: string;
54
54
  disabled: boolean;
55
55
  }, SlotsType<GPageTransitionSlots>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
56
56
  //#endregion
@@ -14,6 +14,18 @@ function _isSlot(s) {
14
14
  }
15
15
  const LayoutSider = /* @__PURE__ */ defineComponent((props, { emit, slots }) => {
16
16
  const { sider, header, layout, menuState, prefixCls, cssVarCls, rootCls, collapseConfig, collapsed, isMobile, logoConfig, logoTitle, selectedKeys, openKeys, proClasses, proStyles, siderWidth, collapsedWidth } = useLayoutBase(props);
17
+ /** wide 模式 sider sticky 定位样式 */
18
+ const wideSiderStyle = computed(() => {
19
+ if (layout.value !== "wide") return void 0;
20
+ const headerHeight = unit(header.value?.height);
21
+ return {
22
+ top: `calc(${headerHeight} + 20px)`,
23
+ height: `calc(100vh - ${headerHeight} - 20px)`,
24
+ zIndex: 100
25
+ };
26
+ });
27
+ /** wide 模式下 sider 使用 sticky 而非 fixed */
28
+ const isWide = computed(() => layout.value === "wide");
17
29
  /** GScrollbar 组件引用,用于获取滚动容器 DOM */
18
30
  const scrollbarRef = shallowRef();
19
31
  /** 滚动阴影状态:上下边缘是否可继续滚动 */
@@ -36,7 +48,7 @@ const LayoutSider = /* @__PURE__ */ defineComponent((props, { emit, slots }) =>
36
48
  useResizeObserver(scrollbarWrapEl, () => updateScrollShadow());
37
49
  useResizeObserver(scrollbarViewEl, () => updateScrollShadow());
38
50
  const siderMenus = computed(() => menuState?.siderMenus.value ?? []);
39
- const siderClassNames = computed(() => classNames(`${prefixCls.value}-sider`, proClasses.value.sider, { [`${prefixCls.value}-sider-fixed`]: sider.value?.fixed }));
51
+ const siderClassNames = computed(() => classNames(`${prefixCls.value}-sider`, proClasses.value.sider, { [`${prefixCls.value}-sider-fixed`]: !isWide.value && sider.value?.fixed }));
40
52
  const siderChildrenClassNames = computed(() => classNames(`${prefixCls.value}-sider-children`, proClasses.value.siderChildren));
41
53
  const siderHeaderClassNames = computed(() => classNames(`${prefixCls.value}-sider-header`, proClasses.value.siderHeader));
42
54
  const siderFooterClassNames = computed(() => classNames(`${prefixCls.value}-sider-footer`, proClasses.value.siderFooter));
@@ -63,11 +75,7 @@ const LayoutSider = /* @__PURE__ */ defineComponent((props, { emit, slots }) =>
63
75
  const collapseRender = slots.collapse || collapseConfig.value?.render;
64
76
  const collapseIconRender = slots.collapseIcon || collapseConfig.value?.icon;
65
77
  return createVNode(Fragment, null, [
66
- [
67
- "side",
68
- "mix",
69
- "wide"
70
- ].includes(layout.value ?? "") && logoConfig.value && createVNode("div", {
78
+ ["side", "mix"].includes(layout.value ?? "") && logoConfig.value && createVNode("div", {
71
79
  "class": siderHeaderClassNames.value,
72
80
  "style": {
73
81
  ...proStyles.value.siderHeader,
@@ -108,7 +116,7 @@ const LayoutSider = /* @__PURE__ */ defineComponent((props, { emit, slots }) =>
108
116
  collapsed: collapsed.value,
109
117
  isMobile: isMobile.value
110
118
  })]),
111
- collapseConfig.value && collapseConfig.value.placement === "sider" && (collapseRender?.({ collapsed: collapsed.value }) ?? createVNode(LayoutCollapseButton, {
119
+ layout.value !== "wide" && collapseConfig.value && collapseConfig.value.placement === "sider" && (collapseRender?.({ collapsed: collapsed.value }) ?? createVNode(LayoutCollapseButton, {
112
120
  "collapsed": collapsed.value,
113
121
  "onClick": handleToggleCollapsed
114
122
  }, { icon: collapseIconRender }))
@@ -147,7 +155,7 @@ const LayoutSider = /* @__PURE__ */ defineComponent((props, { emit, slots }) =>
147
155
  "onClose": () => emit("update:collapsed", true)
148
156
  }, _isSlot(_slot = renderSiderChildren()) ? _slot : { default: () => [_slot] });
149
157
  }
150
- return createVNode(Fragment, null, [sider.value?.fixed && createVNode("div", { "style": {
158
+ return createVNode(Fragment, null, [!isWide.value && sider.value?.fixed && createVNode("div", { "style": {
151
159
  width: `${unit(siderWidth.value)}`,
152
160
  overflow: "hidden",
153
161
  flex: `0 0 ${unit(siderWidth.value)}`,
@@ -161,7 +169,10 @@ const LayoutSider = /* @__PURE__ */ defineComponent((props, { emit, slots }) =>
161
169
  "collapsedWidth": collapsedWidth.value,
162
170
  "breakpoint": breakpoint ?? void 0,
163
171
  "class": siderClassNames.value,
164
- "style": proStyles.value.sider,
172
+ "style": {
173
+ ...proStyles.value.sider,
174
+ ...wideSiderStyle.value
175
+ },
165
176
  "onCollapse": handleSiderCollapse,
166
177
  "onBreakpoint": handleBreakpoint
167
178
  }, _isSlot(_slot2 = renderSiderChildren()) ? _slot2 : { default: () => [_slot2] })]);
@@ -47,6 +47,7 @@ interface LayoutContextProps {
47
47
  /** 导航到指定菜单名 */
48
48
  navigate: (name: string) => void;
49
49
  tabsState?: UseTabsStateReturn;
50
+ wideContentWidth: ComputedRef<number | string | undefined>;
50
51
  }
51
52
  declare const useProvideLayoutContext: (ctx: LayoutContextProps) => LayoutContextProps, useInjectLayoutContext: () => LayoutContextProps;
52
53
  //#endregion
@@ -38,11 +38,11 @@ declare function useLayoutBase(props?: {
38
38
  selectedKeys: import("vue").ComputedRef<string[]>;
39
39
  openKeys: import("vue").ComputedRef<string[]>;
40
40
  proClasses: import("vue").ComputedRef<{
41
- content?: string;
42
41
  header?: string;
43
42
  sider?: string;
44
43
  breadcrumb?: string;
45
44
  logo?: string;
45
+ content?: string;
46
46
  siderHeader?: string;
47
47
  siderFooter?: string;
48
48
  footer?: string;
@@ -53,11 +53,11 @@ declare function useLayoutBase(props?: {
53
53
  tabs?: string;
54
54
  }>;
55
55
  proStyles: import("vue").ComputedRef<{
56
- content?: import("vue").CSSProperties;
57
56
  header?: import("vue").CSSProperties;
58
57
  sider?: import("vue").CSSProperties;
59
58
  breadcrumb?: import("vue").CSSProperties;
60
59
  logo?: import("vue").CSSProperties;
60
+ content?: import("vue").CSSProperties;
61
61
  siderHeader?: import("vue").CSSProperties;
62
62
  siderFooter?: import("vue").CSSProperties;
63
63
  footer?: import("vue").CSSProperties;
@@ -70,6 +70,7 @@ declare function useLayoutBase(props?: {
70
70
  breadcrumbRender: import("vue").Ref<(props: LayoutBreadcrumbSlotProps) => any, (props: LayoutBreadcrumbSlotProps) => any>;
71
71
  breadcrumbConfig: import("vue").ComputedRef<LayoutBreadcrumbConfig>;
72
72
  pageContainerConfig: import("vue").ComputedRef<LayoutPageContainerConfig>;
73
+ wideContentWidth: import("vue").ComputedRef<string | number>;
73
74
  hasFooterToolbar: import("vue").ComputedRef<boolean>;
74
75
  navigate: (name: string) => void;
75
76
  setHasFooterToolbar: (value: boolean) => void;
@@ -24,6 +24,7 @@ function useLayoutBase(props) {
24
24
  const breadcrumbRender = layoutContext?.breadcrumbRender;
25
25
  const breadcrumbConfig = layoutContext?.breadcrumbConfig;
26
26
  const pageContainerConfig = layoutContext?.pageContainerConfig;
27
+ const wideContentWidth = layoutContext?.wideContentWidth;
27
28
  const collapseConfig = layoutContext?.collapseConfig;
28
29
  const contentFullscreen = layoutContext?.contentFullscreen;
29
30
  const renderRouterView = layoutContext?.renderRouterView;
@@ -77,6 +78,7 @@ function useLayoutBase(props) {
77
78
  breadcrumbRender,
78
79
  breadcrumbConfig,
79
80
  pageContainerConfig,
81
+ wideContentWidth,
80
82
  hasFooterToolbar,
81
83
  navigate,
82
84
  setHasFooterToolbar