Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feta: 添加 json-schema-editor 渲染器 #4092

Merged
merged 11 commits into from
Apr 20, 2022
96 changes: 96 additions & 0 deletions docs/zh-CN/components/form/json-schema-editor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
title: JSONSchema Editor
description:
type: 0
group: null
menuName: JSONSchema Editor
icon:
order: 61
---

## 基本用法

```schema: scope="body"
{
"type": "form",
"api": "/api/mock2/form/saveForm",
debug: true,
"body": [
{
"type": "json-schema-editor",
"name": "schema",
"label": "字段类型"
}
]
}
```

## 顶级类型可配置

```schema: scope="body"
{
"type": "form",
"api": "/api/mock2/form/saveForm",
"body": [
{
"type": "json-schema-editor",
"name": "schema",
"label": "字段类型",
"rootTypeMutable": true,
"showRootInfo": true
}
]
}
```

## 预设类型

通过设置 definitions 属性可以提供一些默认类型,可以减少类型的定义成本。

```schema: scope="form-item"
{
label: 'JSON Schema Editor',
name: 'schema',
// showRootInfo: true,
// rootTypeMutable: true,
type: 'json-schema-editor',
disabledTypes: ['null', 'interger', 'boolean'],
definitions: {
user: {
type: 'object',
title: '用户',
properties: {
name: {
type: 'string',
title: '用户名',
description: '用户名信息'
},

id: {
type: 'interger',
title: '用户ID'
},

email: {
type: 'string',
title: '用户邮箱'
},

displayName: {
type: 'string',
title: '用户昵称'
}
}
}
}
}
```

## 属性表

| 属性名 | 类型 | 默认值 | 说明 |
| --------------- | --------------- | ------ | ------------------------------------------------------------------------------------------------ |
| rootTypeMutable | `boolean` | false | 顶级类型是否可配置 |
| showRootInfo | `boolean` | false | 是否显示顶级类型信息 |
| disabledTypes | `Array<string>` | | 用来禁用默认数据类型,默认类型有:string、number、interger、object、number、array、boolean、null |
| definitions | `object` | | 用来配置预设类型 |
10 changes: 10 additions & 0 deletions examples/components/Components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,16 @@ export const components = [
wrapDoc
)
)
},

{
label: 'JsonSchema Editor',
path: '/zh-CN/components/form/json-schema-editor',
component: React.lazy(() =>
import('../../docs/zh-CN/components/form/json-schema-editor.md').then(
wrapDoc
)
)
}
]
},
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
"@types/history": "^4.6.0",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/jest": "^27.0.2",
"@types/json-schema": "^7.0.11",
"@types/lodash": "^4.14.175",
"@types/markdown-it": "^12.2.1",
"@types/mkdirp": "^1.0.1",
Expand Down
126 changes: 126 additions & 0 deletions scss/components/_json-schema-editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
.#{$ns}SchemaEditor {
&Props {
width: 100%;

> button {
margin-top: 7px;
}

&-placeholder {
color: var(--text--muted-color);
}
}

&Props--depth {
position: relative;
margin-left: px2rem(40px);

&:before {
width: 1px;
content: '';
display: block;
position: absolute;
top: -10px;
bottom: 10px;
left: -35px;
border-left: dashed 1px var(--icon-color);
}

& .#{$ns}SchemaEditorItem:before {
height: 1px;
content: '';
display: block;
position: absolute;
top: 17px;
width: 25px;
left: -35px;
border-top: dashed 1px var(--icon-color);
}

& > button {
position: relative;

&:before {
height: 1px;
content: '';
display: block;
position: absolute;
top: 10px;
width: 25px;
left: -35px;
border-top: dashed 1px var(--icon-color);
}
}
}

&ArrayProps:before {
bottom: 15px;
}

&Item {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: var(--gap-sm);

align-items: flex-start;
position: relative;
}

&Item + &Item {
margin-top: var(--gap-sm);
}

&Object,
&Array {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: var(--gap-sm);
align-items: flex-start;
width: 100%;
}

&-itemsLabel {
margin-top: calc((var(--Form-input-height) - var(--Switch-height)) / 2);
}

&-caret {
display: inline-block;
height: px2rem(24px);
text-align: center;
line-height: px2rem(24px);
vertical-align: middle;
cursor: pointer;
transform: rotate(0deg);
transition: transform var(--animation-duration);
color: var(--icon-color);
margin-top: calc((var(--Form-input-height) - var(--Switch-height)) / 2);

> svg {
width: 10px;
height: 10px;
top: 0;
}
}

&-caret.is-collapsed {
transform: rotate(-90deg);
}

&-required {
padding-top: 4px;
}

