diff --git a/packages/core/client/src/modules/popup/__e2e__/schemaInitializer1.test.ts b/packages/core/client/src/modules/popup/__e2e__/schemaInitializer1.test.ts
index 94561bb6a3..7d9b481842 100644
--- a/packages/core/client/src/modules/popup/__e2e__/schemaInitializer1.test.ts
+++ b/packages/core/client/src/modules/popup/__e2e__/schemaInitializer1.test.ts
@@ -34,6 +34,7 @@ test.describe('where to open a popup and what can be added to it', () => {
// add blocks
await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-general').hover();
await page.getByText('Markdown').click();
+ await page.waitForTimeout(500);
await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-general').hover();
await page.getByText('Form').hover();
await page.getByRole('menuitem', { name: 'Current collection' }).click();
diff --git a/packages/core/client/src/schema-component/antd/association-field/InternalNester.tsx b/packages/core/client/src/schema-component/antd/association-field/InternalNester.tsx
index 0483d86cc8..dff712bf09 100644
--- a/packages/core/client/src/schema-component/antd/association-field/InternalNester.tsx
+++ b/packages/core/client/src/schema-component/antd/association-field/InternalNester.tsx
@@ -18,24 +18,12 @@ import { NocoBaseRecursionField } from '../../../formily/NocoBaseRecursionField'
import { useAssociationFieldContext, useInsertSchema } from './hooks';
import schema from './schema';
-const InternalNesterCss = css`
- & .ant-formily-item-layout-vertical {
- margin-bottom: 10px;
- }
- .ant-card-body {
- padding: 15px 20px 5px;
- }
- .ant-divider-horizontal {
- margin: 10px 0;
- }
-`;
-
const InternalNesterCardCss = css`
.ant-card-bordered {
border: none;
}
.ant-card-body {
- padding: 0px 20px 20px 0px;
+ padding: 0px 20px 0px 0px;
}
`;
@@ -55,6 +43,20 @@ export const InternalNester = observer(
labelWrap = true,
} = fieldSchema?.['x-component-props'] || {};
+ const InternalNesterCss = css`
+ margin-top: 0.4em;
+
+ & .ant-formily-item-layout-vertical {
+ margin-bottom: 10px;
+ }
+ .ant-card-body {
+ padding: ${token.padding}px ${token.paddingLG}px;
+ }
+ .ant-divider-horizontal {
+ margin: 10px 0;
+ }
+ `;
+
useEffect(() => {
insertNester(schema.Nester);
}, []);
diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Decorator.style.ts b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Decorator.style.ts
index dd641ed636..e3ff692660 100644
--- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Decorator.style.ts
+++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Decorator.style.ts
@@ -11,8 +11,19 @@ import { genStyleHook } from '../__builtins__';
const useStyles = genStyleHook('nb-grid-card', (token) => {
const { componentCls } = token;
+
return {
[componentCls]: {
+ '.nb-action-bar': {
+ borderRadius: token.borderRadiusBlock,
+ marginBottom: `${token.marginBlock / 2}px !important`,
+ },
+
+ '.ant-list-pagination': {
+ borderRadius: token.borderRadiusBlock,
+ marginTop: `${token.marginBlock / 2}px !important`,
+ },
+
'& > .nb-block-item': {
marginBottom: token.marginLG,
'& > .nb-action-bar:has(:first-child:not(:empty))': {
diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx
index 1bcba0f03a..25a946e6b0 100644
--- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx
+++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx
@@ -28,15 +28,10 @@ const itemCss = css`
const gridCardCss = css`
height: 100%;
> .ant-card-body {
- padding: 24px 24px 0px;
height: 100%;
- button {
- margin-bottom: 0px !important;
- margin-top: 5px;
- }
}
.nb-action-bar {
- padding: 5px 0;
+ padding-top: 5px;
}
`;
diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx b/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx
index c9d385dd09..0ad8a32745 100644
--- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx
+++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx
@@ -17,6 +17,7 @@ import { getCardItemSchema } from '../../../block-provider';
import { NocoBaseRecursionField } from '../../../formily/NocoBaseRecursionField';
import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps';
import { withSkeletonComponent } from '../../../hoc/withSkeletonComponent';
+import { useToken } from '../../../style/useToken';
import { SortableItem } from '../../common';
import { SchemaComponentOptions } from '../../core';
import { useDesigner, useProps } from '../../hooks';
@@ -141,6 +142,7 @@ const InternalGridCard = withSkeletonComponent(
},
[fieldSchema.properties],
);
+ const { token } = useToken();
const onPaginationChange: PaginationProps['onChange'] = useCallback(
(page, pageSize) => {
@@ -207,7 +209,7 @@ const InternalGridCard = withSkeletonComponent(
...columnCount,
sm: columnCount.xs,
xl: columnCount.lg,
- gutter: [rowGutter, rowGutter],
+ gutter: [token.marginBlock / 2, token.marginBlock / 2],
}}
renderItem={(item, index) => {
return (
diff --git a/packages/plugins/@nocobase/plugin-block-workbench/src/client/WorkbenchAction.tsx b/packages/plugins/@nocobase/plugin-block-workbench/src/client/WorkbenchAction.tsx
index 889dda2bc0..1b58c9b1f1 100644
--- a/packages/plugins/@nocobase/plugin-block-workbench/src/client/WorkbenchAction.tsx
+++ b/packages/plugins/@nocobase/plugin-block-workbench/src/client/WorkbenchAction.tsx
@@ -18,13 +18,20 @@ import { WorkbenchLayout } from './workbenchBlockSettings';
const useStyles = createStyles(({ token, css }) => ({
// 支持 css object 的写法
action: css`
+ display: flex;
background-color: transparent;
border: 0;
height: auto;
box-shadow: none;
+ padding-top: 8px;
+ `,
+ avatar: css`
+ width: 4em;
`,
title: css`
margin-top: ${token.marginSM}px;
+ width: 100%;
+ white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
`,
@@ -37,8 +44,8 @@ function Button() {
const { layout } = useContext(WorkbenchBlockContext);
const { styles, cx } = useStyles();
return layout === WorkbenchLayout.Grid ? (
-
-
} />
+
+
} />
{fieldSchema.title}
) : (
@@ -55,6 +62,7 @@ export const WorkbenchAction = withDynamicSchemaProps((props) => {
}
confirmTitle={fieldSchema.title}
diff --git a/packages/plugins/@nocobase/plugin-block-workbench/src/client/WorkbenchBlock.tsx b/packages/plugins/@nocobase/plugin-block-workbench/src/client/WorkbenchBlock.tsx
index 697e34e735..e56de6da59 100644
--- a/packages/plugins/@nocobase/plugin-block-workbench/src/client/WorkbenchBlock.tsx
+++ b/packages/plugins/@nocobase/plugin-block-workbench/src/client/WorkbenchBlock.tsx
@@ -7,23 +7,22 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
-import { css } from '@emotion/css';
import { observer, useFieldSchema } from '@formily/react';
import {
CollectionContext,
+ createStyles,
DataSourceContext,
DndContext,
Icon,
NocoBaseRecursionField,
- useBlockHeight,
useDesignable,
+ useOpenModeContext,
useSchemaInitializerRender,
withDynamicSchemaProps,
- useOpenModeContext,
- useBlockHeightProps,
} from '@nocobase/client';
-import { Space, List, Avatar, theme } from 'antd';
-import React, { createContext, useEffect, useState, useRef, useMemo, useLayoutEffect } from 'react';
+import { Avatar, Space } from 'antd';
+import { Grid, List } from 'antd-mobile';
+import React, { createContext } from 'react';
import { WorkbenchLayout } from './workbenchBlockSettings';
const ConfigureActionsButton = observer(
@@ -45,105 +44,27 @@ const ResponsiveSpace = () => {
const isMobileMedia = isMobile();
const { isMobile: underMobileCtx } = useOpenModeContext() || {};
const { itemsPerRow = 4 } = fieldSchema.parent['x-decorator-props'] || {};
- const isUnderMobile = isMobileMedia || underMobileCtx;
- const containerRef = useRef(null); // 引用容器
- const [containerWidth, setContainerWidth] = useState(0); // 容器宽度
- // 使用 ResizeObserver 动态获取容器宽度
- useEffect(() => {
- const handleResize = () => {
- if (containerRef.current) {
- setContainerWidth(containerRef.current.offsetWidth); // 更新宽度
- }
- };
- // 初始化 ResizeObserver
- const resizeObserver = new ResizeObserver(handleResize);
- // 监听容器宽度变化
- if (containerRef.current) {
- resizeObserver.observe(containerRef.current);
- handleResize(); // 初始化时获取一次宽度
- }
-
- return () => {
- if (containerRef.current) {
- resizeObserver.unobserve(containerRef.current);
- }
- };
- }, []);
-
- useLayoutEffect(() => {
- if (!containerRef.current) return;
-
- const observer = new ResizeObserver((entries) => {
- for (const entry of entries) {
- setContainerWidth(entry.contentRect.width); // 更新宽度
- }
- });
-
- observer.observe(containerRef.current);
-
- return () => {
- observer.unobserve(containerRef.current);
- };
- }, []);
-
- // 计算每个元素的宽度
- const itemWidth = useMemo(() => {
- if (isUnderMobile) {
- const totalGapWidth = gap * itemsPerRow;
- const availableWidth = containerWidth - totalGapWidth;
- return availableWidth / itemsPerRow;
- }
- return 70;
- }, [itemsPerRow, gap, containerWidth]);
-
- // 计算 Avatar 的宽度
- const avatarSize = useMemo(() => {
- return isUnderMobile ? (Math.floor(itemWidth * 0.8) > 70 ? 60 : Math.floor(itemWidth * 0.8)) : 54; // Avatar 大小为 item 宽度的 60%
- }, [itemWidth, itemsPerRow, containerWidth]);
+ if (underMobileCtx || isMobileMedia) {
+ return (
+
+ {fieldSchema.mapProperties((s, key) => {
+ return (
+
+
+
+ );
+ })}
+
+ );
+ }
return (
-
-
- {fieldSchema.mapProperties((s, key) => (
-
-
-
- ))}
-
-
+
+ {fieldSchema.mapProperties((s, key) => {
+ return ;
+ })}
+
);
};
@@ -157,36 +78,17 @@ const InternalIcons = () => {
{layout === WorkbenchLayout.Grid ? (
) : (
-
+
{fieldSchema.mapProperties((s, key) => {
const icon = s['x-component-props']?.['icon'];
const backgroundColor = s['x-component-props']?.['iconColor'];
return (
} />}
+ onClick={() => {}}
>
- } />}
- title={}
- >
+
);
})}
@@ -199,44 +101,55 @@ const InternalIcons = () => {
export const WorkbenchBlockContext = createContext({ layout: 'grid' });
+const useStyles = createStyles(({ token, css }) => ({
+ containerClass: css`
+ &.list {
+ margin: -${token.paddingLG}px;
+ border-radius: ${(token as any).borderRadiusBlock}px;
+ overflow: hidden;
+
+ .adm-list {
+ --padding-left: ${token.paddingLG}px;
+ --padding-right: ${token.paddingLG}px;
+
+ .adm-list-item-content-main {
+ display: flex;
+
+ button {
+ background-color: transparent;
+ border: none;
+ height: auto;
+ box-shadow: none;
+ padding: 16px 32px;
+ margin: -12px -32px;
+ width: calc(100% + 64px);
+ text-align: start;
+ color: ${token.colorText};
+ }
+ }
+ }
+
+ button[aria-label*='schema-initializer-WorkbenchBlock.ActionBar-workbench:configureActions'] {
+ margin-bottom: ${token.paddingLG}px;
+ margin-left: ${token.paddingLG}px;
+ }
+ }
+ `,
+}));
+
export const WorkbenchBlock: any = withDynamicSchemaProps(
(props) => {
const fieldSchema = useFieldSchema();
const { layout = 'grid' } = fieldSchema['x-component-props'] || {};
- const { title } = fieldSchema['x-decorator-props'] || {};
- const targetHeight = useBlockHeight();
- const { token } = theme.useToken();
- const { designable } = useDesignable();
- const titleHeight = title ? token.fontSizeLG * token.lineHeightLG + token.padding * 2 - 1 : 0;
- const internalHeight = 2 * token.paddingLG + token.controlHeight + token.marginLG + titleHeight;
- const warperHeight =
- targetHeight - (designable ? internalHeight : 2 * token.paddingLG + token.marginLG + titleHeight);
- const targetWarperHeight = warperHeight > 0 ? warperHeight + 'px' : '100%';
+ const { styles } = useStyles();
+
return (
-
-
-
-
- {props.children}
-
-
-
+
+
+
+ {props.children}
+
+
);
},
diff --git a/packages/plugins/@nocobase/plugin-mobile/src/client/__e2e__/zIndex.test.ts b/packages/plugins/@nocobase/plugin-mobile/src/client/__e2e__/zIndex.test.ts
index c7b1b58bc8..74e3208e35 100644
--- a/packages/plugins/@nocobase/plugin-mobile/src/client/__e2e__/zIndex.test.ts
+++ b/packages/plugins/@nocobase/plugin-mobile/src/client/__e2e__/zIndex.test.ts
@@ -56,14 +56,27 @@ test.describe('zIndex', () => {
await page.getByLabel('Close lightbox').click();
// 3. 进入第二层子页面,然后点击图片预览, 图片不能被子页面盖住
- await page.getByLabel('action-Action-Edit-update-').click();
+ await page.getByLabel('action-Action-Edit-update-').click({
+ position: {
+ x: 5,
+ y: 5,
+ },
+ });
await page.getByRole('link', { name: title }).nth(2).click();
await page.waitForTimeout(300);
await check(2);
await page.getByLabel('Close lightbox').click();
// 4. 进入第三层子页面,然后点击图片预览, 图片不能被子页面盖住
- await page.getByLabel('action-Action-Edit-update-').nth(2).click();
+ await page
+ .getByLabel('action-Action-Edit-update-')
+ .nth(2)
+ .click({
+ position: {
+ x: 5,
+ y: 5,
+ },
+ });
await page.getByRole('link', { name: title }).nth(3).click();
await page.waitForTimeout(300);
await check(3);
diff --git a/packages/plugins/@nocobase/plugin-mobile/src/client/mobile-blocks/settings-block/MobileSettings.tsx b/packages/plugins/@nocobase/plugin-mobile/src/client/mobile-blocks/settings-block/MobileSettings.tsx
index bf5e00692a..c7d734fed7 100644
--- a/packages/plugins/@nocobase/plugin-mobile/src/client/mobile-blocks/settings-block/MobileSettings.tsx
+++ b/packages/plugins/@nocobase/plugin-mobile/src/client/mobile-blocks/settings-block/MobileSettings.tsx
@@ -16,8 +16,10 @@ export const InternalSettings = () => {
const style = useMemo(() => {
return {
marginBottom: token.marginBlock,
+ borderRadius: token.borderRadiusBlock,
+ overflow: 'hidden',
};
- }, [token.marginBlock]);
+ }, [token.borderRadiusBlock, token.marginBlock]);
return (
diff --git a/packages/plugins/@nocobase/plugin-mobile/src/client/mobile/Mobile.tsx b/packages/plugins/@nocobase/plugin-mobile/src/client/mobile/Mobile.tsx
index 62b2600862..5e99193c84 100644
--- a/packages/plugins/@nocobase/plugin-mobile/src/client/mobile/Mobile.tsx
+++ b/packages/plugins/@nocobase/plugin-mobile/src/client/mobile/Mobile.tsx
@@ -23,6 +23,7 @@ import {
import React from 'react';
import { isDesktop } from 'react-device-detect';
+import { theme } from 'antd';
import { ActionDrawerUsedInMobile, useToAdaptActionDrawerToMobile } from '../adaptor-of-desktop/ActionDrawer';
import { useToAdaptFilterActionToMobile } from '../adaptor-of-desktop/FilterAction';
import { InternalPopoverNesterUsedInMobile } from '../adaptor-of-desktop/InternalPopoverNester';
@@ -92,11 +93,13 @@ export const Mobile = () => {
diff --git a/packages/plugins/@nocobase/plugin-mobile/src/client/mobile/styles.ts b/packages/plugins/@nocobase/plugin-mobile/src/client/mobile/styles.ts
index e43e31397e..daf87c36ca 100644
--- a/packages/plugins/@nocobase/plugin-mobile/src/client/mobile/styles.ts
+++ b/packages/plugins/@nocobase/plugin-mobile/src/client/mobile/styles.ts
@@ -8,43 +8,30 @@
*/
import { genStyleHook } from '@nocobase/client';
-import { PageBackgroundColor } from '../constants';
export const useStyles = genStyleHook('nb-mobile', (token) => {
const { componentCls } = token;
return {
[componentCls]: {
+ // 调整移动端 Grid card 区块顶部按钮和卡片之间的间距
+ '--nb-spacing': '12px',
+
WebkitOverflowScrolling: 'touch',
display: 'initial',
'& ::-webkit-scrollbar': {
display: 'none',
},
- body: {
- backgroundColor: PageBackgroundColor,
- },
'.nb-details .ant-formily-item-feedback-layout-loose': {
marginBottom: '5px',
},
'.nb-details .ant-formily-item-layout-vertical .ant-formily-item-label': {
marginBottom: '-8px',
},
- '.ant-card .ant-card-body': {
- paddingBottom: '10px',
- paddingTop: '10px',
- },
'.ant-pagination-simple': {
marginTop: '0px !important',
},
- '.nb-action-penal-container': {
- marginTop: '-10px',
- marginBottom: '-10px',
- },
- '.nb-action-penal-container button[aria-label*="schema-initializer-WorkbenchBlock.ActionBar-workbench:configureActions"]':
- {
- marginBottom: '10px',
- },
'.ant-list-item': {
paddingTop: '8px',
paddingBottom: '8px',
@@ -58,9 +45,6 @@ export const useStyles = genStyleHook('nb-mobile', (token) => {
paddingBottom: '0px',
paddingTop: '0px',
},
- '.nb-chart-block .noco-card-item': {
- marginBottom: '-13px',
- },
'.ant-table-thead button[aria-label*="schema-initializer-TableV2-table:configureColumns"] > span:last-child': {
display: 'none !important',
},
@@ -87,22 +71,6 @@ export const useStyles = genStyleHook('nb-mobile', (token) => {
'.ant-pagination .ant-pagination-item': {
display: 'none',
},
- '.ant-card-body .nb-action-bar .ant-btn': {
- justifyContent: 'space-between',
- display: 'flex',
- alignItems: 'center',
- gap: '8px',
- '& span': {
- display: 'contents',
- },
- },
- '.ant-card-body .nb-action-bar .ant-btn-icon': {
- marginInlineEnd: '0px !important',
- },
- '.ant-card-body .nb-table-container': {
- marginRight: '-20px',
- marginLeft: '-10px',
- },
'.nb-action-bar button[aria-label*="schema-initializer-ActionBar-table:configureActions"] > span:last-child': {
display: 'none !important',
},
@@ -121,6 +89,11 @@ export const useStyles = genStyleHook('nb-mobile', (token) => {
'[data-menu-id$="-theme"]': {
display: 'none',
},
+
+ '& > .ant-menu > .ant-menu-item': {
+ marginInline: 8,
+ width: `calc(100% - 16px)`,
+ },
},
},
};
diff --git a/packages/plugins/@nocobase/plugin-mobile/src/client/pages/dynamic-page/content/MobilePageContentContainer.tsx b/packages/plugins/@nocobase/plugin-mobile/src/client/pages/dynamic-page/content/MobilePageContentContainer.tsx
index b474e08622..1285cf538a 100644
--- a/packages/plugins/@nocobase/plugin-mobile/src/client/pages/dynamic-page/content/MobilePageContentContainer.tsx
+++ b/packages/plugins/@nocobase/plugin-mobile/src/client/pages/dynamic-page/content/MobilePageContentContainer.tsx
@@ -7,12 +7,16 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
+import { useToken } from '@nocobase/client';
import _ from 'lodash';
import React, { FC, useEffect } from 'react';
+import { PageBackgroundColor } from '../../../constants';
export const MobilePageContentContainer: FC<{ hideTabBar?: boolean }> = ({ children, hideTabBar }) => {
const [mobileTabBarHeight, setMobileTabBarHeight] = React.useState(0);
const [mobilePageHeader, setMobilePageHeader] = React.useState(0);
+ const { token } = useToken();
+
useEffect(() => {
const navigationBar = _.last(document.querySelectorAll('.mobile-page-header'));
setMobilePageHeader(navigationBar?.offsetHeight);
@@ -34,6 +38,9 @@ export const MobilePageContentContainer: FC<{ hideTabBar?: boolean }> = ({ child
boxSizing: 'border-box',
maxWidth: '100%',
overflowX: 'hidden',
+ backgroundColor: PageBackgroundColor,
+ paddingInline: token.paddingPageHorizontal,
+ paddingBlock: token.paddingPageVertical,
}}
>
{children}