perf: form item (#1171)

Co-authored-by: sealday <sealday@gmail.com>
Reviewed-on: daoyoucloud/tachybase#1171
This commit is contained in:
sealday 2024-06-13 03:46:45 +08:00
parent c1d1a70eaf
commit 943db605c8
6 changed files with 92 additions and 86 deletions

View File

@ -1,7 +1,9 @@
import { observer, RecursionField, useField, useFieldSchema } from '@tachybase/schema';
import { Input, Select } from 'antd';
import { differenceBy, unionBy } from 'lodash';
import React, { useContext, useMemo, useState } from 'react'; import React, { useContext, useMemo, useState } from 'react';
import { observer, RecursionField, useField, useFieldSchema } from '@tachybase/schema';
import { Select, Space } from 'antd';
import { differenceBy, unionBy } from 'lodash';
import { import {
FormProvider, FormProvider,
RecordPickerContext, RecordPickerContext,
@ -9,7 +11,7 @@ import {
SchemaComponentOptions, SchemaComponentOptions,
useActionContext, useActionContext,
} from '../..'; } from '../..';
import { CollectionProvider_deprecated, RecordProvider, useFormBlockContext, useCollectionRecordData } from '../../../'; import { CollectionProvider_deprecated, RecordProvider, useCollectionRecordData, useFormBlockContext } from '../../../';
import { import {
TableSelectorParamsProvider, TableSelectorParamsProvider,
useTableSelectorProps as useTsp, useTableSelectorProps as useTsp,
@ -133,7 +135,7 @@ export const InternalPicker = observer(
}; };
return ( return (
<> <>
<Input.Group compact style={{ display: 'flex', lineHeight: '32px' }}> <Space.Compact style={{ display: 'flex', lineHeight: '32px' }}>
<div style={{ width: '100%' }}> <div style={{ width: '100%' }}>
<Select <Select
role="button" role="button"
@ -181,7 +183,7 @@ export const InternalPicker = observer(
/> />
</RecordProvider> </RecordProvider>
)} )}
</Input.Group> </Space.Compact>
<ActionContextProvider <ActionContextProvider
value={{ value={{
openSize: fieldSchema['x-component-props']?.['openSize'] || openSize, openSize: fieldSchema['x-component-props']?.['openSize'] || openSize,

View File

@ -1,6 +1,6 @@
import React, { useEffect, useMemo } from 'react'; import React, { useEffect, useMemo } from 'react';
import { FormItem as Item } from '@tachybase/components'; import { FormItem as Item } from '@tachybase/components';
import { Field, observer, useField, useFieldSchema } from '@tachybase/schema'; import { Field, useField, useFieldSchema } from '@tachybase/schema';
import { createStyles } from 'antd-style'; import { createStyles } from 'antd-style';
import cx from 'classnames'; import cx from 'classnames';
@ -39,8 +39,7 @@ const useStyles = createStyles(({ css }) => {
}; };
}); });
export const FormItem: any = observer( export const FormItem = (props: any) => {
(props: any) => {
const { styles } = useStyles(); const { styles } = useStyles();
const { layoutDirection: selfLayoutDirection } = props; const { layoutDirection: selfLayoutDirection } = props;
const field = useField<Field>(); const field = useField<Field>();
@ -98,9 +97,9 @@ export const FormItem: any = observer(
</BlockItem> </BlockItem>
</CollectionFieldProvider> </CollectionFieldProvider>
); );
}, };
{ displayName: 'FormItem' },
); FormItem.displayName = 'FormItem';
FormItem.Designer = function Designer() { FormItem.Designer = function Designer() {
const app = useApp(); const app = useApp();

View File

@ -1,11 +1,13 @@
import { Input, Select } from 'antd';
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { Select, Space } from 'antd';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useFormBlockContext } from '../../block-provider'; import { useFormBlockContext } from '../../block-provider';
import { useRecord } from '../../record-provider'; import { useRecord } from '../../record-provider';
import { Variable } from '.././../schema-component'; import { Variable } from '.././../schema-component';
import { useCompatOldVariables } from '../VariableInput/VariableInput';
import { useVariableOptions } from '../VariableInput/hooks/useVariableOptions'; import { useVariableOptions } from '../VariableInput/hooks/useVariableOptions';
import { useCompatOldVariables } from '../VariableInput/VariableInput';
import { DynamicComponent } from './DynamicComponent'; import { DynamicComponent } from './DynamicComponent';
const { Option } = Select; const { Option } = Select;
@ -104,7 +106,7 @@ export const ValueDynamicComponent = (props: ValueDynamicComponentProps) => {
}; };
return ( return (
<Input.Group compact> <Space.Compact>
<Select <Select
// @ts-ignore // @ts-ignore
role="button" role="button"
@ -123,6 +125,6 @@ export const ValueDynamicComponent = (props: ValueDynamicComponentProps) => {
<Option value="empty">{t('Empty')}</Option> <Option value="empty">{t('Empty')}</Option>
</Select> </Select>
{modeMap[mode]} {modeMap[mode]}
</Input.Group> </Space.Compact>
); );
}; };

