add Filter component into schema componens (#176)
* feat: add next Filter component into schema component * fix: bugfix Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
2929c77775
commit
8e1543269f
@ -0,0 +1,8 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import * as components from '.';
|
||||||
|
import { SchemaComponentOptions } from '../components/SchemaComponentOptions';
|
||||||
|
|
||||||
|
export const AntdSchemaComponentProvider = (props) => {
|
||||||
|
const { children } = props;
|
||||||
|
return <SchemaComponentOptions components={{ ...(components as any) }}>{children}</SchemaComponentOptions>;
|
||||||
|
};
|
84
packages/client/src/schema-component/antd/filter/Filter.tsx
Normal file
84
packages/client/src/schema-component/antd/filter/Filter.tsx
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { LoadingOutlined } from '@ant-design/icons';
|
||||||
|
import { createForm, onFieldValueChange } from '@formily/core';
|
||||||
|
import { connect, FieldContext, FormContext, ISchema, mapProps, mapReadPretty, Schema } from '@formily/react';
|
||||||
|
import deepmerge from 'deepmerge';
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { SchemaComponent } from '../../components';
|
||||||
|
import { FilterGroup } from './FilterGroup';
|
||||||
|
import './style.less';
|
||||||
|
|
||||||
|
export const Filter: any = connect(
|
||||||
|
(props) => <FilterGroup bordered={false} {...props} />,
|
||||||
|
mapProps((props, field) => {
|
||||||
|
return {
|
||||||
|
...props,
|
||||||
|
suffix: <span>{field?.['loading'] || field?.['validating'] ? <LoadingOutlined /> : props.suffix}</span>,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
mapReadPretty((props) => {
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
interface DynamicValueProps {
|
||||||
|
value?: any;
|
||||||
|
onChange?: any;
|
||||||
|
schema?: Schema;
|
||||||
|
operation?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter.DynamicValue = connect((props: DynamicValueProps) => {
|
||||||
|
const { onChange, value, operation } = props;
|
||||||
|
const fieldName = Object.keys(props?.schema?.properties || {}).shift() ?? 'value';
|
||||||
|
const fieldSchema = Object.values(props?.schema?.properties || {}).shift();
|
||||||
|
const form = useMemo(
|
||||||
|
() =>
|
||||||
|
createForm({
|
||||||
|
initialValues: {
|
||||||
|
[fieldName]: value,
|
||||||
|
},
|
||||||
|
effects(form) {
|
||||||
|
onFieldValueChange(fieldName, (field) => {
|
||||||
|
onChange(field.value);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
const extra: ISchema = deepmerge(
|
||||||
|
{
|
||||||
|
required: false,
|
||||||
|
'x-read-pretty': false,
|
||||||
|
name: fieldName,
|
||||||
|
default: value,
|
||||||
|
'x-decorator': 'FormilyFormItem',
|
||||||
|
'x-decorator-props': {
|
||||||
|
asterisk: true,
|
||||||
|
feedbackLayout: 'none',
|
||||||
|
},
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
minWidth: '150px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
operation?.schema || {},
|
||||||
|
);
|
||||||
|
const schema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
[fieldName]: deepmerge(fieldSchema, extra, {
|
||||||
|
arrayMerge: (target, source) => source,
|
||||||
|
}) as any,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<FieldContext.Provider value={null}>
|
||||||
|
<FormContext.Provider value={form}>
|
||||||
|
<SchemaComponent schema={schema} />
|
||||||
|
</FormContext.Provider>
|
||||||
|
</FieldContext.Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Filter;
|
@ -0,0 +1,75 @@
|
|||||||
|
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||||
|
import { useForm } from '@formily/react';
|
||||||
|
import { isValid } from '@formily/shared';
|
||||||
|
import { Select } from 'antd';
|
||||||
|
import cls from 'classnames';
|
||||||
|
import React from 'react';
|
||||||
|
import { Trans } from 'react-i18next';
|
||||||
|
import { FilterList } from './FilterList';
|
||||||
|
|
||||||
|
const toValue = (value) => {
|
||||||
|
if (!value) {
|
||||||
|
return {
|
||||||
|
logical: 'and',
|
||||||
|
list: [{}],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (value.and) {
|
||||||
|
return {
|
||||||
|
logical: 'and',
|
||||||
|
list: value.and,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (value.or) {
|
||||||
|
return {
|
||||||
|
logical: 'and',
|
||||||
|
list: value.or,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
logical: 'and',
|
||||||
|
list: [{}],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function FilterGroup(props) {
|
||||||
|
const { bordered = true, onRemove, onChange } = props;
|
||||||
|
const value = toValue(props.value);
|
||||||
|
const form = useForm();
|
||||||
|
console.log('list', form.values, value);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cls('nb-filter-group', { bordered })}>
|
||||||
|
{onRemove && (
|
||||||
|
<a className={'nb-filter-group-close'} onClick={() => onRemove()}>
|
||||||
|
<CloseCircleOutlined />
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
<div style={{ marginBottom: 14 }}>
|
||||||
|
<Trans>
|
||||||
|
<Select
|
||||||
|
style={{ width: 80 }}
|
||||||
|
onChange={(logical) => {
|
||||||
|
onChange?.({
|
||||||
|
[logical]: value.list,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
defaultValue={value.logical}
|
||||||
|
>
|
||||||
|
<Select.Option value={'and'}>All</Select.Option>
|
||||||
|
<Select.Option value={'or'}>Any</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Trans>
|
||||||
|
</div>
|
||||||
|
<FilterList
|
||||||
|
initialValue={value.list}
|
||||||
|
onChange={(list: any[]) => {
|
||||||
|
const values = {
|
||||||
|
[value.logical]: list.filter((item) => isValid(item) && Object.keys(item).length),
|
||||||
|
};
|
||||||
|
onChange?.(values);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
247
packages/client/src/schema-component/antd/filter/FilterItem.tsx
Normal file
247
packages/client/src/schema-component/antd/filter/FilterItem.tsx
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||||
|
import { FormItem as FormilyFormItem, FormLayout, Space as AntdSpace } from '@formily/antd';
|
||||||
|
import { createForm, onFieldReact, onFieldValueChange, onFormValuesChange } from '@formily/core';
|
||||||
|
import { Field } from '@formily/core/esm/models/Field';
|
||||||
|
import { Form } from '@formily/core/esm/models/Form';
|
||||||
|
import {
|
||||||
|
FieldContext,
|
||||||
|
FormContext,
|
||||||
|
ISchema,
|
||||||
|
Schema,
|
||||||
|
SchemaKey,
|
||||||
|
SchemaOptionsContext,
|
||||||
|
useFieldSchema,
|
||||||
|
} from '@formily/react';
|
||||||
|
import { isValid, uid } from '@formily/shared';
|
||||||
|
import { get } from 'lodash';
|
||||||
|
import React, { useContext, useMemo } from 'react';
|
||||||
|
import { SchemaComponent } from '../../components';
|
||||||
|
|
||||||
|
function useFilterColumns(): Map<SchemaKey, Schema> {
|
||||||
|
const schema = useFieldSchema();
|
||||||
|
const columns = schema.reduceProperties((columns, current) => {
|
||||||
|
if (current['x-component'] === 'Filter.Column') {
|
||||||
|
const fieldName = Object.keys(current.properties).shift();
|
||||||
|
columns.set(fieldName, current);
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
return columns;
|
||||||
|
}, new Map<SchemaKey, Schema>());
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FilterItem = (props) => {
|
||||||
|
const { value, initialValues = {}, onRemove, onChange } = props;
|
||||||
|
const options = useContext(SchemaOptionsContext);
|
||||||
|
const columns = useFilterColumns();
|
||||||
|
|
||||||
|
const toValues = (value) => {
|
||||||
|
if (!value) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (Object.keys(value).length === 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const fieldName = Object.keys(value).shift();
|
||||||
|
const nested = value[fieldName];
|
||||||
|
const column = columns.get(fieldName).toJSON();
|
||||||
|
const operations = column?.['x-component-props']?.['operations'] || [];
|
||||||
|
if (!nested) {
|
||||||
|
return {
|
||||||
|
column,
|
||||||
|
operations,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (Object.keys(nested).length === 0) {
|
||||||
|
return {
|
||||||
|
column,
|
||||||
|
operations,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const operationValue = Object.keys(nested).shift();
|
||||||
|
console.log('toValues', { operationValue });
|
||||||
|
const operation = operations.find((operation) => operation.value === operationValue);
|
||||||
|
console.log('toValues', { operation });
|
||||||
|
if (!operation) {
|
||||||
|
return {
|
||||||
|
operations,
|
||||||
|
column,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (operation.noValue) {
|
||||||
|
return {
|
||||||
|
column,
|
||||||
|
operations,
|
||||||
|
operation,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
column,
|
||||||
|
operation,
|
||||||
|
operations,
|
||||||
|
value: nested[operationValue],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const values = toValues(value);
|
||||||
|
|
||||||
|
console.log('toValues', values, value);
|
||||||
|
|
||||||
|
const Remove = (props) => {
|
||||||
|
return (
|
||||||
|
onRemove && (
|
||||||
|
<a onClick={() => onRemove()}>
|
||||||
|
<CloseCircleOutlined />
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const form = useMemo(
|
||||||
|
() =>
|
||||||
|
createForm({
|
||||||
|
initialValues: values,
|
||||||
|
effects: (form) => {
|
||||||
|
onFieldValueChange('column', (field: Field, form: Form) => {
|
||||||
|
const column = (field.value || {}) as ISchema;
|
||||||
|
const operations = column?.['x-component-props']?.['operations'] || [];
|
||||||
|
field.query('operation').take((f: Field) => {
|
||||||
|
f.setDataSource(operations);
|
||||||
|
f.value = get(operations, [0]);
|
||||||
|
});
|
||||||
|
field.query('value').take((f: Field) => {
|
||||||
|
f.value = undefined;
|
||||||
|
f.componentProps.schema = column;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
onFieldReact('operation', (field: Field) => {
|
||||||
|
console.log('operation', field.value);
|
||||||
|
const operation = field.value || {};
|
||||||
|
field.query('value').take((f: Field) => {
|
||||||
|
f.visible = !operation.noValue;
|
||||||
|
if (operation.noValue) {
|
||||||
|
f.value = undefined;
|
||||||
|
}
|
||||||
|
f.componentProps.operation = operation;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
onFormValuesChange((form) => {
|
||||||
|
const { column, operation, value } = form?.values || {};
|
||||||
|
|
||||||
|
if (!operation?.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const fieldName = Object.keys(column.properties).shift();
|
||||||
|
if (operation?.noValue) {
|
||||||
|
onChange({
|
||||||
|
[fieldName]: {
|
||||||
|
[operation.value]: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
onChange(
|
||||||
|
isValid(value)
|
||||||
|
? {
|
||||||
|
[fieldName]: {
|
||||||
|
[operation.value]: value,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console.log('form.values', form.values);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const columnEnum: any = [...columns.values()].map((column) => column.toJSON());
|
||||||
|
const schema: ISchema = {
|
||||||
|
type: 'void',
|
||||||
|
properties: {
|
||||||
|
space: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'AntdSpace',
|
||||||
|
properties: {
|
||||||
|
column: {
|
||||||
|
type: 'object',
|
||||||
|
name: 'column',
|
||||||
|
'x-decorator': 'FormilyFormItem',
|
||||||
|
'x-decorator-props': {
|
||||||
|
asterisk: true,
|
||||||
|
feedbackLayout: 'none',
|
||||||
|
},
|
||||||
|
'x-component': 'Select',
|
||||||
|
'x-component-props': {
|
||||||
|
objectValue: true,
|
||||||
|
style: {
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
fieldNames: {
|
||||||
|
label: 'title',
|
||||||
|
value: 'name',
|
||||||
|
options: 'options',
|
||||||
|
},
|
||||||
|
options: columnEnum,
|
||||||
|
},
|
||||||
|
enum: columnEnum,
|
||||||
|
},
|
||||||
|
operation: {
|
||||||
|
type: 'object',
|
||||||
|
name: 'operation',
|
||||||
|
'x-decorator': 'FormilyFormItem',
|
||||||
|
'x-decorator-props': {
|
||||||
|
asterisk: true,
|
||||||
|
feedbackLayout: 'none',
|
||||||
|
},
|
||||||
|
'x-component': 'Select',
|
||||||
|
'x-component-props': {
|
||||||
|
objectValue: true,
|
||||||
|
style: {
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
fieldNames: {
|
||||||
|
label: 'label',
|
||||||
|
value: 'value',
|
||||||
|
options: 'options',
|
||||||
|
},
|
||||||
|
options: values.operations,
|
||||||
|
},
|
||||||
|
enum: values.operations,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: 'object',
|
||||||
|
name: 'value',
|
||||||
|
'x-decorator': 'FormilyFormItem',
|
||||||
|
'x-decorator-props': {
|
||||||
|
asterisk: true,
|
||||||
|
feedbackLayout: 'none',
|
||||||
|
},
|
||||||
|
'x-component': 'Filter.DynamicValue',
|
||||||
|
'x-component-props': {
|
||||||
|
schema: values.column,
|
||||||
|
operation: values.operation,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[uid()]: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Remove',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FieldContext.Provider value={null}>
|
||||||
|
<FormContext.Provider value={form}>
|
||||||
|
<FormLayout layout={'inline'}>
|
||||||
|
<SchemaComponent schema={schema} components={{ AntdSpace, FormilyFormItem, Remove }}></SchemaComponent>
|
||||||
|
</FormLayout>
|
||||||
|
</FormContext.Provider>
|
||||||
|
</FieldContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilterItem;
|
@ -0,0 +1,83 @@
|
|||||||
|
import { onFormReset } from '@formily/core';
|
||||||
|
import { useForm } from '@formily/react';
|
||||||
|
import { uid } from '@formily/shared';
|
||||||
|
import { useMap } from 'ahooks';
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { FilterGroup } from './FilterGroup';
|
||||||
|
import { FilterItem } from './FilterItem';
|
||||||
|
|
||||||
|
export function FilterList(props) {
|
||||||
|
const { initialValue = [] } = props;
|
||||||
|
const form = useForm();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [map, { set, setAll, remove, reset }] = useMap<string, any>(
|
||||||
|
initialValue.map((item, index) => {
|
||||||
|
return [`index-${index}`, item];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
const id = uid();
|
||||||
|
form.addEffects(id, () => {
|
||||||
|
onFormReset((form) => {
|
||||||
|
setAll([]);
|
||||||
|
setTimeout(() => {
|
||||||
|
reset();
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
form.removeEffects(id);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
props.onChange?.([...map.values()]);
|
||||||
|
}, [map]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={'nb-filter-list'}>
|
||||||
|
<div>
|
||||||
|
{[...map.entries()].map(([index, item]) => {
|
||||||
|
if (item.and || item.or) {
|
||||||
|
return (
|
||||||
|
<FilterGroup
|
||||||
|
key={index}
|
||||||
|
value={item}
|
||||||
|
onChange={(value: any) => set(index, value)}
|
||||||
|
onRemove={() => remove(index)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<FilterItem
|
||||||
|
key={index}
|
||||||
|
value={item}
|
||||||
|
onChange={(value: any) => set(index, value)}
|
||||||
|
onRemove={() => remove(index)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div style={{ marginTop: 16 }}>
|
||||||
|
<a
|
||||||
|
onClick={() => {
|
||||||
|
set(uid(), {});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('Add filter')}
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
style={{ marginLeft: 16 }}
|
||||||
|
onClick={() => {
|
||||||
|
set(uid(), {
|
||||||
|
and: [{}],
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('Add filter group')}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* title: Filter
|
||||||
|
*/
|
||||||
|
import { observer, useForm } from '@formily/react';
|
||||||
|
import { AntdSchemaComponentProvider, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const schema = {
|
||||||
|
type: 'void',
|
||||||
|
properties: {
|
||||||
|
demo: {
|
||||||
|
name: 'filter',
|
||||||
|
type: 'array',
|
||||||
|
'x-component': 'Filter',
|
||||||
|
'x-component-props': {
|
||||||
|
onChange: (value) => {
|
||||||
|
console.log('=====', JSON.stringify(value, null, 2));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {
|
||||||
|
and: [
|
||||||
|
{
|
||||||
|
field1: {
|
||||||
|
eq: 'aa',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field1: {
|
||||||
|
eq: 500,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
column1: {
|
||||||
|
type: 'void',
|
||||||
|
title: '字段1',
|
||||||
|
'x-component': 'Filter.Column',
|
||||||
|
'x-component-props': {
|
||||||
|
operations: [
|
||||||
|
{ label: '等于', value: 'eq' },
|
||||||
|
{ label: '不等于', value: 'ne' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
field1: {
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'Input',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
column2: {
|
||||||
|
type: 'void',
|
||||||
|
title: '字段2',
|
||||||
|
'x-component': 'Filter.Column',
|
||||||
|
'x-component-props': {
|
||||||
|
operations: [
|
||||||
|
{ label: '大于', value: 'gt' },
|
||||||
|
{ label: '小于', value: 'lt' },
|
||||||
|
{ label: '非空', value: 'notNull', noValue: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
field2: {
|
||||||
|
type: 'number',
|
||||||
|
'x-component': 'InputNumber',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'Output',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const Output = observer(() => {
|
||||||
|
const form = useForm();
|
||||||
|
return <pre>{JSON.stringify(form.values, null, 2)}</pre>;
|
||||||
|
});
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return (
|
||||||
|
<SchemaComponentProvider>
|
||||||
|
<AntdSchemaComponentProvider>
|
||||||
|
<SchemaComponent components={{ Output }} schema={schema} />
|
||||||
|
</AntdSchemaComponentProvider>
|
||||||
|
</SchemaComponentProvider>
|
||||||
|
);
|
||||||
|
};
|
@ -6,3 +6,9 @@ group:
|
|||||||
---
|
---
|
||||||
|
|
||||||
# Filter
|
# Filter
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Filter usage
|
||||||
|
|
||||||
|
<code src="./demos/demo1.tsx" />
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
export * from './Filter';
|
18
packages/client/src/schema-component/antd/filter/style.less
Normal file
18
packages/client/src/schema-component/antd/filter/style.less
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
.nb-filter-group {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
min-width: 400px;
|
||||||
|
&-close {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
&.bordered {
|
||||||
|
border: 1px dashed rgb(222, 222, 222);
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nb-filter-list {
|
||||||
|
.ant-form-inline {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ export * from './checkbox';
|
|||||||
export * from './color-select';
|
export * from './color-select';
|
||||||
export * from './date-picker';
|
export * from './date-picker';
|
||||||
export * from './dnd-context';
|
export * from './dnd-context';
|
||||||
|
export * from './filter';
|
||||||
export * from './form';
|
export * from './form';
|
||||||
export * from './form-item';
|
export * from './form-item';
|
||||||
export * from './grid';
|
export * from './grid';
|
||||||
@ -29,4 +30,3 @@ export * from './time-picker';
|
|||||||
export * from './tree-select';
|
export * from './tree-select';
|
||||||
export * from './upload';
|
export * from './upload';
|
||||||
export * from './void-table';
|
export * from './void-table';
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export * from './antd';
|
export * from './antd';
|
||||||
|
export * from './antd/AntdSchemaComponentProvider';
|
||||||
export * from './components';
|
export * from './components';
|
||||||
export * from './context';
|
export * from './context';
|
||||||
export * from './hooks';
|
export * from './hooks';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user