mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2024-11-21 03:15:49 +08:00
feat: implement FormStack and FormControl
This commit is contained in:
parent
bb6aba3f83
commit
1a4cd734b9
15
packages/arco-lib/src/components/Form/DragComponentTips.tsx
Normal file
15
packages/arco-lib/src/components/Form/DragComponentTips.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import { Typography } from '@arco-design/web-react';
|
||||
|
||||
const DragComponentTips: React.FC<{ componentName: string }> = ({ componentName }) => {
|
||||
return (
|
||||
<Typography.Paragraph style={{ color: '#b2b2b2' }}>
|
||||
Please drag{' '}
|
||||
<Typography.Text bold style={{ color: '#777' }}>
|
||||
{componentName}
|
||||
</Typography.Text>{' '}
|
||||
components here
|
||||
</Typography.Paragraph>
|
||||
);
|
||||
};
|
||||
|
||||
export { DragComponentTips };
|
79
packages/arco-lib/src/components/Form/Form.tsx
Normal file
79
packages/arco-lib/src/components/Form/Form.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
import { Form as BaseForm } from '@arco-design/web-react';
|
||||
import { ComponentImpl, implementRuntimeComponent } from '@sunmao-ui/runtime';
|
||||
import { css } from '@emotion/css';
|
||||
import { Type, Static } from '@sinclair/typebox';
|
||||
import { FALLBACK_METADATA, getComponentProps } from '../../sunmao-helper';
|
||||
import { FormPropsSchema as BaseFormPropsSchema } from '../../generated/types/Form';
|
||||
import { DragComponentTips } from './DragComponentTips';
|
||||
|
||||
const FormPropsSchema = Type.Object(BaseFormPropsSchema);
|
||||
const FormStateSchema = Type.Object({});
|
||||
|
||||
const FormImpl: ComponentImpl<Static<typeof FormPropsSchema>> = props => {
|
||||
const { childrenLayout, bordered, ...cProps } = getComponentProps(props);
|
||||
const { elementRef, customStyle, slotsElements } = props;
|
||||
|
||||
let formStyle;
|
||||
if (cProps.layout === 'inline' && childrenLayout === 'vertical') {
|
||||
formStyle = `
|
||||
&& {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
&& > *{
|
||||
margin:0 10px 10px 0;
|
||||
display: block;
|
||||
width: auto
|
||||
}
|
||||
`;
|
||||
}
|
||||
const borderStyle = css`
|
||||
border: 1px solid #eee;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 5px;
|
||||
`;
|
||||
|
||||
return (
|
||||
<div ref={elementRef} className={bordered ? borderStyle : ''}>
|
||||
<BaseForm className={css(customStyle?.content, formStyle)} {...cProps}>
|
||||
{slotsElements.content ? (
|
||||
slotsElements.content
|
||||
) : (
|
||||
<DragComponentTips componentName="Form Control" />
|
||||
)}
|
||||
</BaseForm>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const exampleProperties: Static<typeof FormPropsSchema> = {
|
||||
layout: 'horizontal',
|
||||
size: 'default',
|
||||
bordered: true,
|
||||
labelAlign: 'left',
|
||||
childrenLayout: 'horizontal',
|
||||
};
|
||||
|
||||
const options = {
|
||||
version: 'arco/v1',
|
||||
metadata: {
|
||||
...FALLBACK_METADATA,
|
||||
name: 'formStack',
|
||||
displayName: 'Form Stack',
|
||||
exampleProperties,
|
||||
annotations: {
|
||||
category: 'Display',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
properties: FormPropsSchema,
|
||||
state: FormStateSchema,
|
||||
methods: {},
|
||||
slots: ['content'],
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
};
|
||||
|
||||
export const Form = implementRuntimeComponent(options)(FormImpl);
|
95
packages/arco-lib/src/components/Form/FormControl.tsx
Normal file
95
packages/arco-lib/src/components/Form/FormControl.tsx
Normal file
@ -0,0 +1,95 @@
|
||||
import { Form } from '@arco-design/web-react';
|
||||
import { ComponentImpl, implementRuntimeComponent, Text } from '@sunmao-ui/runtime';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { Type, Static } from '@sinclair/typebox';
|
||||
import { FALLBACK_METADATA, getComponentProps } from '../../sunmao-helper';
|
||||
import { FormControlPropsSchema as BaseFormControlPropsSchema } from '../../generated/types/Form';
|
||||
import { DragComponentTips } from './DragComponentTips';
|
||||
import { FormControlErrorMessage } from './FormControlErrorMessage';
|
||||
|
||||
const FormControlPropsSchema = Type.Object(BaseFormControlPropsSchema);
|
||||
const BaseFormControl = Form.Item;
|
||||
|
||||
const FormControlImpl: ComponentImpl<Static<typeof FormControlPropsSchema>> = props => {
|
||||
const { label, errorMsg, ...cProps } = getComponentProps(props);
|
||||
const { elementRef, slotsElements, customStyle } = props;
|
||||
|
||||
if (!cProps.colon) {
|
||||
Reflect.deleteProperty(cProps, 'colon');
|
||||
}
|
||||
if (cProps.labelAlign === 'unset') {
|
||||
Reflect.deleteProperty(cProps, 'labelAlign');
|
||||
}
|
||||
|
||||
const formControlProps = {
|
||||
className: cx(
|
||||
'sunmao-form-control-layout',
|
||||
css`
|
||||
${customStyle?.content}
|
||||
svg {
|
||||
display: inherit;
|
||||
}
|
||||
& * {
|
||||
word-wrap: normal;
|
||||
}
|
||||
& label {
|
||||
white-space: inherit !important;
|
||||
}
|
||||
`
|
||||
),
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseFormControl
|
||||
label={<Text cssStyle="display:inline-block" value={label} />}
|
||||
ref={elementRef}
|
||||
{...formControlProps}
|
||||
{...cProps}
|
||||
labelAlign={cProps.labelAlign as any}
|
||||
>
|
||||
{slotsElements.content ? (
|
||||
slotsElements.content
|
||||
) : (
|
||||
<DragComponentTips componentName="Form Control" />
|
||||
)}
|
||||
<FormControlErrorMessage errorMsg={errorMsg} />
|
||||
</BaseFormControl>
|
||||
);
|
||||
};
|
||||
|
||||
const exampleProperties: Static<typeof FormControlPropsSchema> = {
|
||||
label: {
|
||||
format: 'md',
|
||||
raw: '**label**',
|
||||
},
|
||||
required: false,
|
||||
hidden: false,
|
||||
extra: '',
|
||||
errorMsg: '',
|
||||
labelAlign: 'unset',
|
||||
colon: false,
|
||||
labelCol: { span: 5, offset: 0 },
|
||||
wrapperCol: { span: 19, offset: 0 },
|
||||
help: '',
|
||||
};
|
||||
|
||||
export const FormControl = implementRuntimeComponent({
|
||||
version: 'arco/v1',
|
||||
metadata: {
|
||||
...FALLBACK_METADATA,
|
||||
name: 'formControl',
|
||||
displayName: 'Form Control',
|
||||
exampleProperties: exampleProperties,
|
||||
annotations: {
|
||||
category: 'Display',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
properties: FormControlPropsSchema,
|
||||
state: Type.Object({}),
|
||||
methods: {},
|
||||
slots: ['content'],
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(FormControlImpl);
|
@ -0,0 +1,17 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
const FormControlErrorMessage: React.FC<{ errorMsg: string }> = ({ errorMsg }) => {
|
||||
return errorMsg ? (
|
||||
<div
|
||||
className={css`
|
||||
color: rgb(245, 63, 63);
|
||||
line-height: 20px;
|
||||
min-height: 20px;
|
||||
`}
|
||||
>
|
||||
{errorMsg}
|
||||
</div>
|
||||
) : null;
|
||||
};
|
||||
|
||||
export { FormControlErrorMessage };
|
73
packages/arco-lib/src/generated/types/Form.ts
Normal file
73
packages/arco-lib/src/generated/types/Form.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { StringUnion } from '../../sunmao-helper';
|
||||
import { PRESET_PROPERTY_CATEGORY } from '@sunmao-ui/editor'
|
||||
import { TextPropertySchema } from "@sunmao-ui/runtime";
|
||||
|
||||
export const FormControlPropsSchema = {
|
||||
label: TextPropertySchema,
|
||||
required: Type.Boolean({
|
||||
title: 'Required',
|
||||
category: PRESET_PROPERTY_CATEGORY.Basic
|
||||
}),
|
||||
hidden: Type.Boolean({
|
||||
title: 'Hidden',
|
||||
category: PRESET_PROPERTY_CATEGORY.Basic
|
||||
}),
|
||||
extra: Type.String({
|
||||
title: 'Extra',
|
||||
category: PRESET_PROPERTY_CATEGORY.Basic
|
||||
}),
|
||||
errorMsg: Type.String({
|
||||
title: 'Error Message',
|
||||
category: PRESET_PROPERTY_CATEGORY.Basic
|
||||
}),
|
||||
help: Type.String({
|
||||
title: 'Help Message',
|
||||
category: PRESET_PROPERTY_CATEGORY.Basic
|
||||
}),
|
||||
labelAlign: StringUnion(['left', 'right', 'unset'], {
|
||||
title: 'Label Align',
|
||||
category: PRESET_PROPERTY_CATEGORY.Layout
|
||||
}),
|
||||
colon: Type.Boolean({
|
||||
title: 'Colon',
|
||||
category: PRESET_PROPERTY_CATEGORY.Style
|
||||
}),
|
||||
labelCol: Type.Object({
|
||||
span: Type.Number(),
|
||||
offset: Type.Number()
|
||||
}, {
|
||||
title: 'Label Col',
|
||||
category: PRESET_PROPERTY_CATEGORY.Layout
|
||||
}),
|
||||
wrapperCol: Type.Object({
|
||||
span: Type.Number(),
|
||||
offset: Type.Number()
|
||||
}, {
|
||||
title: 'Wrapper Col',
|
||||
category: PRESET_PROPERTY_CATEGORY.Layout
|
||||
})
|
||||
}
|
||||
|
||||
export const FormPropsSchema = {
|
||||
layout: StringUnion(['horizontal', 'vertical', 'inline'], {
|
||||
title: 'Layout',
|
||||
category: PRESET_PROPERTY_CATEGORY.Layout
|
||||
}),
|
||||
childrenLayout: StringUnion(['vertical', 'horizontal'], {
|
||||
title: 'Children Layout',
|
||||
category: PRESET_PROPERTY_CATEGORY.Layout,
|
||||
}),
|
||||
labelAlign: StringUnion(['left', 'right'], {
|
||||
title: 'Label Align',
|
||||
category: PRESET_PROPERTY_CATEGORY.Layout
|
||||
}),
|
||||
size: StringUnion(['mini', 'small', 'default', 'large'], {
|
||||
title: 'Size',
|
||||
category: PRESET_PROPERTY_CATEGORY.Layout
|
||||
}),
|
||||
bordered: Type.Boolean({
|
||||
title: 'Bordered',
|
||||
category: PRESET_PROPERTY_CATEGORY.Layout
|
||||
}),
|
||||
};
|
@ -34,6 +34,8 @@ import { Switch } from "./components/Switch";
|
||||
import { PasswordInput } from "./components/PasswordInput";
|
||||
import { TextArea } from "./components/TextArea";
|
||||
import { Tabs } from "./components/Tabs";
|
||||
import { Form } from "./components/Form/Form";
|
||||
import { FormControl } from "./components/Form/FormControl";
|
||||
|
||||
type Component = Parameters<Registry["registerComponent"]>[0];
|
||||
type Trait = Parameters<Registry["registerTrait"]>[0];
|
||||
@ -74,7 +76,9 @@ export const components: Component[] = [
|
||||
Switch,
|
||||
PasswordInput,
|
||||
TextArea,
|
||||
Tabs
|
||||
Tabs,
|
||||
Form,
|
||||
FormControl
|
||||
];
|
||||
export const traits: Trait[] = [];
|
||||
export const modules: Module[] = [];
|
||||
|
@ -2,6 +2,7 @@ import { StrictMode } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Registry } from '@sunmao-ui/runtime';
|
||||
import { sunmaoChakraUILib } from '@sunmao-ui/chakra-ui-lib';
|
||||
import { ArcoDesignLib } from '@sunmao-ui/arco-lib';
|
||||
import { initSunmaoUIEditor } from './init';
|
||||
import { LocalStorageManager } from './LocalStorageManager';
|
||||
|
||||
@ -14,7 +15,7 @@ type Options = Partial<{
|
||||
|
||||
const lsManager = new LocalStorageManager();
|
||||
const { Editor, registry } = initSunmaoUIEditor({
|
||||
libs: [sunmaoChakraUILib],
|
||||
libs: [sunmaoChakraUILib, ArcoDesignLib],
|
||||
storageHandler: {
|
||||
onSaveApp(app) {
|
||||
lsManager.saveAppInLS(app);
|
||||
|
Loading…
Reference in New Issue
Block a user