{
+ const value = (parseFloat((val.split('%')[0])) / 100).toFixed(2);
+ utils.setPropertyValue(this.props, 'opacity', value);
+ }}
+ min={0}
+ max={100}
+ units={[{
+ type: '%',
+ list: true,
+ }]}
+ />
+ );
+ }
+}
+
+export default Opacity;
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/effects/shadow.js b/packages/editor-setters/src/style-setter/lc-style-setter/effects/shadow.js
new file mode 100644
index 000000000..775d5c3c4
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/effects/shadow.js
@@ -0,0 +1,210 @@
+import React, { Component, PropTypes } from 'react';
+import classNames from 'classnames';
+import Field from '@ali/ve-field';
+import Icons from '@ali/ve-icons';
+import NumberControl from '@ali/ve-number-control';
+import ColorControl from '@ali/ve-color-control';
+
+import utils from '../utils';
+import $i18n from '../i18n/index';
+
+const generateShadow = (c = 'rgba(0,0,0,0)', x = '0', y = '0', b = '0', s = '0') => `${c} ${x} ${y} ${b} ${s}`;
+
+class Shadow extends Component {
+ static propTypes = {
+ prop: PropTypes.object,
+ className: PropTypes.string,
+ };
+
+ static displayName = 'StyleShadowSetter';
+
+ static transducer = utils.transducer;
+
+ componentWillMount() {
+
+ }
+
+ componentWillUnmount() {
+
+ }
+
+ render() {
+ const className = classNames('vs-style-shadow', this.props.className);
+ const shadow = utils.getPropertyValue(this.props, 'box-shadow').value;
+
+ let c = ''; // color
+ let x = ''; // x
+ let y = ''; // y
+ let b = ''; // blur
+ let s = ''; // spread
+
+ // @todo shadow parser 比较复杂考虑情况比较多,这里有明显的 Bug
+ // 由于时间问题,这里先留坑,满足可用性,后面有时间再来修复一下。
+ if (shadow !== 'none' && !!shadow && typeof shadow === 'string') {
+ const res = shadow.split(' ');
+ s = res.pop();
+ b = res.pop();
+ y = res.pop();
+ x = res.pop();
+ c = res.join(' ');
+ }
+
+ return (
+
+
+
+
+
+)}
+ >
+ {
+ utils.setPropertyValue(this.props, 'box-shadow', generateShadow(val, x, y, b, s));
+ }}
+ />
+
+
+
+
+ {
+ utils.setPropertyValue(this.props, 'box-shadow', generateShadow(c, val, y, b, s));
+ }}
+ min={0}
+ max={100}
+ units={[
+ {
+ type: 'px',
+ list: true,
+ },
+ {
+ type: '%',
+ list: true,
+ },
+ {
+ type: 'em',
+ list: true,
+ },
+ ]}
+ />
+
+
+ {
+ utils.setPropertyValue(this.props, 'box-shadow', generateShadow(c, x, val, b, s));
+ }}
+ min={0}
+ max={100}
+ units={[
+ {
+ type: 'px',
+ list: true,
+ },
+ {
+ type: '%',
+ list: true,
+ },
+ {
+ type: 'em',
+ list: true,
+ },
+ ]}
+ />
+
+
+
+
+
+
+)}
+ >
+ {
+ utils.setPropertyValue(this.props, 'box-shadow', generateShadow(c, x, y, val, s));
+ }}
+ min={0}
+ max={100}
+ units={[
+ {
+ type: 'px',
+ list: true,
+ },
+ {
+ type: '%',
+ list: true,
+ },
+ {
+ type: 'em',
+ list: true,
+ },
+ ]}
+ />
+
+
+
+
+)}
+ >
+ {
+ utils.setPropertyValue(this.props, 'box-shadow', generateShadow(c, x, y, b, val));
+ }}
+ min={0}
+ max={100}
+ units={[
+ {
+ type: 'px',
+ list: true,
+ },
+ {
+ type: '%',
+ list: true,
+ },
+ {
+ type: 'em',
+ list: true,
+ },
+ ]}
+ />
+
+
+
+ );
+ }
+}
+
+export default Shadow;
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/i18n/index.js b/packages/editor-setters/src/style-setter/lc-style-setter/i18n/index.js
new file mode 100644
index 000000000..ed0ccb71e
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/i18n/index.js
@@ -0,0 +1,45 @@
+const { provideIntl, destroyIntl } = require('@ali/intl-universal');
+const strings = require('./strings');
+
+let intl;
+const MEDUSA_APP_NAME = 'legao-designer';
+const PSEUDO_LANGUAGE_TAG = 'pd-KV';
+const CURRENT_LANGUAGE = (window.locale || window.localStorage.getItem('vdev-locale') || '').replace(/_/, '-') || 'zh-CN';
+
+function update(language) {
+ destroyIntl();
+ intl = provideIntl({
+ locale: language,
+ messagesAIO: strings,
+ });
+}
+
+function get(id, variable) {
+ if (!intl) update();
+ let string = '';
+ let key = '';
+ if (typeof id === 'string') {
+ key = id;
+ string = intl.formatMessage({ id }, variable);
+ }
+ if (typeof id === 'object' && id.dm) {
+ id.defaultMessage = id.dm;
+ }
+ key = id.id;
+ string = intl.formatMessage(id, variable);
+ if (CURRENT_LANGUAGE === PSEUDO_LANGUAGE_TAG) {
+ return `##@@@${key}##${MEDUSA_APP_NAME}@@@##${string}`;
+ }
+ return string;
+}
+
+if (PSEUDO_LANGUAGE_TAG === CURRENT_LANGUAGE) {
+ update('en-US');
+} else {
+ update(CURRENT_LANGUAGE);
+}
+
+module.exports = {
+ get,
+ update,
+};
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/i18n/strings/en-US.json b/packages/editor-setters/src/style-setter/lc-style-setter/i18n/strings/en-US.json
new file mode 100644
index 000000000..03a69fdf0
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/i18n/strings/en-US.json
@@ -0,0 +1,72 @@
+{
+ "styleImpactBlackBody": "Impact, black body",
+ "styleImpactMicrosoftYahei": "Impact, Microsoft Yahei",
+ "styleComicSansMSBlackbody": "Comic Sans MS, Blackbody",
+ "styleGeorgiaMicrosoftYahei": "Georgia, Microsoft Yahei",
+ "styleArialHelveticaBlackBody": "Arial, Helvetica, black body",
+ "styleLateralOffset": "Horizontal offset",
+ "styleAlign": "text-align",
+ "styleTrebuchetMSMicrosoftYahei": "Trebuchet MS, Microsoft Yahei",
+ "styleTrebuchetMSBlackBody": "Trebuchet MS, black body",
+ "styleArialHelveticaMicrosoftYahei": "Arial, Helvetica, Microsoft Yahei",
+ "styleLucidaSansUnicodeMicrosoft": "Lucida Sans Unicode, Microsoft Yahei",
+ "styleRowHeight": "line-height",
+ "styleFontColor": "font-color",
+ "styleSolidLine": "solid line",
+ "styleLinear": "style",
+ "styleLucidaConsoleBlackbody": "Lucida Console, Blackbody",
+ "styleStyle": "font-style",
+ "styleWordWeight": "font-width",
+ "styleLayout": "layout",
+ "styleSourceEditor": "Source editor",
+ "styleTopBorder": "Top border",
+ "styleStatus": "status",
+ "styleText": "Text",
+ "stylePleaseEnterAnAddress": "Please enter an address or paste upload",
+ "styleDefaultState": "Default state",
+ "styleRightBorder": "Right border",
+ "styleHigh": "high",
+ "styleBottomBorder": "Bottom border",
+ "styleTransparency": "opacity",
+ "styleBottomRightCorner": "Bottom right corner",
+ "styleUpperRightCorner": "Upper right corner",
+ "styleColour": "color",
+ "styleUnsupportedImage": "Unsupported image",
+ "styleTimesNewRomanBlackbody": "Times New Roman, Blackbody",
+ "styleLucidaConsoleMicrosoftYahei": "Lucida Console, Microsoft Yahei",
+ "styleDisplay": "display",
+ "styleFlexibleLayout": "Flexible layout",
+ "styleSize": "font-size",
+ "styleFillet": "radius",
+ "styleEffect": "effect",
+ "stylePositioning": "Positioning",
+ "styleLeftBorder": "Left border",
+ "styleBackground": "background",
+ "styleFillColor": "background-color",
+ "stylePalatinoLinotypeBlackBody": "Palatino Linotype, black body",
+ "styleFont": "font-family",
+ "styleMouseGesture": "cursor",
+ "styleAir": "empty",
+ "styleAll": "All",
+ "styleTimesNewRomanMicrosoft": "Times New Roman, Microsoft Yahei",
+ "styleUpperLeftCorner": "Upper left corner",
+ "styleCourierNewMicrosoftYahei": "Courier New, Microsoft Yahei",
+ "styleCourierNewBlackbody": "Courier New, Blackbody",
+ "styleFrame": "Border",
+ "styleImage": "background-image",
+ "styleComicSansMSMicrosoft": "Comic Sans MS, Microsoft Yahei",
+ "styleVerdanaBlackBody": "Verdana, black body",
+ "stylePalatinoLinotypeMicrosoftYahei": "Palatino Linotype, Microsoft Yahei",
+ "styleGeorgiaBlackbody": "Georgia, Blackbody",
+ "styleWidth": "width",
+ "styleVerticalOffset": "Vertical offset",
+ "styleModification": "text-decoration",
+ "styleHeight": "height",
+ "styleFixed": "fixed",
+ "styleLucidaSansUnicodeBlackbody": "Lucida Sans Unicode, Blackbody",
+ "styleVerdanaMicrosoftYahei": "Verdana, Microsoft Yahei",
+ "styleNo": "no",
+ "styleTile": "Tile",
+ "styleDottedLine": "dotted line",
+ "styleDottedLine.1": "dashed line"
+}
\ No newline at end of file
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/i18n/strings/index.js b/packages/editor-setters/src/style-setter/lc-style-setter/i18n/strings/index.js
new file mode 100644
index 000000000..9b61c93e1
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/i18n/strings/index.js
@@ -0,0 +1,4 @@
+module.exports = {
+ 'en-US': require('./en-US.json'),
+ 'zh-CN': require('./zh-CN.json'),
+};
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/i18n/strings/zh-CN.json b/packages/editor-setters/src/style-setter/lc-style-setter/i18n/strings/zh-CN.json
new file mode 100644
index 000000000..599c944f8
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/i18n/strings/zh-CN.json
@@ -0,0 +1,72 @@
+{
+ "styleAir": "空",
+ "stylePalatinoLinotypeMicrosoftYahei": "Palatino Linotype, 微软雅黑",
+ "styleMouseGesture": "鼠标手势",
+ "styleAll": "全部",
+ "styleImpactBlackBody": "Impact, 黑体",
+ "styleFont": "字体",
+ "styleFrame": "边框",
+ "styleImage": "图片",
+ "styleRowHeight": "行高",
+ "styleArialHelveticaMicrosoftYahei": "Arial, Helvetica, 微软雅黑",
+ "styleUpperLeftCorner": "左上角",
+ "styleCourierNewMicrosoftYahei": "Courier New, 微软雅黑",
+ "styleTimesNewRomanMicrosoft": "Times New Roman, 微软雅黑",
+ "styleFixed": "固定",
+ "styleModification": "修饰",
+ "stylePleaseEnterAnAddress": "请输入地址或粘贴上传",
+ "styleText": "文字",
+ "styleVerticalOffset": "纵向偏移",
+ "styleComicSansMSMicrosoft": "Comic Sans MS, 微软雅黑",
+ "styleLinear": "线形",
+ "styleWidth": "宽",
+ "styleVerdanaBlackBody": "Verdana, 黑体",
+ "styleGeorgiaBlackbody": "Georgia, 黑体",
+ "styleTrebuchetMSBlackBody": "Trebuchet MS, 黑体",
+ "styleFillet": "圆角",
+ "styleFlexibleLayout": "弹性布局",
+ "styleDottedLine": "点线",
+ "styleLeftBorder": "左边框",
+ "styleNo": "无",
+ "styleLucidaSansUnicodeBlackbody": "Lucida Sans Unicode, 黑体",
+ "styleLucidaConsoleMicrosoftYahei": "Lucida Console, 微软雅黑",
+ "styleSize": "大小",
+ "styleLateralOffset": "横向偏移",
+ "styleAlign": "对齐",
+ "styleImpactMicrosoftYahei": "Impact, 微软雅黑",
+ "styleArialHelveticaBlackBody": "Arial, Helvetica, 黑体",
+ "styleComicSansMSBlackbody": "Comic Sans MS, 黑体",
+ "stylePalatinoLinotypeBlackBody": "Palatino Linotype, 黑体",
+ "styleGeorgiaMicrosoftYahei": "Georgia, 微软雅黑",
+ "styleDefaultState": "默认状态",
+ "styleFontColor": "字体颜色",
+ "styleSolidLine": "实线",
+ "styleTrebuchetMSMicrosoftYahei": "Trebuchet MS, 微软雅黑",
+ "styleLucidaSansUnicodeMicrosoft": "Lucida Sans Unicode, 微软雅黑",
+ "styleStyle": "样式",
+ "styleTransparency": "透明度",
+ "styleSourceEditor": "源码编辑",
+ "styleStatus": "状态",
+ "styleHigh": "高",
+ "styleTopBorder": "上边框",
+ "styleBottomBorder": "下边框",
+ "styleRightBorder": "右边框",
+ "styleHeight": "高度",
+ "styleLayout": "布局",
+ "styleUnsupportedImage": "暂未支持的图片",
+ "styleLucidaConsoleBlackbody": "Lucida Console, 黑体",
+ "styleWordWeight": "字重",
+ "styleCourierNewBlackbody": "Courier New, 黑体",
+ "styleFillColor": "填充色",
+ "styleTile": "平铺",
+ "styleBackground": "背景",
+ "stylePositioning": "定位",
+ "styleEffect": "效果",
+ "styleBottomRightCorner": "右下角",
+ "styleDottedLine.1": "虚线",
+ "styleColour": "颜色",
+ "styleTimesNewRomanBlackbody": "Times New Roman, 黑体",
+ "styleUpperRightCorner": "右上角",
+ "styleVerdanaMicrosoftYahei": "Verdana, 微软雅黑",
+ "styleDisplay": "显示"
+}
\ No newline at end of file
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/index.js b/packages/editor-setters/src/style-setter/lc-style-setter/index.js
new file mode 100644
index 000000000..7eb21f3ae
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/index.js
@@ -0,0 +1,117 @@
+import React, { Component, PropTypes } from 'react';
+import classNames from 'classnames';
+import Field from '@ali/ve-field';
+import { registerDict } from '@ali/ve-icons';
+import { normalizeStyle } from '@ali/vu-css-style';
+
+import Layout from './layout';
+import Typography from './typography';
+import Background from './background';
+import Border from './border';
+import Effects from './effects';
+
+import utils from './utils';
+import SvgLib from './svglib';
+import './style.less';
+import $i18n from './i18n/index';
+
+registerDict('style', SvgLib);
+
+/**
+ * state
+ * json: JSON模式
+ * ----
+ * layout
+ * display
+ * flexItem
+ * padding+margin
+ * size
+ * width
+ * height
+ * min+max advanced
+ * float advanced
+ * clear advanced
+ * overflow advanced
+ * position advanced
+ * background
+ * color
+ * image
+ * border
+ * border
+ * radius
+ * typography
+ * font-family
+ * color
+ * font-size
+ * text-align
+ * line-height
+ * font-weight
+ * text-decoration
+ * font-style
+ * letter-spacing advanced
+ * text-indent advanced
+ * text-transform advanced
+ * direction advanced
+ * effects
+ * opacity
+ * cursor
+ * svg
+ * fill
+ */
+
+class StyleSetter extends Component {
+ static propTypes = {
+ prop: PropTypes.object,
+ className: PropTypes.string,
+ };
+
+ static displayName = 'StyleSetter';
+
+ static transducer = utils.transducer;
+
+ static defaultProps = {
+
+ };
+
+ render() {
+ const className = classNames(
+ 'vs-style',
+ 'vs-style-advanced',
+ this.props.className,
+ );
+ // react style -> css style
+ const value = this.props.value ? normalizeStyle(this.props.value) : null;
+ const defaultValue = this.props.defaultValue ? normalizeStyle(this.props.defaultValue) : null;
+ const props = {...this.props, value, defaultValue};
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+StyleSetter.Layout = Layout;
+StyleSetter.Typography = Typography;
+StyleSetter.Background = Background;
+StyleSetter.Effects = Effects;
+StyleSetter.Border = Border;
+
+// StyleSetter.Svg = Svg;
+
+export default StyleSetter;
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/layout/display.js b/packages/editor-setters/src/style-setter/lc-style-setter/layout/display.js
new file mode 100644
index 000000000..464abdf23
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/layout/display.js
@@ -0,0 +1,44 @@
+import React, { Component, PropTypes } from 'react';
+import classNames from 'classnames';
+import ChoiceControl from '@ali/ve-choice-control';
+import Icons from '@ali/ve-icons';
+import utils from '../utils';
+class Display extends Component {
+ static propTypes = {
+ prop: PropTypes.object,
+ className: PropTypes.string,
+ };
+
+ static displayName = 'StyleLayoutDisplaySetter';
+
+ render() {
+ const display = utils.getPropertyValue(this.props, 'display').value;
+ return (
+ ,
+ value: 'block',
+ }, {
+ title: ,
+ value: 'inline-block',
+ }, {
+ title: ,
+ value: 'inline',
+ }, {
+ title: ,
+ value: 'flex',
+ },
+ // {
+ // title: ,
+ // value: 'none',
+ // }
+ ]}
+ onChange={val => utils.setPropertyValue(this.props, 'display', val)}
+ />
+ );
+ }
+}
+
+export default Display;
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/layout/flex.js b/packages/editor-setters/src/style-setter/lc-style-setter/layout/flex.js
new file mode 100644
index 000000000..3e3e3addc
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/layout/flex.js
@@ -0,0 +1,176 @@
+import React, { Component, PropTypes } from 'react';
+import ChoiceControl from '@ali/ve-choice-control';
+import Icons from '@ali/ve-icons';
+import Field from '@ali/ve-field';
+import utils from '../utils';
+class Flex extends Component {
+ static propTypes = {
+ prop: PropTypes.object,
+ };
+
+ static displayName = 'StyleLayoutFlexSetter';
+
+ render() {
+ // flex-direction
+ const direction = utils.getPropertyValue(this.props, 'flex-direction').value;
+ // align-items
+ const align = utils.getPropertyValue(this.props, 'align-items').value;
+ // justify-content
+ const justify = utils.getPropertyValue(this.props, 'justify-content').value;
+ /*
+ // flex-warp
+ const wrap = getPropertyValue(this.props, 'flex-wrap').value;
+ const isWrap = /^wrap/.test(wrap);
+ // align-content
+ const alignColumns = getPropertyValue(this.props, 'align-content').value;
+ */
+
+ const isVertical = /^column/.test(direction);
+ const v = isVertical ? '-v' : '';
+ const reverseClass = /reverse$/.test(direction)
+ ? `vs-style-reverse${isVertical ? '-v' : '-h'}` : null;
+
+ return (
+
+ ,
+ tip: 'Direction:row',
+ value: 'row',
+ }, {
+ title: ,
+ tip: 'Direction:column',
+ value: 'column',
+ }, {
+ title: ,
+ tip: 'Direction:row-reverse',
+ value: 'row-reverse',
+ }, {
+ title: (),
+ tip: 'Direction:column-reverse',
+ value: 'column-reverse',
+ }]}
+ onChange={(val) => utils.setPropertyValue(this.props, 'flex-direction', val)}
+ />
+
+ ),
+ tip: 'Align:flex-start',
+ value: 'flex-start',
+ }, {
+ title: (
+
+ ),
+ tip: 'Align:center',
+ value: 'center',
+ }, {
+ title: (
+
+ ),
+ tip: 'Align:flex-end',
+ value: 'flex-end',
+ }, {
+ title: (
+
+ ),
+ tip: 'Align:stretch',
+ value: 'stretch',
+ }, {
+ title: (
+
+ ),
+ tip: 'Align:baseline',
+ value: 'baseline',
+ }]}
+ onChange={(val) => utils.setPropertyValue(this.props, 'align-items', val)}
+ />
+
+ ),
+ tip: 'Justify:flex-start',
+ value: 'flex-start',
+ }, {
+ title: (
+
+ ),
+ tip: 'Justify:center',
+ value: 'center',
+ }, {
+ title: (
+
+ ),
+ tip: 'Justify:flex-end',
+ value: 'flex-end',
+ }, {
+ title: (
+
+ ),
+ tip: 'Justify:space-between',
+ value: 'space-between',
+ }, {
+ title: (
+
+ ),
+ tip: 'Justify:space-around',
+ value: 'space-around',
+ }]}
+ onChange={(val) => utils.setPropertyValue(this.props, 'justify-content', val)}
+ />
+
+ );
+ }
+}
+
+export default Flex;
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/layout/flexitem.js b/packages/editor-setters/src/style-setter/lc-style-setter/layout/flexitem.js
new file mode 100644
index 000000000..0a432e05f
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/layout/flexitem.js
@@ -0,0 +1,10 @@
+import React, { Component, PropTypes } from 'react';
+import classNames from 'classnames';
+
+class FlexItem extends Component {
+ render() {
+ return null;
+ }
+}
+
+export default FlexItem;
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/layout/height.js b/packages/editor-setters/src/style-setter/lc-style-setter/layout/height.js
new file mode 100644
index 000000000..26e0afa45
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/layout/height.js
@@ -0,0 +1,19 @@
+import React, { Component, PropTypes } from 'react';
+import Size from './size';
+import utils from '../utils';
+class Height extends Component {
+ static propTypes = {
+ prop: PropTypes.object,
+ className: PropTypes.string,
+ };
+
+ static displayName = 'StyleLayoutWidthSetter';
+
+ static transducer = utils.transducer;
+
+ render() {
+ return ;
+ }
+}
+
+export default Height;
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/layout/index.js b/packages/editor-setters/src/style-setter/lc-style-setter/layout/index.js
new file mode 100644
index 000000000..4a32635ca
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/layout/index.js
@@ -0,0 +1,107 @@
+import React, { Component, PropTypes } from 'react';
+import classNames from 'classnames';
+import Field from '@ali/ve-field';
+import Display from './display';
+import Flex from './flex';
+import FlexItem from './flexitem';
+import PaddingMargin from './padding+margin';
+import Width from './width';
+import Height from './height';
+import Position from './position'; // advanced
+import utils from '../utils';
+import $i18n from '../i18n/index';
+
+function inFlexBox(node) {
+ const nativeNode = node;
+ if (!nativeNode) return false;
+ const { parentNode } = nativeNode;
+ if (!parentNode) return false;
+ const display = window.getComputedStyle(parentNode).getPropertyValue('display');
+ return /flex/.test(display);
+}
+
+function isFlexBox(props) {
+ const display = utils.getPropertyValue(props, 'display').value;
+ return /flex$/.test(display);
+}
+
+class Layout extends Component {
+ static propTypes = {
+ prop: PropTypes.object,
+ className: PropTypes.string,
+ };
+
+ static displayName = 'StyleLayoutSetter';
+
+ componentWillMount() {
+
+ }
+
+ // shouldComponentUpdate() {
+ // return false;
+ // }
+
+ componentWillUnmount() {
+
+ }
+
+ render() {
+ const className = classNames('vs-style-layout', this.props.className);
+ const aFlexBox = isFlexBox(this.props);
+ const aFlexItem = inFlexBox(this.props.node);
+
+ return (
+
+
+
+
+ {aFlexBox && (
+
+
+
+ )}
+ {/* todo: aFlexItem &&
+
+ */}
+
+
+
+
+
+
+
+
+
+
+
+ {/* todo:
+ {advanced &&
+
+ }
+ */}
+
+ );
+ }
+}
+
+export default Layout;
diff --git a/packages/editor-setters/src/style-setter/lc-style-setter/layout/padding+margin.js b/packages/editor-setters/src/style-setter/lc-style-setter/layout/padding+margin.js
new file mode 100644
index 000000000..a1d4a7b34
--- /dev/null
+++ b/packages/editor-setters/src/style-setter/lc-style-setter/layout/padding+margin.js
@@ -0,0 +1,504 @@
+import React, { Component, PropTypes } from 'react';
+import classNames from 'classnames';
+import Icons, { Button } from '@ali/ve-icons';
+import utils from '../utils';
+import $i18n from '../i18n/index';
+
+function diplayValue(value) {
+ if (utils.isEmptyCssValue(value)) {
+ return $i18n.get({ id: 'styleAir', dm: '空' });
+ }
+
+ const m = /^(.+)px/.exec(value);
+ if (m) {
+ return m[1];
+ }
+
+ return value;
+}
+
+class Input extends Component {
+ componentDidMount() {
+ if (this.input) {
+ this.input.select();
+ }
+ }
+
+ render() {
+ return (
+ {
+ this.input = ref;
+ }}
+ {...this.props}
+ />
+ );
+ }
+}
+
+class InlineInput extends Component {
+ static propTypes = {
+ className: PropTypes.string,
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+
+ inheritValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+
+ onChange: PropTypes.func,
+ negtive: PropTypes.bool,
+ compute: PropTypes.func,
+ highlight: PropTypes.bool,
+ };
+
+ static defaultProps = {
+ compute() {
+ return '0px';
+ },
+ highlight: false,
+ };
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ value: '',
+ editing: false,
+ };
+
+ this.pattern = this.props.negtive
+ ? /^(-?\d+(?:\.\d+)?)(px|rem|em|%|pt)?$|^auto$/i
+ : /^(\d+(?:\.\d+)?)(px|rem|em|%|pt)?$|^auto$/i;
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.value !== this.props.value) {
+ this.setState({ value: utils.isEmptyCssValue(nextProps.value) ? '' : nextProps.value });
+ }
+ }
+
+ setValue(value) {
+ this.setState({ value });
+ if (this.isValid(value) && this.props.onChange) {
+ this.props.onChange(value.trim());
+ }
+ }
+
+ isValid(value) {
+ return value.trim() === '' || this.pattern.test(value);
+ }
+
+ keyDown(e) {
+ if (e.keyCode === 27 || e.keyCode === 13) {
+ this.exitEdit();
+ e.preventDefault();
+ return;
+ }
+ if (e.keyCode !== 38 && e.keyCode !== 40) {
+ return;
+ }
+ e.preventDefault();
+
+ const factor = e.keyCode === 40 ? -1 : 1;
+ let value = e.target.value.trim();
+ if (!this.isValid(value)) {
+ value = utils.isEmptyCssValue(this.props.value) ? this.props.inheritValue : this.props.value;
+ }
+
+ if (utils.isEmptyCssValue(value) || value.toLowerCase() === 'auto') {
+ value = this.props.compute(value);
+ }
+
+ const m = this.pattern.exec(value);
+ if (!m[1]) return;
+ let n = parseFloat(m[1]) + factor;
+ if (!this.props.negtive && n < 0) {
+ n = 0;
+ }
+ this.setValue(`${n}${m[2] || 'px'}`);
+ }
+
+ exitEdit() {
+ if (!/\D+$/.test(this.state.value)) {
+ this.setValue(`${this.state.value}px`);
+ } else if (!this.pattern.test(this.state.value)) {
+ this.setValue(`${/\d+/.exec(this.state.value)[0]}px`);
+ }
+
+ this.setState({
+ editing: false,
+ });
+ }
+
+ enterEdit() {
+ this.setState({
+ editing: true,
+ value: utils.isEmptyCssValue(this.props.value) ? '' : this.props.value,
+ });
+ }
+
+ render() {
+ const { value, inheritValue, highlight } = this.props;
+ const className = classNames('vs-inline-input', this.props.className, {
+ 've-highlight': highlight,
+ });
+
+ const display = diplayValue(utils.isEmptyCssValue(value) ? inheritValue : value);
+
+ return (
+
+ {!this.state.editing && (
+
+ {display}
+
+ )}
+ {this.state.editing && (
+ this.setValue(e.target.value)}
+ onKeyDown={this.keyDown.bind(this)}
+ onBlur={this.exitEdit.bind(this)}
+ />
+ )}
+
+ );
+ }
+}
+
+function spliteMargin(all) {
+ if (!all) {
+ return {
+ top: null,
+ right: null,
+ bottom: null,
+ left: null,
+ };
+ }
+ let [top, right, bottom, left] = all.trim().split(/\s+/); // eslint-disable-line
+ if (utils.isEmptyCssValue(right)) {
+ right = top;
+ }
+ if (utils.isEmptyCssValue(bottom)) {
+ bottom = top;
+ }
+ if (utils.isEmptyCssValue(left)) {
+ left = right;
+ }
+ return {
+ top, right, bottom, left,
+ };
+}
+
+function compositeMargin(all, top, right, bottom, left) {
+ const ret = spliteMargin(all);
+
+ if (!utils.isEmptyCssValue(top)) {
+ ret.top = top;
+ }
+ if (!utils.isEmptyCssValue(right)) {
+ ret.right = right;
+ }
+ if (!utils.isEmptyCssValue(bottom)) {
+ ret.bottom = bottom;
+ }
+ if (!utils.isEmptyCssValue(left)) {
+ ret.left = left;
+ }
+
+ return ret;
+}
+
+function isFull(box) {
+ return (
+ !utils.isEmptyCssValue(box.top)
+ && !utils.isEmptyCssValue(box.right)
+ && !utils.isEmptyCssValue(box.bottom)
+ && !utils.isEmptyCssValue(box.left)
+ );
+}
+
+class LayoutBox extends Component {
+ static propTypes = {
+ prop: PropTypes.object,
+ className: PropTypes.string,
+ name: PropTypes.string,
+ negtive: PropTypes.bool,
+ };
+
+ constructor(props) {
+ super(props);
+
+ this.pattern = this.props.negtive
+ ? /^(-?\d+(?:\.\d+)?)(px|rem|em|%|pt)?$|^auto$/i
+ : /^(\d+(?:\.\d+)?)(px|rem|em|%|pt)?$|^auto$/i;
+ }
+
+ componentDidMount() {
+ this.shell.addEventListener('mousedown', (e) => {
+ // todo: dragging & interval add
+ const t = e.target;
+ if (t.dataset && t.dataset.handle) {
+ this.add(t.dataset.handle);
+ }
+ });
+ }
+
+ add(dir, factor = 1) {
+ if (!this.current || !this.inherit) return;
+ let value = utils.isEmptyCssValue(this.current[dir]) ? this.inherit[dir] : this.current[dir];
+
+ if (utils.isEmptyCssValue(value) || value.toLowerCase() === 'auto') {
+ value = this.compute(dir);
+ }
+
+ const m = this.pattern.exec(value);
+ if (!m[1]) return;
+ let n = parseFloat(m[1]) + factor;
+ if (!this.props.negtive && n < 0) {
+ n = 0;
+ }
+ this.change(this.current, dir, `${n}${m[2] || 'px'}`);
+ }
+
+ change(box, dir, val) {
+ const { name } = this.props;
+ box[dir] = val;
+ if (isFull(box)) {
+ utils.setPropertyValue(
+ this.props,
+ {
+ [name]: `${box.top} ${box.right} ${box.bottom} ${box.left}`,
+ [`${name}-top`]: null,
+ [`${name}-right`]: null,
+ [`${name}-bottom`]: null,
+ [`${name}-left`]: null,
+ },
+ );
+ } else {
+ utils.setPropertyValue(
+ this.props,
+ {
+ [name]: null,
+ [`${name}-top`]: box.top,
+ [`${name}-right`]: box.right,
+ [`${name}-bottom`]: box.bottom,
+ [`${name}-left`]: box.left,
+ },
+ );
+ }
+ }
+
+ compute(dir) {
+ const { name, node } = this.props;
+ // if (external) {
+ // return getComputePropertyValue(node, `${name}-${dir}`);
+ // }
+ return '0px';
+ }
+
+ render() {
+ const {
+ name, negtive,
+ } = this.props;
+
+ const all = utils.getPropertyValue(this.props, name);
+ const top = utils.getPropertyValue(this.props, `${name}-top`);
+ const right = utils.getPropertyValue(this.props, `${name}-right`);
+ const bottom = utils.getPropertyValue(this.props, `${name}-bottom`);
+ const left = utils.getPropertyValue(this.props, `${name}-left`);
+
+ const current = compositeMargin(
+ all.current,
+ top.current,
+ right.current,
+ bottom.current,
+ left.current,
+ );
+
+ const inherit = compositeMargin(
+ all.inherit,
+ top.inherit,
+ right.inherit,
+ bottom.inherit,
+ left.inherit,
+ );
+
+ this.current = current;
+ this.inherit = inherit;
+
+ return (
+ {
+ this.shell = ref;
+ }}
+ >
+
+
+
+
this.compute('top')}
+ negtive={negtive}
+ highlight={current.top != undefined}
+ onChange={val => this.change(current, 'top', val)}
+ />
+
+
+
+
+ this.compute('right')}
+ onChange={val => this.change(current, 'right', val)}
+ />
+
+
+ {name}
+
+
+ this.compute('bottom')}
+ onChange={val => this.change(current, 'bottom', val)}
+ />
+
+
+
+
+ this.compute('left')}
+ onChange={val => this.change(current, 'left', val)}
+ />
+
+ );
+ }
+}
+
+class MarginAuto extends Component {
+ static propTypes = {
+ prop: PropTypes.object,
+ };
+
+ setAuto(box) {
+ box.left = 'auto';
+ box.right = 'auto';
+ if (isFull(box)) {
+ utils.setPropertyValue(
+ this.props,
+ {
+ margin: `${box.top} ${box.right} ${box.bottom} ${box.left}`,
+ 'margin-top': null,
+ 'margin-right': null,
+ 'margin-bottom': null,
+ 'margin-left': null,
+ },
+ );
+ } else {
+ utils.setPropertyValue(
+ this.props,
+ {
+ margin: null,
+ 'margin-top': box.top,
+ 'margin-right': box.right,
+ 'margin-bottom': box.bottom,
+ 'margin-left': box.left,
+ },
+ );
+ }
+ }
+
+ render() {
+ const all = utils.getPropertyValue(this.props, 'margin');
+ const top = utils.getPropertyValue(this.props, 'margin-top');
+ const bottom = utils.getPropertyValue(this.props, 'margin-bottom');
+ const right = utils.getPropertyValue(this.props, 'margin-right');
+ const left = utils.getPropertyValue(this.props, 'margin-left');
+
+ const current = compositeMargin(
+ all.current,
+ top.current,
+ right.current,
+ bottom.current,
+ left.current,
+ );
+
+ const inherit = compositeMargin(
+ all.inherit,
+ top.inherit,
+ right.inherit,
+ bottom.inherit,
+ left.inherit,
+ );
+
+ const eright = utils.isEmptyCssValue(current.right) ? inherit.right : current.right;
+ const eleft = utils.isEmptyCssValue(current.left) ? inherit.left : current.left;
+
+ const className = classNames('vs-margin-auto', {
+ 've-active': eright === 'auto' && eleft === 'auto',
+ });
+
+ return (
+