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:
sealday 2024-06-12 22:52:26 +08:00
parent c31608b8cb
commit b213c7fc49
30 changed files with 212 additions and 230 deletions

View File

@ -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,

View File

@ -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',

View File

@ -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}>

View File

@ -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()}

View File

@ -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 }) => {
// 新版 UISchema1.0 之后)中已经废弃了 useProps这里之所以继续保留是为了兼容旧版的 UISchema // 新版 UISchema1.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>

View File

@ -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>
);
};

View File

@ -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', () => {

View File

@ -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 {

View File

@ -1,2 +1 @@
export * from './BlockItem'; export * from './BlockItem';
export * from './TestDesigner';

View File

@ -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>
),
); );
}; };

View File

@ -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', () => {

View File

@ -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',

View File

@ -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;

View File

@ -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>

View File

@ -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,

View File

@ -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;

View File

@ -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>
); );
} }

View File

@ -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)

View File

@ -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';

View File

@ -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 {

View File

@ -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';

View File

@ -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' },

View File

@ -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' },

View File

@ -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' },

View File

@ -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;
`,
}; };
}); });

View File

@ -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;

View File

@ -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;
} }
`, `,

View File

@ -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>

View File

@ -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']}>

View File

@ -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;
} }