&-key,
&-title,
&-description {
flex: 1;
max-width: 300px;
min-width: 80px;

> input {
flex-basis: 0;
}
}
}
4 changes: 2 additions & 2 deletions scss/components/_result-box.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@include input-input();
@include input-border();
flex-wrap: wrap;
padding: 0 px2rem(26px) 0 px2rem(3px);
padding: 0 px2rem(5px);
min-height: var(--Form-input-height);
align-items: center;
border-radius: 3px;
Expand Down Expand Up @@ -172,7 +172,7 @@
}
}
}

&.is-mobile {
min-height: calc(var(--Form-input-lineHeight) * var(--fontSizeLg));
border: none;
Expand Down
15 changes: 1 addition & 14 deletions scss/components/form/_selection.scss
Original file line number Diff line number Diff line change
Expand Up @@ -212,20 +212,7 @@
cursor: pointer;
user-select: none;

position: relative;
& > * {
position: relative;
z-index: 2;
}

&:hover:after {
position: absolute;
content: '';
z-index: 1;
top: 0;
right: 0;
bottom: 0;
left: -99999px;
&:hover {
background: var(--Tree-item-onHover-bg);
}

Expand Down
1 change: 1 addition & 0 deletions scss/themes/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
@import '../components/image-gallery';
@import '../components/images';
@import '../components/input-box';
@import '../components/json-schema-editor';
@import '../components/result-box';
@import '../components/search-box';
@import '../components/list-menu';
Expand Down
3 changes: 3 additions & 0 deletions src/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ import {UUIDControlSchema} from './renderers/Form/UUID';
import {FormControlSchema} from './renderers/Form/Control';
import {TransferPickerControlSchema} from './renderers/Form/TransferPicker';
import {TabsTransferPickerControlSchema} from './renderers/Form/TabsTransferPicker';
import {JSONSchemaEditorControlSchema} from './renderers/Form/JSONSchemaEditor';

// 每加个类型,这补充一下。
export type SchemaType =
Expand Down Expand Up @@ -168,6 +169,7 @@ export type SchemaType =
| 'static-image' // 这个几个跟表单项同名,再form下面用必须带前缀 static-
| 'images'
| 'static-images' // 这个几个跟表单项同名,再form下面用必须带前缀 static-
| 'json-schema-editor'
| 'json'
| 'static-json' // 这个几个跟表单项同名,再form下面用必须带前缀 static-
| 'link'
Expand Down Expand Up @@ -432,6 +434,7 @@ export type SchemaObject =
| ImageControlSchema
| InputGroupControlSchema
| ListControlSchema
| JSONSchemaEditorControlSchema
| LocationControlSchema
| UUIDControlSchema
| MatrixControlSchema
Expand Down
1 change: 1 addition & 0 deletions src/components/InputBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export class InputBox extends React.Component<InputBoxProps, InputBoxState> {
onFocus={this.handleFocus}
onBlur={this.handleBlur}
size={12}
disabled={disabled}
/>

{children}
Expand Down
13 changes: 8 additions & 5 deletions src/components/PickerContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface PickerContainerProps extends ThemeProps, LocaleProps {
headerClassName?: string;
children: (props: {
onClick: (e: React.MouseEvent) => void;
setState: (state: any) => void;
isOpened: boolean;
}) => JSX.Element;
bodyRender: (props: {
Expand Down Expand Up @@ -62,8 +63,8 @@ export class PickerContainer extends React.Component<
this.setState(
{
isOpened: true
},
(() => this.props.onFocus?.())
},
() => this.props.onFocus?.()
);
}

Expand All @@ -77,10 +78,11 @@ export class PickerContainer extends React.Component<
this.props.onClose?.();
if (callback) {
callback();
return
return;
}
this.props.onCancel?.();
})
}
);
}

@autobind
Expand Down Expand Up @@ -120,7 +122,8 @@ export class PickerContainer extends React.Component<
<>
{children({
isOpened: this.state.isOpened,
onClick: this.handleClick
onClick: this.handleClick,
setState: this.updateState
})}

<Modal
Expand Down
3 changes: 2 additions & 1 deletion src/components/TooltipWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export interface TooltipWrapperProps {
rootClose: boolean;
overlay?: any;
delay: number;
theme?: string;
tooltipTheme?: string;
tooltipClassName?: string;
style?: React.CSSProperties;
}
Expand Down Expand Up @@ -262,6 +262,7 @@ export class TooltipWrapper extends React.Component<
tooltipClassName: props.tooltipClassName,
style: props.style,
mouseLeaveDelay: props.delay,
tooltipTheme: props.tooltipTheme as 'dark' | 'light',
...(typeof props.tooltip === 'string'
? {content: props.tooltip}
: props.tooltip)
Expand Down
1 change: 1 addition & 0 deletions src/components/formula/VariableList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {TabsMode} from '../Tabs';
export interface VariableListProps extends ThemeProps {
className?: string;
itemClassName?: string;
value?: any;
data: Array<VariableItem>;
selectMode?: 'list' | 'tree' | 'tabs';
tabsMode?: TabsMode;
Expand Down
Loading