diff --git a/packages/core/client/package.json b/packages/core/client/package.json index ea842dd3a6..a66a9d7fc7 100644 --- a/packages/core/client/package.json +++ b/packages/core/client/package.json @@ -15,7 +15,7 @@ "@dnd-kit/modifiers": "^6.0.0", "@dnd-kit/sortable": "^6.0.0", "@emotion/css": "^11.7.1", - "@formily/antd-v5": "^1.1.0", + "@formily/antd-v5": "^1.1.1", "@formily/core": "^2.2.27", "@formily/grid": "^2.2.27", "@formily/json-schema": "^2.2.27", @@ -30,7 +30,7 @@ "@nocobase/utils": "0.13.0-alpha.3", "@types/requirejs": "^2.1.34", "ahooks": "^3.7.2", - "antd": "^5.7.3", + "antd": "5.8.4", "antd-style": "^3.3.0", "axios": "^0.26.1", "classnames": "^2.3.1", diff --git a/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx b/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx index e6a7dc0cd0..09d063f07a 100644 --- a/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx +++ b/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx @@ -1,8 +1,6 @@ -import { Cascader } from '@formily/antd-v5'; import { useField, useForm } from '@formily/react'; -import { Input, Select, Spin, Table, Tag } from 'antd'; +import { Cascader, Input, Select, Spin, Table, Tag } from 'antd'; import { last } from 'lodash'; -import { boolean } from 'mathjs'; import React, { useContext, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ResourceActionContext, useCompile } from '../../../'; diff --git a/packages/core/client/src/global-theme/type.ts b/packages/core/client/src/global-theme/type.ts index 014de53441..40779b727d 100644 --- a/packages/core/client/src/global-theme/type.ts +++ b/packages/core/client/src/global-theme/type.ts @@ -1,4 +1,4 @@ -import { MappingAlgorithm } from 'antd/es/config-provider/context'; +import { MappingAlgorithm } from 'antd-style'; import { OverrideToken } from 'antd/es/theme/interface'; import { AliasToken } from 'antd/es/theme/internal'; diff --git a/packages/core/client/src/schema-component/antd/action/Action.tsx b/packages/core/client/src/schema-component/antd/action/Action.tsx index 1f75d11c65..bcea781d6a 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.tsx @@ -1,5 +1,5 @@ import { observer, RecursionField, useField, useFieldSchema, useForm } from '@formily/react'; -import { App, Button, Popover } from 'antd'; +import { App, Button } from 'antd'; import classnames from 'classnames'; import lodash from 'lodash'; import React, { useEffect, useState } from 'react'; @@ -11,6 +11,7 @@ import { useRecord } from '../../../record-provider'; import { SortableItem } from '../../common'; import { useCompile, useComponent, useDesigner } from '../../hooks'; import { useProps } from '../../hooks/useProps'; +import { Popover } from '../popover'; import ActionContainer from './Action.Container'; import { ActionDesigner } from './Action.Designer'; import { ActionDrawer } from './Action.Drawer'; diff --git a/packages/core/client/src/schema-component/antd/association-field/InternalPopoverNester.tsx b/packages/core/client/src/schema-component/antd/association-field/InternalPopoverNester.tsx index ec090f5c91..7b68398587 100644 --- a/packages/core/client/src/schema-component/antd/association-field/InternalPopoverNester.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/InternalPopoverNester.tsx @@ -1,13 +1,13 @@ -import { Popover } from 'antd'; -import { css } from '@emotion/css'; import { EditOutlined } from '@ant-design/icons'; +import { css } from '@emotion/css'; import { observer } from '@formily/react'; import React, { useContext, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { ReadPrettyInternalViewer } from './InternalViewer'; +import { ActionContext, ActionContextProvider } from '../action/context'; +import { Popover } from '../popover'; import { InternalNester } from './InternalNester'; +import { ReadPrettyInternalViewer } from './InternalViewer'; import { useAssociationFieldContext } from './hooks'; -import { ActionContextProvider, ActionContext } from '../action/context'; export const InternaPopoverNester = observer( (props) => { diff --git a/packages/core/client/src/schema-component/antd/date-picker/__tests__/date-picker.test.tsx b/packages/core/client/src/schema-component/antd/date-picker/__tests__/date-picker.test.tsx index 95ab97a60e..6f9a07d020 100644 --- a/packages/core/client/src/schema-component/antd/date-picker/__tests__/date-picker.test.tsx +++ b/packages/core/client/src/schema-component/antd/date-picker/__tests__/date-picker.test.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { render, screen, sleep, userEvent, waitFor } from 'testUtils'; import App1 from '../demos/demo1'; +import App11 from '../demos/demo11'; import App2 from '../demos/demo2'; import App3 from '../demos/demo3'; import App4 from '../demos/demo4'; @@ -68,8 +69,11 @@ describe('DatePicker', () => { await userEvent.click(picker); await userEvent.type(input, '2023/05/01'); - const selected = document.querySelector('.ant-picker-cell-selected') as HTMLElement; - expect(selected).toBeInTheDocument(); + let selected; + await waitFor(() => { + selected = document.querySelector('.ant-picker-cell-selected') as HTMLElement; + expect(selected).toBeInTheDocument(); + }); await userEvent.click(selected); expect(input).toHaveValue('2023/05/01'); @@ -138,15 +142,20 @@ describe('RangePicker', () => { const endInput = getByPlaceholderText('End date'); await userEvent.click(picker); + await sleep(); await userEvent.click(document.querySelector('[title="2023-05-01"]') as HTMLElement); await userEvent.click(document.querySelector('[title="2023-05-02"]') as HTMLElement); - expect(startInput).toHaveValue('2023-05-01'); - expect(endInput).toHaveValue('2023-05-02'); + await waitFor(() => expect(startInput).toHaveValue('2023-05-01')); + await waitFor(() => expect(endInput).toHaveValue('2023-05-02')); + // Read pretty - expect(screen.getByText('2023-05-01~2023-05-02', { selector: '.ant-description-text' })).toBeInTheDocument(); + await waitFor(() => + expect(screen.getByText('2023-05-01~2023-05-02', { selector: '.ant-description-text' })).toBeInTheDocument(), + ); + // Value - expect(screen.getByText('2023-05-01 ~ 2023-05-02')).toBeInTheDocument(); + await waitFor(() => expect(screen.getByText('2023-05-01 ~ 2023-05-02')).toBeInTheDocument()); }); it('showTime=false,gmt=true,utc=true', async () => { @@ -219,4 +228,25 @@ describe('RangePicker', () => { expect(screen.getByText(`${currentDateString}T00:00:00.000Z`)).toBeInTheDocument(); }); }); + + // fix T-1506 + it('shortcut', async () => { + const { container } = render(); + + await sleep(); + + const picker = container.querySelector('.ant-picker') as HTMLElement; + const startInput = screen.getByPlaceholderText('Start date'); + const endInput = screen.getByPlaceholderText('End date'); + + await userEvent.click(picker); + + // shortcut: Today + await userEvent.click(screen.getByText(/today/i)); + await sleep(); + + // 因为 Today 快捷键的值是动态生成的,所以这里没有断言具体的值 + await waitFor(() => expect(startInput.getAttribute('value')).toBeTruthy()); + await waitFor(() => expect(endInput.getAttribute('value')).toBeTruthy()); + }); }); diff --git a/packages/core/client/src/schema-component/antd/date-picker/demos/demo11.tsx b/packages/core/client/src/schema-component/antd/date-picker/demos/demo11.tsx new file mode 100644 index 0000000000..1cd60ac4d6 --- /dev/null +++ b/packages/core/client/src/schema-component/antd/date-picker/demos/demo11.tsx @@ -0,0 +1,65 @@ +/** + * title: DatePicker.RangePicker + */ +import { FormItem } from '@formily/antd-v5'; +import { DatePicker, Input, SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; +import React from 'react'; + +const schema = { + type: 'object', + properties: { + input: { + type: 'boolean', + title: `Editable`, + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + gmt: true, + }, + 'x-reactions': [ + { + target: 'read1', + fulfill: { + state: { + value: '{{$self.value}}', + }, + }, + }, + { + target: 'read2', + fulfill: { + state: { + value: '{{$self.value && $self.value.join(" ~ ")}}', + }, + }, + }, + ], + }, + read1: { + type: 'boolean', + title: `Read pretty`, + 'x-read-pretty': true, + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker.RangePicker', + 'x-component-props': { + gmt: true, + }, + }, + read2: { + type: 'string', + title: `Value`, + 'x-read-pretty': true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + 'x-component-props': {}, + }, + }, +}; + +export default () => { + return ( + + + + ); +}; diff --git a/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx b/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx index 2faac33c20..2edc93f6a5 100644 --- a/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx +++ b/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx @@ -1,13 +1,14 @@ import { css } from '@emotion/css'; import { createForm, Field, Form } from '@formily/core'; import { observer, useField, useFieldSchema, useForm } from '@formily/react'; -import { Button, Popover, Space } from 'antd'; -import React, { createContext, useContext, useMemo, useState } from 'react'; +import { Button, Space } from 'antd'; +import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { FormProvider, SchemaComponent } from '../../core'; import { useDesignable } from '../../hooks'; import { useProps } from '../../hooks/useProps'; import { Action } from '../action'; +import { Popover } from '../popover'; export const FilterActionContext = createContext(null); @@ -20,15 +21,17 @@ export const FilterAction = observer( const fieldSchema = useFieldSchema(); const form = useMemo
(() => props.form || createForm(), []); const { options, onSubmit, onReset, ...others } = useProps(props); + const onOpenChange = useCallback((visible: boolean): void => { + setVisible(visible); + }, []); + return ( { - setVisible(visible); - }} + onOpenChange={onOpenChange} trigger={'click'} content={ diff --git a/packages/core/client/src/schema-component/antd/icon-picker/IconPicker.tsx b/packages/core/client/src/schema-component/antd/icon-picker/IconPicker.tsx index 71bafad26f..1062bc4cd9 100644 --- a/packages/core/client/src/schema-component/antd/icon-picker/IconPicker.tsx +++ b/packages/core/client/src/schema-component/antd/icon-picker/IconPicker.tsx @@ -2,10 +2,11 @@ import { CloseOutlined, LoadingOutlined } from '@ant-design/icons'; import { useFormLayout } from '@formily/antd-v5'; import { connect, mapProps, mapReadPretty } from '@formily/react'; import { isValid } from '@formily/shared'; -import { Button, Input, Popover } from 'antd'; +import { Button, Input } from 'antd'; import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Icon, hasIcon, icons } from '../../../icon'; +import { Popover } from '../popover'; function IconField(props: any) { const layout = useFormLayout(); diff --git a/packages/core/client/src/schema-component/antd/index.ts b/packages/core/client/src/schema-component/antd/index.ts index fd5b21bc48..a135753b3b 100644 --- a/packages/core/client/src/schema-component/antd/index.ts +++ b/packages/core/client/src/schema-component/antd/index.ts @@ -35,6 +35,7 @@ export * from './page'; export * from './pagination'; export * from './password'; export * from './percent'; +export * from './popover'; export * from './preview'; export * from './quick-edit'; export * from './radio'; diff --git a/packages/core/client/src/schema-component/antd/input/EllipsisWithTooltip.tsx b/packages/core/client/src/schema-component/antd/input/EllipsisWithTooltip.tsx index 408b66a930..9f97c597b7 100644 --- a/packages/core/client/src/schema-component/antd/input/EllipsisWithTooltip.tsx +++ b/packages/core/client/src/schema-component/antd/input/EllipsisWithTooltip.tsx @@ -1,5 +1,5 @@ -import { Popover } from 'antd'; -import React, { CSSProperties, forwardRef, useImperativeHandle, useState, useRef } from 'react'; +import React, { CSSProperties, forwardRef, useImperativeHandle, useRef, useState } from 'react'; +import { Popover } from '../popover'; const getContentWidth = (element) => { if (element) { diff --git a/packages/core/client/src/schema-component/antd/popover/Popover.tsx b/packages/core/client/src/schema-component/antd/popover/Popover.tsx new file mode 100644 index 0000000000..43fb91db35 --- /dev/null +++ b/packages/core/client/src/schema-component/antd/popover/Popover.tsx @@ -0,0 +1,16 @@ +import { Popover as AntdPopover, PopoverProps } from 'antd'; +import React, { useCallback } from 'react'; + +export const Popover = (props: PopoverProps) => { + // 参见:https://github.com/ant-design/ant-design/issues/44119 + // fix T-1508 + const avoidClose = useCallback((e: React.MouseEvent) => { + e.stopPropagation(); + }, []); + + return ( +
+ +
+ ); +}; diff --git a/packages/core/client/src/schema-component/antd/popover/index.ts b/packages/core/client/src/schema-component/antd/popover/index.ts new file mode 100644 index 0000000000..8f473de4b9 --- /dev/null +++ b/packages/core/client/src/schema-component/antd/popover/index.ts @@ -0,0 +1 @@ +export * from './Popover'; diff --git a/packages/core/client/src/schema-component/antd/quick-edit/QuickEdit.tsx b/packages/core/client/src/schema-component/antd/quick-edit/QuickEdit.tsx index ed5de34057..e526a9fd43 100644 --- a/packages/core/client/src/schema-component/antd/quick-edit/QuickEdit.tsx +++ b/packages/core/client/src/schema-component/antd/quick-edit/QuickEdit.tsx @@ -2,9 +2,9 @@ import { css } from '@emotion/css'; import { FormItem } from '@formily/antd-v5'; import { Field, createForm } from '@formily/core'; import { FormContext, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { Popover } from 'antd'; import React, { useMemo, useRef } from 'react'; import { useCollectionManager } from '../../../collection-manager'; +import { Popover } from '../popover'; export const Editable = observer((props) => { const field: any = useField(); diff --git a/packages/plugins/charts/src/client/select/CustomSelect.tsx b/packages/plugins/charts/src/client/select/CustomSelect.tsx index 7061682b55..1e5c364f83 100644 --- a/packages/plugins/charts/src/client/select/CustomSelect.tsx +++ b/packages/plugins/charts/src/client/select/CustomSelect.tsx @@ -1,9 +1,9 @@ import { LoadingOutlined } from '@ant-design/icons'; import { connect, mapProps, mapReadPretty } from '@formily/react'; import { isValid } from '@formily/shared'; -import { css, Icon } from '@nocobase/client'; +import { Icon, Popover, css } from '@nocobase/client'; import type { SelectProps } from 'antd'; -import { Popover, Select as AntdSelect } from 'antd'; +import { Select as AntdSelect } from 'antd'; import React from 'react'; import { lang } from '../locale'; import { ReadPretty } from './ReadPretty'; @@ -35,7 +35,7 @@ const InternalSelect = connect( > {group1.map((option) => ( - {group2.map((option) => ( -