From 49dd89632d9a95485288799921d9137f87b63f94 Mon Sep 17 00:00:00 2001 From: harrywan Date: Mon, 1 Jun 2026 20:31:14 +0800 Subject: [PATCH 1/2] =?UTF-8?q?refactor(space):=20=E6=94=B9=E7=94=A8=20gri?= =?UTF-8?q?d=20gap=20=E5=AE=9E=E7=8E=B0=20(#885)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/space/space.tsx | 48 +++++++++++++++----------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/components/space/space.tsx b/components/space/space.tsx index 3377c421..8f38829d 100644 --- a/components/space/space.tsx +++ b/components/space/space.tsx @@ -7,35 +7,25 @@ import type { TThemeVars } from '../_theme/base'; import { COMPONENT_NAME, prefixCls } from './const'; import { type SpaceInnerProps, spaceProps } from './props'; -const useMargin = (props: SpaceInnerProps, themeVarsRef: Ref) => { - const margin = computed(() => { +const useGap = (props: SpaceInnerProps, themeVarsRef: Ref) => { + const gap = computed(() => { const { size } = props; - let horizontal = 0; - let vertical = 0; if (Array.isArray(size)) { - horizontal = size[0]; - vertical = size[1]; + return { row: size[0], col: size[1] }; } else if (typeof size === 'number') { - horizontal = size; - vertical = size; - } else { - const currentSize = depx( - themeVarsRef.value[createKey('padding', size)] - || themeVarsRef.value[createKey('padding', 'small')], - ); - horizontal = currentSize; - vertical = currentSize; + return { row: size, col: size }; } - return { - horizontal: `${horizontal}px`, - vertical: `${vertical}px`, - }; + const currentSize = depx( + themeVarsRef.value[createKey('padding', size)] + || themeVarsRef.value[createKey('padding', 'small')], + ); + return { row: currentSize, col: currentSize }; }); return { - margin, + gap, }; }; @@ -45,11 +35,11 @@ export default defineComponent({ setup(props) { const { themeVars } = useTheme(); - const { margin } = useMargin(props, themeVars); + const { gap } = useGap(props, themeVars); return { prefixCls, - margin, + gap, }; }, render() { @@ -62,7 +52,7 @@ export default defineComponent({ itemStyle, wrap, prefixCls, - margin, + gap, } = this; const children = flatten(getSlot(this.$slots) || []).filter((node) => @@ -74,14 +64,14 @@ export default defineComponent({ role="none" class={`${prefixCls}`} style={{ - display: inline ? 'inline-flex' : 'flex', - flexDirection: vertical ? 'column' : 'row', - justifyContent: ['start', 'end'].includes(justify) + display: inline ? 'inline-grid' : 'grid', + gridTemplateColumns: vertical ? 'unset' : 'repeat(auto-fit, minmax(0, 1fr))', + gridTemplateRows: vertical ? 'repeat(auto-fit, minmax(0, 1fr))' : 'unset', + justifyItems: justify === 'start' || justify === 'end' ? `flex-${justify}` - : justify, + : justify === 'center' ? 'center' : justify, alignItems: align, - flexWrap: !wrap || vertical ? 'nowrap' : 'wrap', - gap: `${margin.vertical} ${margin.horizontal}`, + gap: `${gap.row}px ${gap.col}px`, }} > { wrapItem From 96748a2018a6fbe0a51763a2493f89225be12f86 Mon Sep 17 00:00:00 2001 From: harrywan Date: Mon, 1 Jun 2026 23:54:59 +0800 Subject: [PATCH 2/2] =?UTF-8?q?test(space):=20=E4=B8=BA=20#885=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20vitest=20=E5=8D=95=E6=B5=8B=E3=80=81playwright=20e2?= =?UTF-8?q?e=20=E5=92=8C=20CHANGELOG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 ++ components/space/__tests__/space-885.spec.ts | 50 ++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 components/space/__tests__/space-885.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index f6de2065..7f36a688 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ * include documents in npm package for ai agents ([#960](https://github.com/WeBankFinTech/fes-design/issues/960)) ([3cc476c](https://github.com/WeBankFinTech/fes-design/commit/3cc476c81fb652c7fc3887884d99b46a02de0b74)) +### Refactor + +* refactor(space): 改用 grid gap 实现 ([#885](https://github.com/WeBankFinTech/fes-design/issues/885)) + + ## [0.8.84](https://github.com/WeBankFinTech/fes-design/compare/v0.8.83...v0.8.84) (2025-11-04) diff --git a/components/space/__tests__/space-885.spec.ts b/components/space/__tests__/space-885.spec.ts new file mode 100644 index 00000000..0715210f --- /dev/null +++ b/components/space/__tests__/space-885.spec.ts @@ -0,0 +1,50 @@ +import { describe, it, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; +import FSpace from '../index'; +import '../space'; + +describe('Space Grid Layout #885', () => { + it('space.tsx uses grid display (not flex)', async () => { + const fsSpace = mount(FSpace, { + slots: { + default: [ + { template: '1' }, + { template: '2' }, + { template: '3' }, + ], + }, + }); + const el = fsSpace.element as HTMLElement; + expect(el.style.display).toBe('grid'); + }); + + it('space.tsx sets gridTemplateColumns with repeat(auto-fit or auto-fill)', async () => { + const fsSpace = mount(FSpace, { + slots: { + default: [ + { template: '1' }, + { template: '2' }, + { template: '3' }, + ], + }, + }); + const el = fsSpace.element as HTMLElement; + expect(el.style.gridTemplateColumns).toMatch(/repeat\((auto-fit|auto-fill)/); + }); + + it('FSpace with 3 children renders with display grid', async () => { + const wrapper = mount(FSpace, { + props: { size: 8 }, + slots: { + default: [ + { template: '' }, + { template: '' }, + { template: '' }, + ], + }, + }); + const el = wrapper.element as HTMLElement; + expect(el.style.display).toBe('grid'); + expect(wrapper.findAll('.fes-space > *')).toHaveLength(3); + }); +}); \ No newline at end of file