feat:🤒️新增iconsetter

This commit is contained in:
荣彬 2020-08-10 16:50:22 +08:00
parent f44e7abf34
commit 31196cad08
8 changed files with 252 additions and 89 deletions

View File

@ -9776,7 +9776,7 @@
},
{
"name": "icon",
"propType": "string",
"propType": "icon",
"description": "图标"
},
{
@ -10857,7 +10857,7 @@
},
{
"name": "icon",
"propType": "string",
"propType": "icon",
"description": "图标"
},
{

View File

@ -18,23 +18,23 @@ export default class ColorPickerView extends PureComponent<PluginProps> {
static display = 'ColorPicker';
static propTypes = {
onChange: PropTypes.func,
value: PropTypes.string
value: PropTypes.string,
};
static defaultProps = {
onChange: () => {},
value: ''
value: '',
};
constructor(props: Readonly<{value: string; defaultValue: string}>) {
constructor(props: Readonly<{ value: string; defaultValue: string }>) {
super(props);
this.state = {
value: props.value || props.defaultValue
value: props.value || props.defaultValue,
};
}
static getDerivedStateFromProps(props: { value: string; }, state: { preValue: string; }) {
static getDerivedStateFromProps(props: { value: string }, state: { preValue: string }) {
if (props.value != state.preValue) {
return {
preValue: props.value,
value: props.value
value: props.value,
};
}
return null;
@ -42,35 +42,35 @@ export default class ColorPickerView extends PureComponent<PluginProps> {
onChangeComplete = (color: Color): void => {
let value;
if (color.rgb.a < 1) {
let rgb = color.rgb;
let rgba = [rgb.r, rgb.g, rgb.b, rgb.a];
const rgb = color.rgb;
const rgba = [rgb.r, rgb.g, rgb.b, rgb.a];
value = `rgba(${rgba.join(',')})`;
} else {
value = color.hex;
}
this.setState({
value
value,
});
this.props.onChange && this.props.onChange(value);
}
};
onInputChange = (value: string): void => {
if (/^[0-9a-zA-Z]{6}$/.test(value)) value = '#' + value;
this.setState({
value
value,
});
this.props.onChange && this.props.onChange(value);
}
render(): React.ReactNode {
};
render(): React.ReactNode {
const { value, onChange, ...restProps } = this.props;
let boxStyle = {
backgroundColor: this.state.value
const boxStyle = {
backgroundColor: this.state.value,
};
let triggerNode = (
const triggerNode = (
<div className="lowcode-color-box">
<div style={boxStyle} />
</div>
);
let InnerBeforeNode = (
const InnerBeforeNode = (
<Balloon
className={'lowcode-color-content'}
trigger={triggerNode}
@ -80,20 +80,11 @@ export default class ColorPickerView extends PureComponent<PluginProps> {
alignEdge="edge"
offset={[-3, -6]}
>
<SketchPicker
onChangeComplete={this.onChangeComplete}
color={this.state.value}
arrowPointAtCenter={true}
/>
<SketchPicker onChangeComplete={this.onChangeComplete} color={this.state.value} arrowPointAtCenter={true} />
</Balloon>
);
return (
<Input
{...restProps}
innerBefore={InnerBeforeNode}
onChange={this.onInputChange}
value={this.state.value}
/>
<Input {...restProps} innerBefore={InnerBeforeNode} onChange={this.onInputChange} value={this.state.value} />
);
}
}

View File

@ -0,0 +1,44 @@
.lowcode-icon-box {
display: inline-block;
margin-right: -5px;
padding: 3px 0 3px 0;
width: 26px;
height: 26px;
text-align: center;
line-height: 20px;
background: #f2f2f2;
div {
width: 20px;
height: 20px;
border: 1px solid #ddd;
}
}
.lc-icon-setter{
.next-input{
width: auto !important;
}
}
.lowcode-icon-setter-popup{
max-width: 354px;
.lowcode-icon-list{
overflow: auto;
li{
float: left;
margin-bottom: 10px;
width: 40px;
color: #666;
cursor: pointer;
text-align: center;
&:hover{
color: #000;
}
}
}
}

View File

@ -0,0 +1,121 @@
import React, { PureComponent } from 'react';
// import PropTypes from 'prop-types';
import { Input, Icon, Balloon } from '@alifd/next';
import './index.scss';
const icons = [
'smile',
'cry',
'success',
'warning',
'prompt',
'error',
'help',
'clock',
'success-filling',
'delete-filling',
'favorites-filling',
'add',
'minus',
'arrow-up',
'arrow-down',
'arrow-left',
'arrow-right',
'arrow-double-left',
'arrow-double-right',
'switch',
'sorting',
'descending',
'ascending',
'select',
'semi-select',
'loading',
'search',
'close',
'ellipsis',
'picture',
'calendar',
'ashbin',
'upload',
'download',
'set',
'edit',
'refresh',
'filter',
'attachment',
'account',
'email',
'atm',
'copy',
'exit',
'eye',
'eye-close',
'toggle-left',
'toggle-right',
'lock',
'unlock',
'chart-pie',
'chart-bar',
'form',
'detail',
'list',
'dashboard',
];
interface IconSetterProps {
value: string;
onChange: (icon: string) => undefined;
icons: string[];
}
export default class IconSetter extends PureComponent<IconSetterProps, {}> {
static defaultProps = {
value: '',
icons: icons,
onChange: (icon: string) => undefined,
};
onInputChange() {
console.log(this);
}
onSelectIcon(icon: string) {
const { onChange } = this.props;
onChange(icon);
}
render() {
const { icons, value } = this.props;
const triggerNode = (
<div className="lowcode-icon-box">
<Icon type={value} />
</div>
);
const InnerBeforeNode = (
<Balloon
className={'lowcode-icon-content'}
trigger={triggerNode}
needAdjust={true}
triggerType="click"
closable={false}
alignEdge
align="l"
popupClassName="lowcode-icon-setter-popup"
>
<ul className="lowcode-icon-list">
{icons.map((icon) => (
<li onClick={() => this.onSelectIcon(icon)}>
<Icon type={icon} size="large" />
</li>
))}
</ul>
</Balloon>
);
return (
<div className="lc-icon-setter">
<Input innerBefore={InnerBeforeNode} onChange={this.onInputChange} value={value} />
</div>
);
}
}

View File

@ -1,3 +1,4 @@
import React, { Component } from 'react';
import { registerSetter } from '@ali/lowcode-editor-core';
import { isJSExpression } from '@ali/lowcode-types';
import { DatePicker, TimePicker, Input, Radio, Select, Switch, NumberPicker } from '@alifd/next';
@ -6,7 +7,8 @@ import ColorSetter from './color-setter';
import JsonSetter from './json-setter';
import EventsSetter from './events-setter';
import StyleSetter from './style-setter';
import React, { Component } from 'react';
import IconSetter from './icon-setter';
export const StringSetter = {
component: Input,
defaultProps: { placeholder: '请输入', style: { maxWidth: 180 } },
@ -15,14 +17,16 @@ export const StringSetter = {
};
export const NumberSetter = NumberPicker;
export class BoolSetter extends Component {
render() {
const { onChange, value, defaultValue } = this.props;
return <Switch checked={value || defaultValue} onChange={
val => {
onChange(val)
}
}/>;
return (
<Switch
checked={value || defaultValue}
onChange={(val) => {
onChange(val);
}}
/>
);
}
}
export const SelectSetter = Select;
@ -49,25 +53,27 @@ export const DateRangeSetter = DatePicker.RangePicker;
export { ExpressionSetter, EventsSetter };
class StringDateSetter extends Component {
render() {
const { onChange, editor } = this.props;
return <DatePicker onChange={
val => {
onChange(val.format())
}
}/>;
return (
<DatePicker
onChange={(val) => {
onChange(val.format());
}}
/>
);
}
}
class StringTimePicker extends Component {
render() {
const { onChange, editor } = this.props;
return <TimePicker onChange={
val => {
onChange(val.format('HH:mm:ss'))
}
}/>;
return (
<TimePicker
onChange={(val) => {
onChange(val.format('HH:mm:ss'));
}}
/>
);
}
}
@ -97,6 +103,7 @@ const builtinSetters: any = {
ColorSetter,
JsonSetter,
StyleSetter,
IconSetter,
};
registerSetter(builtinSetters);

View File

@ -25,25 +25,27 @@ export default class Mixin extends PureComponent {
static defaultProps = {
locale: 'zh-CN',
messages: zhCN,
types: [{
"name": "StringSetter",
"props": {}
}],
types: [
{
name: 'StringSetter',
props: {},
},
],
};
typeMap: any;
i18n: (key: any, values?: {}) => string | void | (string | void)[];
i18n: (key: any, values?: {}) => string | void | Array<string | void>;
constructor(props: Readonly<{}>) {
super(props);
let type = props.defaultType;// judgeTypeHandler(props, {});
const type = props.defaultType; // judgeTypeHandler(props, {});
this.i18n = generateI18n(props.locale, props.messages);
this.state = {
preType: type,
type
type,
};
}
changeType(type: string) {
if (typeof type === 'object' || type === this.state.type) return;
let { onChange } = this.props;
const { onChange } = this.props;
let newValue = undefined;
const setterProps = this.typeMap[type]['props'];
if (setterProps) {
@ -60,18 +62,10 @@ export default class Mixin extends PureComponent {
onChange && onChange(newValue);
}
render() {
const {
style = {},
className,
locale,
messages,
types = [],
defaultType,
...restProps
} = this.props;
const { style = {}, className, locale, messages, types = [], defaultType, ...restProps } = this.props;
this.typeMap = {};
let realTypes: any[] = [];
types.forEach( (el: { name: any; props: any; }) => {
const realTypes: any[] = [];
types.forEach((el: { name: any; props: any }) => {
const { name, props } = el;
const Setter = getSetter(name);
if (Setter) {
@ -79,15 +73,15 @@ export default class Mixin extends PureComponent {
label: name,
component: Setter.component,
props,
}
};
}
realTypes.push(name);
})
});
let moreBtnNode = null;
//如果只有2种且有变量表达式则直接展示变量按钮
if (realTypes.length > 1) {
let isTwoType = !!(realTypes.length === 2 && ~realTypes.indexOf('ExpressionSetter'));
let btnProps = {
const isTwoType = !!(realTypes.length === 2 && ~realTypes.indexOf('ExpressionSetter'));
const btnProps = {
size: 'small',
text: true,
style: {
@ -100,13 +94,13 @@ export default class Mixin extends PureComponent {
width: 16,
height: 16,
lineHeight: '16px',
textAlign: 'center'
}
textAlign: 'center',
},
};
if (isTwoType) {
btnProps.onClick = this.changeType.bind(this, realTypes.indexOf(this.state.type) ? realTypes[0] : realTypes[1]);
}
let triggerNode = (
const triggerNode = (
<Button {...btnProps} size={isTwoType ? 'large' : 'small'}>
<Icon type={isTwoType ? 'edit' : 'ellipsis'} />
</Button>
@ -114,19 +108,19 @@ export default class Mixin extends PureComponent {
if (isTwoType) {
moreBtnNode = triggerNode;
} else {
let MenuItems: {} | null | undefined = [];
realTypes.map(type => {
const MenuItems: {} | null | undefined = [];
realTypes.map((type) => {
if (this.typeMap[type]) {
MenuItems.push(<Menu.Item key={type}>{this.typeMap[type]['label']}</Menu.Item>);
} else {
console.error(
this.i18n('typeError', {
type
})
type,
}),
);
}
});
let MenuNode = (
const MenuNode = (
<Menu
selectMode="single"
hasSelectedIcon={false}
@ -144,13 +138,13 @@ export default class Mixin extends PureComponent {
);
}
}
let TargetNode = this.typeMap[this.state.type]?.component || 'div';
let targetProps = this.typeMap[this.state.type]?.props || {};
let tarStyle = { position: 'relative', ...style };
let classes = classNames(className, 'lowcode-setter-mixin');
const TargetNode = this.typeMap[this.state.type]?.component || 'div';
const targetProps = this.typeMap[this.state.type]?.props || {};
const tarStyle = { position: 'relative', ...style };
const classes = classNames(className, 'lowcode-setter-mixin');
return (
<div style={tarStyle} className={classes} >
<div style={tarStyle} className={classes}>
<TargetNode {...restProps} {...targetProps} />
{moreBtnNode}
</div>

View File

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import LowStyleSetter from '@ali/lc-style-setter';
import { globalLocale } from '@ali/lowcode-editor-core';
export default class StyleSetter extends Component{
export default class StyleSetter extends Component {
static displayName = 'StyleSetter';
static propTypes = {
@ -15,7 +15,7 @@ export default class StyleSetter extends Component{
};
static defaultProps = {
value: {},
onChange: () => {},
onChange: () => { },
placeholder: '',
locale: globalLocale.getLocale() || 'en-US'
};
@ -25,7 +25,7 @@ export default class StyleSetter extends Component{
onChange(val.native);
}
render () {
render() {
const { value } = this.props;
return (
<div className="lc-block-setter">

View File

@ -54,6 +54,12 @@ function propTypeToSetter(propType: PropType): SetterType {
initialValue: '',
};
case 'icon':
return {
componentName: 'IconSetter',
isRequired,
initialValue: '',
};
case 'number':
return {
componentName: 'NumberSetter',
@ -164,7 +170,7 @@ function propTypeToSetter(propType: PropType): SetterType {
componentName: 'MixedSetter',
props: {
// TODO:
setters: (propType as OneOfType).value.map(item => propTypeToSetter(item)),
setters: (propType as OneOfType).value.map((item) => propTypeToSetter(item)),
},
isRequired,
};