View File

@ -1293,7 +1293,7 @@ export const SchemaSettingsLinkageRules = function LinkageRules(props) {
'x-use-component-props': () => { 'x-use-component-props': () => {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
const options = useLinkageCollectionFilterOptions(collectionName); const options = useLinkageCollectionFilterOptions(collectionName);
return { const result = {
options, options,
defaultValues: gridSchema?.['x-linkage-rules'] || fieldSchema?.['x-linkage-rules'], defaultValues: gridSchema?.['x-linkage-rules'] || fieldSchema?.['x-linkage-rules'],
type, type,
@ -1306,6 +1306,7 @@ export const SchemaSettingsLinkageRules = function LinkageRules(props) {
record, record,
formBlockType, formBlockType,
}; };
return result;
}, },
}, },
}, },

View File

@ -1,11 +1,13 @@
import React, { useState } from 'react';
import { CheckCircleOutlined, CloseCircleOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; import { CheckCircleOutlined, CloseCircleOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import { isVoidField } from '@formily/core'; import { isVoidField } from '@formily/core';
import { connect, mapProps, ReactFC } from '@formily/react'; import { connect, mapProps, ReactFC } from '@formily/react';
import { Popover, Tooltip } from 'antd'; import { Popover, Tooltip } from 'antd';
import cls from 'classnames'; import cx from 'classnames';
import React, { useState } from 'react';
import { FormLayoutShallowContext } from '../form-layout';
import { pickDataProps, usePrefixCls } from '../__builtins__'; import { pickDataProps, usePrefixCls } from '../__builtins__';
import { FormLayoutShallowContext } from '../form-layout';
import { useFormItemLayout, useOverflow } from './hooks'; import { useFormItemLayout, useOverflow } from './hooks';
import useStyle from './style'; import useStyle from './style';
import { IFormItemProps } from './types'; import { IFormItemProps } from './types';
@ -88,7 +90,7 @@ export const BaseItem: React.FC<React.PropsWithChildren<IFormItemProps>> = ({ ch
placement="top" placement="top"
content={ content={
<div <div
className={cls({ className={cx({
[`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus, [`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus,
[`${prefixCls}-help`]: true, [`${prefixCls}-help`]: true,
})} })}
@ -155,7 +157,7 @@ export const BaseItem: React.FC<React.PropsWithChildren<IFormItemProps>> = ({ ch
if (!label) return null; if (!label) return null;
return ( return (
<div <div
className={cls({ className={cx({
[`${prefixCls}-label`]: true, [`${prefixCls}-label`]: true,
[`${prefixCls}-label-tooltip`]: (tooltip && tooltipLayout === 'text') || overflow, [`${prefixCls}-label-tooltip`]: (tooltip && tooltipLayout === 'text') || overflow,
[`${prefixCls}-item-col-${labelCol}`]: enableCol && !!labelCol, [`${prefixCls}-item-col-${labelCol}`]: enableCol && !!labelCol,
@ -177,7 +179,7 @@ export const BaseItem: React.FC<React.PropsWithChildren<IFormItemProps>> = ({ ch
...gridStyles, ...gridStyles,
}} }}
data-grid-span={props.gridSpan} data-grid-span={props.gridSpan}
className={cls( className={cx(
props.className, props.className,
{ {
[`${prefixCls}`]: true, [`${prefixCls}`]: true,
@ -211,28 +213,28 @@ export const BaseItem: React.FC<React.PropsWithChildren<IFormItemProps>> = ({ ch
> >
{renderLabel()} {renderLabel()}
<div <div
className={cls({ className={cx({
[`${prefixCls}-control`]: true, [`${prefixCls}-control`]: true,
[`${prefixCls}-item-col-${wrapperCol}`]: enableCol && !!wrapperCol && label, [`${prefixCls}-item-col-${wrapperCol}`]: enableCol && !!wrapperCol && label,
})} })}
> >
<div className={cls(`${prefixCls}-control-content`)}> <div className={cx(`${prefixCls}-control-content`)}>
{addonBefore && <div className={cls(`${prefixCls}-addon-before`)}>{addonBefore}</div>} {addonBefore && <div className={cx(`${prefixCls}-addon-before`)}>{addonBefore}</div>}
<div <div
style={wrapperStyle} style={wrapperStyle}
className={cls({ className={cx({
[`${prefixCls}-control-content-component`]: true, [`${prefixCls}-control-content-component`]: true,
[`${prefixCls}-control-content-component-has-feedback-icon`]: !!feedbackIcon, [`${prefixCls}-control-content-component-has-feedback-icon`]: !!feedbackIcon,
})} })}
> >
<FormLayoutShallowContext.Provider value={{}}>{formatChildren}</FormLayoutShallowContext.Provider> <FormLayoutShallowContext.Provider value={{}}>{formatChildren}</FormLayoutShallowContext.Provider>
{feedbackIcon && <div className={cls(`${prefixCls}-feedback-icon`)}>{feedbackIcon}</div>} {feedbackIcon && <div className={cx(`${prefixCls}-feedback-icon`)}>{feedbackIcon}</div>}
</div> </div>
{addonAfter && <div className={cls(`${prefixCls}-addon-after`)}>{addonAfter}</div>} {addonAfter && <div className={cx(`${prefixCls}-addon-after`)}>{addonAfter}</div>}
</div> </div>
{!!feedbackText && feedbackLayout !== 'popover' && feedbackLayout !== 'none' && ( {!!feedbackText && feedbackLayout !== 'popover' && feedbackLayout !== 'none' && (
<div <div
className={cls({ className={cx({
[`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus, [`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus,
[`${prefixCls}-help`]: true, [`${prefixCls}-help`]: true,
[`${prefixCls}-help-enter`]: true, [`${prefixCls}-help-enter`]: true,
@ -242,7 +244,7 @@ export const BaseItem: React.FC<React.PropsWithChildren<IFormItemProps>> = ({ ch
{feedbackText} {feedbackText}
</div> </div>
)} )}
{extra && <div className={cls(`${prefixCls}-extra`)}>{extra}</div>} {extra && <div className={cx(`${prefixCls}-extra`)}>{extra}</div>}
</div> </div>
</div>, </div>,
); );

View File

@ -3,7 +3,7 @@ import { css, useCollectionManager_deprecated, useRecord, useRequest, useToken }
import { connect } from '@tachybase/schema'; import { connect } from '@tachybase/schema';
import { CollectionsGraph, lodash } from '@tachybase/utils/client'; import { CollectionsGraph, lodash } from '@tachybase/utils/client';
import { App, Col, Input, Row, Select, Spin, Table, Tag } from 'antd'; import { App, Col, Input, Row, Select, Space, Spin, Table, Tag } from 'antd';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const excludeCollections = ['users', 'roles', 'applications']; const excludeCollections = ['users', 'roles', 'applications'];
@ -232,7 +232,7 @@ export const TableTransfer = connect((props) => {
`} `}
> >
<strong style={{ fontSize: token.fontSizeLG, color: token.colorText }}>{t('Unshared collections')}</strong> <strong style={{ fontSize: token.fontSizeLG, color: token.colorText }}>{t('Unshared collections')}</strong>
<Input.Group compact style={{ width: 360 }}> <Space.Compact style={{ width: 360 }}>
<Select <Select
popupMatchSelectWidth={false} popupMatchSelectWidth={false}
onChange={(value) => { onChange={(value) => {
@ -251,7 +251,7 @@ export const TableTransfer = connect((props) => {
placeholder={t('Enter name or title...')} placeholder={t('Enter name or title...')}
allowClear allowClear
/> />
</Input.Group> </Space.Compact>
</div> </div>
<Table <Table
bordered bordered
@ -317,7 +317,7 @@ export const TableTransfer = connect((props) => {
`} `}
> >
<strong style={{ fontSize: token.fontSizeLG, color: token.colorText }}>{t('Shared collections')}</strong> <strong style={{ fontSize: token.fontSizeLG, color: token.colorText }}>{t('Shared collections')}</strong>
<Input.Group compact style={{ width: 360 }}> <Space.Compact style={{ width: 360 }}>
<Select <Select
popupMatchSelectWidth={false} popupMatchSelectWidth={false}
onChange={(value) => { onChange={(value) => {
@ -336,7 +336,7 @@ export const TableTransfer = connect((props) => {
placeholder={t('Enter name or title...')} placeholder={t('Enter name or title...')}
allowClear allowClear
/> />
</Input.Group> </Space.Compact>
</div> </div>
<Table <Table
bordered bordered