refactor: block-item form-item card-item variable (#1165)
Co-authored-by: sealday <sealday@gmail.com> Reviewed-on: daoyoucloud/tachybase#1165
This commit is contained in:
parent
c31608b8cb
commit
b213c7fc49
@ -15,7 +15,7 @@ export const useStyles = genStyleHook('nb-action-drawer', (token) => {
|
|||||||
'.ant-drawer-wrapper-body': {
|
'.ant-drawer-wrapper-body': {
|
||||||
backgroundColor: 'var(--colorBgDrawer)',
|
backgroundColor: 'var(--colorBgDrawer)',
|
||||||
},
|
},
|
||||||
'.nb-block-item': {
|
'.tb-block-item': {
|
||||||
marginBottom: token.marginLG,
|
marginBottom: token.marginLG,
|
||||||
'.general-schema-designer': {
|
'.general-schema-designer': {
|
||||||
top: -token.sizeXS,
|
top: -token.sizeXS,
|
||||||
|
@ -8,7 +8,7 @@ const useStyles = genStyleHook('nb-association-filter-item', (token) => {
|
|||||||
'&.SortableItem': {
|
'&.SortableItem': {
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
'&:hover': { '> .general-schema-designer': { display: 'block' } },
|
'&:hover': { '> .general-schema-designer': { display: 'block' } },
|
||||||
'&.nb-form-item:hover': {
|
'&.tb-form-item:hover': {
|
||||||
'> .general-schema-designer': {
|
'> .general-schema-designer': {
|
||||||
background: 'var(--colorBgSettingsHover) !important',
|
background: 'var(--colorBgSettingsHover) !important',
|
||||||
border: '0 !important',
|
border: '0 !important',
|
||||||
|
@ -94,7 +94,7 @@ export const AssociationFilterItem = withDynamicSchemaProps(
|
|||||||
const title = fieldSchema.title ?? collectionField?.uiSchema?.title;
|
const title = fieldSchema.title ?? collectionField?.uiSchema?.title;
|
||||||
|
|
||||||
return wrapSSR(
|
return wrapSSR(
|
||||||
<SortableItem className={cls(componentCls, hashId, 'nb-block-item', props.className, 'SortableItem')}>
|
<SortableItem className={cls(componentCls, hashId, 'tb-block-item', props.className, 'SortableItem')}>
|
||||||
<Designer />
|
<Designer />
|
||||||
{/* @ts-ignore upstream type error */}
|
{/* @ts-ignore upstream type error */}
|
||||||
<Collapse defaultActiveKey={defaultActiveKeyCollapse} ghost expandIcon={searchVisible ? () => null : undefined}>
|
<Collapse defaultActiveKey={defaultActiveKeyCollapse} ghost expandIcon={searchVisible ? () => null : undefined}>
|
||||||
|
@ -32,7 +32,7 @@ const useStyles = createStyles(({ css, token }) => {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.nb-form-item:hover {
|
&.tb-form-item:hover {
|
||||||
> .general-schema-designer {
|
> .general-schema-designer {
|
||||||
background: var(--colorBgSettingsHover) !important;
|
background: var(--colorBgSettingsHover) !important;
|
||||||
border: 0 !important;
|
border: 0 !important;
|
||||||
@ -81,7 +81,7 @@ export const AssociationFilter = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<DndContext>
|
<DndContext>
|
||||||
<SortableItem className={cls('nb-block-item', props.className, styles.container)}>
|
<SortableItem className={cls('tb-block-item', props.className, styles.container)}>
|
||||||
<Designer />
|
<Designer />
|
||||||
{props.children}
|
{props.children}
|
||||||
{render()}
|
{render()}
|
||||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { useFieldSchema } from '@tachybase/schema';
|
import { useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
import { createStyles } from 'antd-style';
|
import { createStyles } from 'antd-style';
|
||||||
import cls from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps';
|
import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps';
|
||||||
import { SortableItem } from '../../common';
|
import { SortableItem } from '../../common';
|
||||||
@ -10,55 +10,53 @@ import { useDesigner, useProps } from '../../hooks';
|
|||||||
import { useGetAriaLabelOfBlockItem } from './hooks/useGetAriaLabelOfBlockItem';
|
import { useGetAriaLabelOfBlockItem } from './hooks/useGetAriaLabelOfBlockItem';
|
||||||
|
|
||||||
const useStyles = createStyles(({ css }) => {
|
const useStyles = createStyles(({ css }) => {
|
||||||
return {
|
return css`
|
||||||
container: css`
|
position: relative;
|
||||||
position: relative;
|
&:hover {
|
||||||
&:hover {
|
|
||||||
> .general-schema-designer {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.nb-form-item:hover {
|
|
||||||
> .general-schema-designer {
|
|
||||||
background: var(--colorBgSettingsHover) !important;
|
|
||||||
border: 0 !important;
|
|
||||||
top: -5px !important;
|
|
||||||
bottom: -5px !important;
|
|
||||||
left: -5px !important;
|
|
||||||
right: -5px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
> .general-schema-designer {
|
> .general-schema-designer {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.tb-form-item:hover {
|
||||||
|
> .general-schema-designer {
|
||||||
|
background: var(--colorBgSettingsHover) !important;
|
||||||
|
border: 0 !important;
|
||||||
|
top: -5px !important;
|
||||||
|
bottom: -5px !important;
|
||||||
|
left: -5px !important;
|
||||||
|
right: -5px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> .general-schema-designer {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 999;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
display: none;
|
||||||
|
border: 2px solid var(--colorBorderSettingsHover);
|
||||||
|
pointer-events: none;
|
||||||
|
> .general-schema-designer-icons {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 999;
|
right: 2px;
|
||||||
top: 0;
|
top: 2px;
|
||||||
bottom: 0;
|
line-height: 16px;
|
||||||
left: 0;
|
pointer-events: all;
|
||||||
right: 0;
|
.ant-space-item {
|
||||||
display: none;
|
background-color: var(--colorSettings);
|
||||||
border: 2px solid var(--colorBorderSettingsHover);
|
color: #fff;
|
||||||
pointer-events: none;
|
|
||||||
> .general-schema-designer-icons {
|
|
||||||
position: absolute;
|
|
||||||
right: 2px;
|
|
||||||
top: 2px;
|
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
pointer-events: all;
|
width: 16px;
|
||||||
.ant-space-item {
|
padding-left: 1px;
|
||||||
background-color: var(--colorSettings);
|
align-self: stretch;
|
||||||
color: #fff;
|
|
||||||
line-height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
padding-left: 1px;
|
|
||||||
align-self: stretch;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
}
|
||||||
};
|
`;
|
||||||
});
|
});
|
||||||
|
|
||||||
export const BlockItem: React.FC<any> = withDynamicSchemaProps((props) => {
|
export const BlockItem = withDynamicSchemaProps((props: unknown & { name: string }) => {
|
||||||
// 新版 UISchema(1.0 之后)中已经废弃了 useProps,这里之所以继续保留是为了兼容旧版的 UISchema
|
// 新版 UISchema(1.0 之后)中已经废弃了 useProps,这里之所以继续保留是为了兼容旧版的 UISchema
|
||||||
const { className, children } = useProps(props);
|
const { className, children } = useProps(props);
|
||||||
const { styles } = useStyles();
|
const { styles } = useStyles();
|
||||||
@ -68,11 +66,7 @@ export const BlockItem: React.FC<any> = withDynamicSchemaProps((props) => {
|
|||||||
const { getAriaLabel } = useGetAriaLabelOfBlockItem(props.name);
|
const { getAriaLabel } = useGetAriaLabelOfBlockItem(props.name);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SortableItem
|
<SortableItem role="button" aria-label={getAriaLabel()} className={cx('tb-block-item', className, styles)}>
|
||||||
role="button"
|
|
||||||
aria-label={getAriaLabel()}
|
|
||||||
className={cls('nb-block-item', className, styles.container)}
|
|
||||||
>
|
|
||||||
<Designer {...fieldSchema['x-toolbar-props']} />
|
<Designer {...fieldSchema['x-toolbar-props']} />
|
||||||
{children}
|
{children}
|
||||||
</SortableItem>
|
</SortableItem>
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { DragHandler } from '../../common';
|
|
||||||
import { useDesignable } from '../../hooks';
|
|
||||||
|
|
||||||
export const TestDesigner = () => {
|
|
||||||
const { remove } = useDesignable();
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
remove();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</a>
|
|
||||||
<DragHandler />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,5 +1,7 @@
|
|||||||
import { render } from '@testing-library/react';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
import App1 from '../demos/demo1';
|
import App1 from '../demos/demo1';
|
||||||
|
|
||||||
describe('BlockItem', () => {
|
describe('BlockItem', () => {
|
||||||
|
@ -1,36 +1,37 @@
|
|||||||
import { useFieldSchema } from '@tachybase/schema';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
import { useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { useBlockContext } from '../../../../block-provider/BlockProvider';
|
import { useBlockContext } from '../../../../block-provider/BlockProvider';
|
||||||
import { useCollection_deprecated } from '../../../../collection-manager';
|
import { useCollection } from '../../../../data-source';
|
||||||
import { useCompile } from '../../../hooks';
|
import { useCompile } from '../../../hooks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* label = 'block-item' + x-component + [collectionName] + [blockName] + [x-collection-field] + [title] + [postfix]
|
* label = 'block-item' + x-component + [collectionName] + [blockName] + [x-collection-field] + [title] + [postfix]
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const useGetAriaLabelOfBlockItem = (name?: string) => {
|
export const useGetAriaLabelOfBlockItem = (defaultName?: string) => {
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
const component = _.isString(fieldSchema['x-component'])
|
const component = _.isString(fieldSchema['x-component'])
|
||||||
? fieldSchema['x-component']
|
? fieldSchema['x-component']
|
||||||
: fieldSchema['x-component']?.displayName;
|
: fieldSchema['x-component']?.displayName;
|
||||||
const collectionField = compile(fieldSchema['x-collection-field']);
|
const collectionField = compile(fieldSchema['x-collection-field']);
|
||||||
let { name: blockName } = useBlockContext() || {};
|
const { name: blockName } = useBlockContext() || {};
|
||||||
// eslint-disable-next-line prefer-const
|
const collection = useCollection();
|
||||||
let { name: collectionName, getField } = useCollection_deprecated();
|
const name = defaultName || blockName;
|
||||||
blockName = name || blockName;
|
|
||||||
|
|
||||||
const title = compile(fieldSchema['title']) || compile(getField(fieldSchema.name)?.uiSchema?.title);
|
const title = compile(fieldSchema['title']) || compile(collection.getField(fieldSchema.name)?.uiSchema?.title);
|
||||||
|
|
||||||
const getAriaLabel = useCallback(
|
const getAriaLabel = useCallback(
|
||||||
(postfix?: string) => {
|
(postfix?: string) => {
|
||||||
postfix = postfix ? `-${postfix}` : '';
|
postfix = postfix ? `-${postfix}` : '';
|
||||||
return ['block-item', component, collectionName, blockName, collectionField, title, postfix]
|
return ['block-item', component, collection.name, name, collectionField, title, postfix]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join('-');
|
.join('-');
|
||||||
},
|
},
|
||||||
[component, collectionName, blockName, collectionField, title],
|
[component, collection.name, name, collectionField, title],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,2 +1 @@
|
|||||||
export * from './BlockItem';
|
export * from './BlockItem';
|
||||||
export * from './TestDesigner';
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { useFieldSchema } from '@tachybase/schema';
|
|
||||||
import { Card } from 'antd';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { Card } from 'antd';
|
||||||
|
|
||||||
import { useSchemaTemplate } from '../../../schema-templates';
|
import { useSchemaTemplate } from '../../../schema-templates';
|
||||||
import { BlockItem } from '../block-item';
|
import { BlockItem } from '../block-item';
|
||||||
import useStyles from './style';
|
import useStyles from './style';
|
||||||
@ -9,7 +11,7 @@ interface Props {
|
|||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
/** 区块标识 */
|
/** 区块标识 */
|
||||||
name?: string;
|
name?: string;
|
||||||
[key: string]: any;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CardItem = (props: Props) => {
|
export const CardItem = (props: Props) => {
|
||||||
@ -17,14 +19,12 @@ export const CardItem = (props: Props) => {
|
|||||||
const template = useSchemaTemplate();
|
const template = useSchemaTemplate();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const templateKey = fieldSchema?.['x-template-key'];
|
const templateKey = fieldSchema?.['x-template-key'];
|
||||||
const { wrapSSR, componentCls, hashId } = useStyles();
|
const { styles } = useStyles();
|
||||||
return wrapSSR(
|
return templateKey && !template ? null : (
|
||||||
templateKey && !template ? null : (
|
<BlockItem name={name} className={`${styles} tb-card-item`}>
|
||||||
<BlockItem name={name} className={`${componentCls} ${hashId} noco-card-item`}>
|
<Card className="card" bordered={false} {...restProps}>
|
||||||
<Card className="card" bordered={false} {...restProps}>
|
{props.children}
|
||||||
{props.children}
|
</Card>
|
||||||
</Card>
|
</BlockItem>
|
||||||
</BlockItem>
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { render, screen } from '@tachybase/test/client';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { render, screen } from '@tachybase/test/client';
|
||||||
|
|
||||||
import App1 from '../demos/demo1';
|
import App1 from '../demos/demo1';
|
||||||
|
|
||||||
describe('CardItem', () => {
|
describe('CardItem', () => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { CardItem, FormProvider, SchemaComponent } from '@tachybase/client';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { CardItem, FormProvider, SchemaComponent } from '@tachybase/client';
|
||||||
|
|
||||||
const schema = {
|
const schema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import { genStyleHook } from '../__builtins__';
|
import { createStyles } from 'antd-style';
|
||||||
|
|
||||||
const useStyles = genStyleHook('nb-card-item', (token) => {
|
const useStyles = createStyles(({ css, token }) => {
|
||||||
const { componentCls } = token;
|
return css`
|
||||||
|
.card {
|
||||||
return {
|
margin-bottom: ${token.marginLG}px;
|
||||||
[componentCls]: {
|
}
|
||||||
'.card': {
|
`;
|
||||||
marginBottom: token.marginLG,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default useStyles;
|
export default useStyles;
|
||||||
|
@ -91,7 +91,7 @@ export const FormItem: any = observer(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<CollectionFieldProvider allowNull={true}>
|
<CollectionFieldProvider allowNull={true}>
|
||||||
<BlockItem className={'nb-form-item'}>
|
<BlockItem className={'tb-form-item'}>
|
||||||
<ACLCollectionFieldProvider>
|
<ACLCollectionFieldProvider>
|
||||||
<Item className={className} {...props} extra={extra} />
|
<Item className={className} {...props} extra={extra} />
|
||||||
</ACLCollectionFieldProvider>
|
</ACLCollectionFieldProvider>
|
||||||
|
@ -4,7 +4,7 @@ const useStyles = genStyleHook('nb-grid-card', (token) => {
|
|||||||
const { componentCls } = token;
|
const { componentCls } = token;
|
||||||
return {
|
return {
|
||||||
[componentCls]: {
|
[componentCls]: {
|
||||||
'& > .nb-block-item': {
|
'& > .tb-block-item': {
|
||||||
marginBottom: token.marginLG,
|
marginBottom: token.marginLG,
|
||||||
'& > .nb-action-bar:has(:first-child:not(:empty))': {
|
'& > .nb-action-bar:has(:first-child:not(:empty))': {
|
||||||
padding: token.marginLG,
|
padding: token.marginLG,
|
||||||
|
@ -67,7 +67,7 @@ const useStyles = createStyles(({ css }) => {
|
|||||||
fixedBlockCss: css`
|
fixedBlockCss: css`
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
.noco-card-item {
|
.tb-card-item {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
.ant-card {
|
.ant-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -5,10 +5,8 @@ import { error } from '@tachybase/utils/client';
|
|||||||
import { CloseCircleFilled } from '@ant-design/icons';
|
import { CloseCircleFilled } from '@ant-design/icons';
|
||||||
import { Input as AntInput, Cascader, DatePicker, InputNumber, Select, Space, Tag } from 'antd';
|
import { Input as AntInput, Cascader, DatePicker, InputNumber, Select, Space, Tag } from 'antd';
|
||||||
import { createStyles } from 'antd-style';
|
import { createStyles } from 'antd-style';
|
||||||
import useAntdInputStyle from 'antd/es/input/style';
|
|
||||||
import type { DefaultOptionType } from 'antd/lib/cascader';
|
import type { DefaultOptionType } from 'antd/lib/cascader';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import classNames from 'classnames';
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -133,36 +131,7 @@ function getTypedConstantOption(type: string, types: true | string[], fieldNames
|
|||||||
}
|
}
|
||||||
|
|
||||||
const useStyles2 = createStyles(({ css }, { disabled }: { disabled: boolean }) => {
|
const useStyles2 = createStyles(({ css }, { disabled }: { disabled: boolean }) => {
|
||||||
return {
|
return {};
|
||||||
container: css`
|
|
||||||
position: relative;
|
|
||||||
line-height: 0;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.clear-button {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-input {
|
|
||||||
overflow: auto;
|
|
||||||
white-space: nowrap;
|
|
||||||
${disabled ? '' : 'padding-right: 28px;'}
|
|
||||||
|
|
||||||
.ant-tag {
|
|
||||||
display: inline;
|
|
||||||
line-height: 19px;
|
|
||||||
margin: 0;
|
|
||||||
padding: 2px 7px;
|
|
||||||
border-radius: 10px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
button: css`
|
|
||||||
margin-left: -1px;
|
|
||||||
`,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export function Input(props) {
|
export function Input(props) {
|
||||||
@ -178,10 +147,6 @@ export function Input(props) {
|
|||||||
fieldNames,
|
fieldNames,
|
||||||
} = props;
|
} = props;
|
||||||
const scope = typeof props.scope === 'function' ? props.scope() : props.scope;
|
const scope = typeof props.scope === 'function' ? props.scope() : props.scope;
|
||||||
const { wrapSSR, hashId, componentCls, rootPrefixCls } = useStyles();
|
|
||||||
|
|
||||||
// 添加 antd input 样式,防止样式缺失
|
|
||||||
useAntdInputStyle(`${rootPrefixCls}-input`);
|
|
||||||
|
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -295,12 +260,12 @@ export function Input(props) {
|
|||||||
}, [variable, options.length]);
|
}, [variable, options.length]);
|
||||||
|
|
||||||
const disabled = props.disabled || form.disabled;
|
const disabled = props.disabled || form.disabled;
|
||||||
const { styles: styles2 } = useStyles2({ disabled });
|
const { styles } = useStyles({ disabled });
|
||||||
|
|
||||||
return wrapSSR(
|
return (
|
||||||
<Space.Compact style={style} className={classNames(componentCls, hashId, className)}>
|
<Space.Compact style={style} className={cx(styles.outerContainer, styles.fixInput, className)}>
|
||||||
{variable ? (
|
{variable ? (
|
||||||
<div className={cx('variable', styles2.container)}>
|
<div className={cx('variable', styles.container2)}>
|
||||||
<div
|
<div
|
||||||
role="button"
|
role="button"
|
||||||
aria-label="variable-tag"
|
aria-label="variable-tag"
|
||||||
@ -312,7 +277,7 @@ export function Input(props) {
|
|||||||
}
|
}
|
||||||
onChange(null);
|
onChange(null);
|
||||||
}}
|
}}
|
||||||
className={cx('ant-input', { 'ant-input-disabled': disabled }, hashId)}
|
className={cx('ant-input', { 'ant-input-disabled': disabled })}
|
||||||
contentEditable={!disabled}
|
contentEditable={!disabled}
|
||||||
suppressContentEditableWarning
|
suppressContentEditableWarning
|
||||||
>
|
>
|
||||||
@ -349,8 +314,8 @@ export function Input(props) {
|
|||||||
fieldNames={fieldNames}
|
fieldNames={fieldNames}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
{button ?? <XButton className={styles2.button} type={variable ? 'primary' : 'default'} />}
|
{button ?? <XButton className={styles.button2} type={variable ? 'primary' : 'default'} />}
|
||||||
</Cascader>
|
</Cascader>
|
||||||
</Space.Compact>,
|
</Space.Compact>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ import { useForm } from '@tachybase/schema';
|
|||||||
import { error } from '@tachybase/utils/client';
|
import { error } from '@tachybase/utils/client';
|
||||||
|
|
||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
import { createStyles } from 'antd-style';
|
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import sanitizeHTML from 'sanitize-html';
|
import sanitizeHTML from 'sanitize-html';
|
||||||
@ -187,60 +186,12 @@ function getCurrentRange(element: HTMLElement): RangeIndexes {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles2 = createStyles(({ css }, { multiline }) => {
|
|
||||||
return {
|
|
||||||
container: css`
|
|
||||||
&.ant-input-group.ant-input-group-compact {
|
|
||||||
display: flex;
|
|
||||||
.ant-input {
|
|
||||||
flex-grow: 1;
|
|
||||||
min-width: 200px;
|
|
||||||
}
|
|
||||||
.ant-input-disabled {
|
|
||||||
.ant-tag {
|
|
||||||
color: #bfbfbf;
|
|
||||||
border-color: #d9d9d9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .x-button {
|
|
||||||
height: min-content;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
button: css`
|
|
||||||
overflow: auto;
|
|
||||||
white-space: ${multiline ? 'normal' : 'nowrap'};
|
|
||||||
|
|
||||||
.ant-tag {
|
|
||||||
display: inline;
|
|
||||||
line-height: 19px;
|
|
||||||
margin: 0 0.5em;
|
|
||||||
padding: 2px 7px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
pretty: css`
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
.ant-tag {
|
|
||||||
display: inline;
|
|
||||||
line-height: 19px;
|
|
||||||
margin: 0 0.25em;
|
|
||||||
padding: 2px 7px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
export function TextArea(props) {
|
export function TextArea(props) {
|
||||||
const { wrapSSR, hashId, componentCls } = useStyles();
|
|
||||||
const { value = '', scope, onChange, multiline = true, changeOnSelect } = props;
|
const { value = '', scope, onChange, multiline = true, changeOnSelect } = props;
|
||||||
|
const { styles } = useStyles({ multiline });
|
||||||
const inputRef = useRef<HTMLDivElement>(null);
|
const inputRef = useRef<HTMLDivElement>(null);
|
||||||
const [options, setOptions] = useState([]);
|
const [options, setOptions] = useState([]);
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
const { styles } = useStyles2({ multiline });
|
|
||||||
const keyLabelMap = useMemo(() => createOptionsValueLabelMap(options), [options]);
|
const keyLabelMap = useMemo(() => createOptionsValueLabelMap(options), [options]);
|
||||||
const [ime, setIME] = useState<boolean>(false);
|
const [ime, setIME] = useState<boolean>(false);
|
||||||
const [changed, setChanged] = useState(false);
|
const [changed, setChanged] = useState(false);
|
||||||
@ -405,8 +356,8 @@ export function TextArea(props) {
|
|||||||
|
|
||||||
const disabled = props.disabled || form.disabled;
|
const disabled = props.disabled || form.disabled;
|
||||||
|
|
||||||
return wrapSSR(
|
return (
|
||||||
<Space.Compact className={cx(componentCls, hashId, styles.container)}>
|
<Space.Compact className={cx(styles.outerContainer, styles.container)}>
|
||||||
<div
|
<div
|
||||||
role="button"
|
role="button"
|
||||||
aria-label="textbox"
|
aria-label="textbox"
|
||||||
@ -416,7 +367,7 @@ export function TextArea(props) {
|
|||||||
onPaste={onPaste}
|
onPaste={onPaste}
|
||||||
onCompositionStart={onCompositionStart}
|
onCompositionStart={onCompositionStart}
|
||||||
onCompositionEnd={onCompositionEnd}
|
onCompositionEnd={onCompositionEnd}
|
||||||
className={cx(hashId, 'ant-input', { 'ant-input-disabled': disabled }, styles.button)}
|
className={cx('ant-input', { 'ant-input-disabled': disabled }, styles.button)}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
contentEditable={!disabled}
|
contentEditable={!disabled}
|
||||||
dangerouslySetInnerHTML={{ __html: html }}
|
dangerouslySetInnerHTML={{ __html: html }}
|
||||||
@ -430,7 +381,7 @@ export function TextArea(props) {
|
|||||||
changeOnSelect={changeOnSelect}
|
changeOnSelect={changeOnSelect}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</Space.Compact>,
|
</Space.Compact>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,7 +421,7 @@ TextArea.ReadPretty = function ReadPretty(props) {
|
|||||||
|
|
||||||
const [options, setOptions] = useState([]);
|
const [options, setOptions] = useState([]);
|
||||||
const keyLabelMap = useMemo(() => createOptionsValueLabelMap(options), [options]);
|
const keyLabelMap = useMemo(() => createOptionsValueLabelMap(options), [options]);
|
||||||
const { styles } = useStyles2();
|
const { styles } = useStyles();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
preloadOptions(scope, value)
|
preloadOptions(scope, value)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { connect, mapReadPretty } from '@tachybase/schema';
|
|
||||||
import React, { createContext, useContext } from 'react';
|
import React, { createContext, useContext } from 'react';
|
||||||
|
import { connect, mapReadPretty } from '@tachybase/schema';
|
||||||
|
|
||||||
import { Input } from './Input';
|
import { Input } from './Input';
|
||||||
import { JSONInput } from './JSONInput';
|
import { JSONInput } from './JSONInput';
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Button, ButtonProps } from 'antd';
|
|
||||||
import React, { forwardRef, useMemo } from 'react';
|
import React, { forwardRef, useMemo } from 'react';
|
||||||
|
|
||||||
|
import { Button, ButtonProps } from 'antd';
|
||||||
|
|
||||||
export const XButton = forwardRef((props: ButtonProps, ref: any) => {
|
export const XButton = forwardRef((props: ButtonProps, ref: any) => {
|
||||||
const style = useMemo(() => {
|
const style = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { render, screen, userEvent, waitFor } from '@tachybase/test/client';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { render, screen, userEvent, waitFor } from '@tachybase/test/client';
|
||||||
|
|
||||||
import App1 from '../demos/demo1';
|
import App1 from '../demos/demo1';
|
||||||
import App2 from '../demos/demo2';
|
import App2 from '../demos/demo2';
|
||||||
import App3 from '../demos/demo3';
|
import App3 from '../demos/demo3';
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* title: Variable.Input
|
* title: Variable.Input
|
||||||
*/
|
*/
|
||||||
import { FormItem } from '@tachybase/components';
|
|
||||||
import { SchemaComponent, SchemaComponentProvider, Variable } from '@tachybase/client';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { SchemaComponent, SchemaComponentProvider, Variable } from '@tachybase/client';
|
||||||
|
import { FormItem } from '@tachybase/components';
|
||||||
|
|
||||||
const scope = [
|
const scope = [
|
||||||
{ label: 'v1', value: 'v1' },
|
{ label: 'v1', value: 'v1' },
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* title: Variable.Input
|
* title: Variable.Input
|
||||||
*/
|
*/
|
||||||
import { FormItem } from '@tachybase/components';
|
|
||||||
import { SchemaComponent, SchemaComponentProvider, Variable } from '@tachybase/client';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { SchemaComponent, SchemaComponentProvider, Variable } from '@tachybase/client';
|
||||||
|
import { FormItem } from '@tachybase/components';
|
||||||
|
|
||||||
const scope = [
|
const scope = [
|
||||||
{ label: 'v1', value: 'v1' },
|
{ label: 'v1', value: 'v1' },
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* title: Variable.Input
|
* title: Variable.Input
|
||||||
*/
|
*/
|
||||||
import { FormItem } from '@tachybase/components';
|
|
||||||
import { SchemaComponent, SchemaComponentProvider, Variable } from '@tachybase/client';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { SchemaComponent, SchemaComponentProvider, Variable } from '@tachybase/client';
|
||||||
|
import { FormItem } from '@tachybase/components';
|
||||||
|
|
||||||
const scope = [
|
const scope = [
|
||||||
{ label: 'v1', value: 'v1' },
|
{ label: 'v1', value: 'v1' },
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { genStyleHook } from './../__builtins__';
|
import { createStyles } from 'antd-style';
|
||||||
|
|
||||||
export const useStyles = genStyleHook('nb-variable', (token) => {
|
export const useStyles = createStyles(({ token, css }, { multiline, disabled }) => {
|
||||||
const { componentCls, lineWidth, colorFillQuaternary } = token;
|
const { lineWidth, colorFillQuaternary } = token;
|
||||||
const inputPaddingHorizontalBase = token.paddingSM - 1;
|
const inputPaddingHorizontalBase = token.paddingSM - 1;
|
||||||
const tagPaddingHorizontal = 8; // Fixed padding.
|
const tagPaddingHorizontal = 8; // Fixed padding.
|
||||||
const paddingInline = tagPaddingHorizontal - lineWidth;
|
const paddingInline = tagPaddingHorizontal - lineWidth;
|
||||||
@ -10,7 +10,26 @@ export const useStyles = genStyleHook('nb-variable', (token) => {
|
|||||||
const defaultBg = colorFillQuaternary;
|
const defaultBg = colorFillQuaternary;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[componentCls]: {
|
fixInput: css`
|
||||||
|
.ant-input {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 3px 7px;
|
||||||
|
color: rgba(0, 0, 0, 0.88);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.6666666666666667;
|
||||||
|
list-style: none;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans',
|
||||||
|
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
transition: all 0.1s;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
outerContainer: {
|
||||||
width: 'auto',
|
width: 'auto',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
'&.ant-input-group-compact': { display: 'flex' },
|
'&.ant-input-group-compact': { display: 'flex' },
|
||||||
@ -95,5 +114,75 @@ export const useStyles = genStyleHook('nb-variable', (token) => {
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
container: css`
|
||||||
|
&.ant-input-group.ant-input-group-compact {
|
||||||
|
display: flex;
|
||||||
|
.ant-input {
|
||||||
|
flex-grow: 1;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
.ant-input-disabled {
|
||||||
|
.ant-tag {
|
||||||
|
color: #bfbfbf;
|
||||||
|
border-color: #d9d9d9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .x-button {
|
||||||
|
height: min-content;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
button: css`
|
||||||
|
overflow: auto;
|
||||||
|
white-space: ${multiline ? 'normal' : 'nowrap'};
|
||||||
|
|
||||||
|
.ant-tag {
|
||||||
|
display: inline;
|
||||||
|
line-height: 19px;
|
||||||
|
margin: 0 0.5em;
|
||||||
|
padding: 2px 7px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
pretty: css`
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.ant-tag {
|
||||||
|
display: inline;
|
||||||
|
line-height: 19px;
|
||||||
|
margin: 0 0.25em;
|
||||||
|
padding: 2px 7px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
container2: css`
|
||||||
|
position: relative;
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.clear-button {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-input {
|
||||||
|
overflow: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
${disabled ? '' : 'padding-right: 28px;'}
|
||||||
|
|
||||||
|
.ant-tag {
|
||||||
|
display: inline;
|
||||||
|
line-height: 19px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 2px 7px;
|
||||||
|
border-radius: 10px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
button2: css`
|
||||||
|
margin-left: -1px;
|
||||||
|
`,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useFieldSchema } from '@tachybase/schema';
|
|
||||||
import { useComponent, useDesignable } from '.';
|
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
import { useFieldSchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { useComponent, useDesignable } from '.';
|
||||||
import { SchemaToolbar } from '../../schema-settings';
|
import { SchemaToolbar } from '../../schema-settings';
|
||||||
|
|
||||||
const Def = () => null;
|
const Def = () => null;
|
||||||
|
@ -28,7 +28,7 @@ import { getShouldChange, VariableInput } from './VariableInput/VariableInput';
|
|||||||
const useStyles = createStyles(({ css }) => {
|
const useStyles = createStyles(({ css }) => {
|
||||||
return {
|
return {
|
||||||
defaultInput: css`
|
defaultInput: css`
|
||||||
& > .nb-form-item {
|
& > .tb-form-item {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
@ -446,7 +446,7 @@ export const FilterFormItem = observer(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ACLCollectionFieldProvider>
|
<ACLCollectionFieldProvider>
|
||||||
<BlockItem className={'nb-form-item'}>
|
<BlockItem className={'tb-form-item'}>
|
||||||
<FormItem className={className} {...props} extra={extra} />
|
<FormItem className={className} {...props} extra={extra} />
|
||||||
</BlockItem>
|
</BlockItem>
|
||||||
</ACLCollectionFieldProvider>
|
</ACLCollectionFieldProvider>
|
||||||
|
@ -103,7 +103,7 @@ export const ChartFilterFormItem = observer(
|
|||||||
// const { getIsChartCollectionExists } = useChartData();
|
// const { getIsChartCollectionExists } = useChartData();
|
||||||
// const exists = (schema.name as string).startsWith('custom.') || getIsChartCollectionExists(dataSource, collection);
|
// const exists = (schema.name as string).startsWith('custom.') || getIsChartCollectionExists(dataSource, collection);
|
||||||
return (
|
return (
|
||||||
<BlockItem className={'nb-form-item'}>
|
<BlockItem className={'tb-form-item'}>
|
||||||
<CollectionManagerProvider dataSource={dataSource}>
|
<CollectionManagerProvider dataSource={dataSource}>
|
||||||
<CollectionProvider name={collection} allowNull={!collection}>
|
<CollectionProvider name={collection} allowNull={!collection}>
|
||||||
<CollectionFieldProvider name={schema.name} allowNull={!schema['x-collection-field']}>
|
<CollectionFieldProvider name={schema.name} allowNull={!schema['x-collection-field']}>
|
||||||
|
@ -65,7 +65,7 @@ export const KanbanCard: any = observer(
|
|||||||
}
|
}
|
||||||
.nb-grid-row:last-of-type {
|
.nb-grid-row:last-of-type {
|
||||||
.nb-grid-col {
|
.nb-grid-col {
|
||||||
.nb-form-item:last-of-type {
|
.tb-form-item:last-of-type {
|
||||||
.ant-formily-item {
|
.ant-formily-item {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user