From 0c7f49c8bc86cf54d6d3b9da4b35862801a6da78 Mon Sep 17 00:00:00 2001 From: myronliu347 Date: Mon, 22 Jul 2019 17:35:15 +0800 Subject: [PATCH 01/27] feat(*): Add Next Adaptor --- docs/adaptor.js | 83 ++++++++ docs/badge/adaptor/index.jsx | 49 +++++ docs/balloon/adaptor/index.jsx | 86 ++++++++ docs/breadcrumb/adaptor/index.jsx | 43 ++++ docs/button/adaptor/index.jsx | 133 +++++++++++++ docs/calendar/adaptor/index.jsx | 54 +++++ docs/card/adaptor/index.jsx | 90 +++++++++ docs/cascader-select/adaptor/index.jsx | 105 ++++++++++ docs/cascader/adaptor/index.jsx | 67 +++++++ docs/checkbox/adaptor/index.jsx | 42 ++++ docs/collapse/adaptor/index.jsx | 49 +++++ docs/date-picker/adaptor/index.jsx | 115 +++++++++++ docs/dialog/adaptor/index.jsx | 137 +++++++++++++ docs/input/adaptor/index.jsx | 171 ++++++++++++++++ docs/loading/adaptor/index.jsx | 17 ++ docs/menu-button/adaptor/index.jsx | 195 ++++++++++++++++++ docs/menu/adaptor/index.jsx | 190 ++++++++++++++++++ docs/message/adaptor/index.jsx | 45 +++++ docs/nav/adaptor/index.jsx | 187 ++++++++++++++++++ docs/number-picker/adaptor/index.jsx | 36 ++++ docs/pagination/adaptor/index.jsx | 57 ++++++ docs/paragraph/adaptor/index.jsx | 25 +++ docs/progress/adaptor/index.jsx | 106 ++++++++++ docs/radio/adaptor/index.jsx | 69 +++++++ docs/range/adaptor/index.jsx | 74 +++++++ docs/rating/adaptor/index.jsx | 27 +++ docs/search/adaptor/index.jsx | 90 +++++++++ docs/select/adaptor/index.jsx | 98 +++++++++ docs/slider/adaptor/index.jsx | 99 ++++++++++ docs/split-button/adaptor/index.jsx | 193 ++++++++++++++++++ docs/step/adaptor/index.jsx | 128 ++++++++++++ docs/switch/adaptor/index.jsx | 27 +++ docs/tab/adaptor/index.jsx | 64 ++++++ docs/table/adaptor/index.jsx | 67 +++++++ docs/tag/adaptor/index.jsx | 43 ++++ docs/time-picker/adaptor/index.jsx | 87 ++++++++ docs/timeline/adaptor/index.jsx | 74 +++++++ docs/transfer/adaptor/index.jsx | 51 +++++ docs/tree-select/adaptor/index.jsx | 111 +++++++++++ docs/tree/adaptor/index.jsx | 77 ++++++++ docs/upload/adaptor/index.jsx | 251 ++++++++++++++++++++++++ package.json | 4 +- scripts/adaptor/build.js | 68 +++++++ scripts/server/loaders/adaptor/index.js | 63 ++++++ scripts/server/tpls/theme.ejs | 5 +- scripts/server/webpack.js | 11 ++ 46 files changed, 3860 insertions(+), 3 deletions(-) create mode 100644 docs/adaptor.js create mode 100644 docs/badge/adaptor/index.jsx create mode 100644 docs/balloon/adaptor/index.jsx create mode 100644 docs/breadcrumb/adaptor/index.jsx create mode 100644 docs/button/adaptor/index.jsx create mode 100644 docs/calendar/adaptor/index.jsx create mode 100644 docs/card/adaptor/index.jsx create mode 100644 docs/cascader-select/adaptor/index.jsx create mode 100644 docs/cascader/adaptor/index.jsx create mode 100644 docs/checkbox/adaptor/index.jsx create mode 100644 docs/collapse/adaptor/index.jsx create mode 100644 docs/date-picker/adaptor/index.jsx create mode 100644 docs/dialog/adaptor/index.jsx create mode 100644 docs/input/adaptor/index.jsx create mode 100644 docs/loading/adaptor/index.jsx create mode 100644 docs/menu-button/adaptor/index.jsx create mode 100644 docs/menu/adaptor/index.jsx create mode 100644 docs/message/adaptor/index.jsx create mode 100644 docs/nav/adaptor/index.jsx create mode 100644 docs/number-picker/adaptor/index.jsx create mode 100644 docs/pagination/adaptor/index.jsx create mode 100644 docs/paragraph/adaptor/index.jsx create mode 100644 docs/progress/adaptor/index.jsx create mode 100644 docs/radio/adaptor/index.jsx create mode 100644 docs/range/adaptor/index.jsx create mode 100644 docs/rating/adaptor/index.jsx create mode 100644 docs/search/adaptor/index.jsx create mode 100644 docs/select/adaptor/index.jsx create mode 100644 docs/slider/adaptor/index.jsx create mode 100644 docs/split-button/adaptor/index.jsx create mode 100644 docs/step/adaptor/index.jsx create mode 100644 docs/switch/adaptor/index.jsx create mode 100644 docs/tab/adaptor/index.jsx create mode 100644 docs/table/adaptor/index.jsx create mode 100644 docs/tag/adaptor/index.jsx create mode 100644 docs/time-picker/adaptor/index.jsx create mode 100644 docs/timeline/adaptor/index.jsx create mode 100644 docs/transfer/adaptor/index.jsx create mode 100644 docs/tree-select/adaptor/index.jsx create mode 100644 docs/tree/adaptor/index.jsx create mode 100644 docs/upload/adaptor/index.jsx create mode 100644 scripts/adaptor/build.js create mode 100644 scripts/server/loaders/adaptor/index.js diff --git a/docs/adaptor.js b/docs/adaptor.js new file mode 100644 index 0000000000..4ac0c77350 --- /dev/null +++ b/docs/adaptor.js @@ -0,0 +1,83 @@ +import Badge from './badge/adaptor'; +import Balloon from './balloon/adaptor'; +import Breadcrumb from './breadcrumb/adaptor'; +import Button from './button/adaptor'; +import Calendar from './calendar/adaptor'; +import Card from './card/adaptor'; +import Cascader from './cascader/adaptor'; +import CascaderSelect from './cascader-select/adaptor'; +import Checkbox from './checkbox/adaptor'; +import Collapse from './collapse/adaptor'; +import DatePicker from './date-picker/adaptor'; +import Dialog from './dialog/adaptor'; +import Input from './input/adaptor'; +import Loading from './loading/adaptor'; +import Menu from './menu/adaptor'; +import MenuButton from './menu-button/adaptor'; +import Message from './message/adaptor'; +import Nav from './nav/adaptor'; +import NumberPicker from './number-picker/adaptor'; +import Pagination from './pagination/adaptor'; +import Paragraph from './paragraph/adaptor'; +import Progress from './progress/adaptor'; +import Radio from './radio/adaptor'; +import Range from './range/adaptor'; +import Rating from './rating/adaptor'; +import Search from './search/adaptor'; +import Select from './select/adaptor'; +import Slider from './slider/adaptor'; +import SplitButton from './split-button/adaptor'; +import Step from './step/adaptor'; +import Switch from './switch/adaptor'; +import Tab from './tab/adaptor'; +import Table from './table/adaptor'; +import Tag from './tag/adaptor'; +import TimePicker from './time-picker/adaptor'; +import Timeline from './timeline/adaptor'; +import Transfer from './transfer/adaptor'; +import Tree from './tree/adaptor'; +import TreeSelect from './tree-select/adaptor'; +import Upload from './upload/adaptor'; + +module.exports = { + Badge, + Balloon, + Breadcrumb, + Button, + Calendar, + Card, + Cascader, + CascaderSelect, + Checkbox, + Collapse, + DatePicker, + Dialog, + Input, + Loading, + Menu, + MenuButton, + Message, + Nav, + NumberPicker, + Pagination, + Paragraph, + Progress, + Radio, + Range, + Rating, + Search, + Select, + Slider, + SplitButton, + Step, + Switch, + Tab, + Table, + Tag, + TimePicker, + Timeline, + Transfer, + Tree, + TreeSelect, + Upload, +}; diff --git a/docs/badge/adaptor/index.jsx b/docs/badge/adaptor/index.jsx new file mode 100644 index 0000000000..7c61d9ac87 --- /dev/null +++ b/docs/badge/adaptor/index.jsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { Badge } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +export default { + name: 'Badge', + editor: () => ({ + props: [{ + name: 'level', + type: Types.enum, + options: ['dot', 'number'], + default: 'dot' + }, { + name: 'count', + type: Types.number, + default: 12, + }] + }), + adaptor: ({ level, count, ...others }) => { + return ; + }, + content: () => ({ + options: [{ + name: 'use', + options: ['independent', 'withOthers'], + default: 'withOthers' + }], + transform: (props, { use }) => { + if (use === 'withOthers') { + return { + ...props, + children: { + adaptor: 'div', + props: { + style: { + width: '42px', + height: '42px', + borderRadius: '50%', + background: '#eee', + display: 'inline-block' + } + } + } + }; + } + return props; + } + }) +}; diff --git a/docs/balloon/adaptor/index.jsx b/docs/balloon/adaptor/index.jsx new file mode 100644 index 0000000000..b343ad1686 --- /dev/null +++ b/docs/balloon/adaptor/index.jsx @@ -0,0 +1,86 @@ +import React from 'react'; +import { Balloon } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +const ALIGN_LIST = [ + { label: 'Top', value: 'b' }, // (上) + { label: 'Right', value: 'l' }, // (右) + { label: 'Bottom', value: 't' }, // (下) + { label: 'Left', value: 'r' }, // (左) + { label: 'Top Left', value: 'br' }, // (上左) + { label: 'Top Right', value: 'bl' }, // (上右) + { label: 'Bottom Left', value: 'tr' }, // (下左) + { label: 'Bottom Right', value: 'tl' }, // (下右) + { label: 'Left Top', value: 'rt' }, // (左上) + { label: 'Left Bottom', value: 'rb' }, // (左下) + { label: 'Right Top', value: 'lt' }, // (右上) + { label: 'Right Bottom', value: 'lb' }, // (右下 及其 两两组合) +]; + + +export default { + name: 'Balloon', + shape: [{ + label: 'Balloon', + value: 'balloon' + }, { + label: 'Tooltip', + value: 'tooltip' + }], + editor: (shape) => { + return { + props: [ + shape === 'balloon' && { + name: 'level', + type: Types.enum, + options: ['normal', 'primary'], + default: 'normal', + }, + { + name: 'direction', + type: Types.enum, + options: ALIGN_LIST, + default: 'b', + }, + shape === 'balloon' ? + { + name: 'closable', + type: Types.bool, + default: true + } : + null + ].filter(v => !!v), + data: { + default: `${shape.substring(0, 1).toUpperCase() + shape.substring(1)} content replace holder.` + } + }; + }, + adaptor: ({ shape, level, direction, closable, data }) => { + return ( + + {data} + + ); + }, + content: (shape) => ({ + options: [ + { + name: 'direction', + options: ALIGN_LIST, + default: 'b' + }, + shape === 'balloon' && { + name: 'closable', + options: ['yes', 'no'], + default: 'yes' + } + ].filter(v => !!v), + transform: (props, { direction, closable }) => { + return { + ...props, + direction, + closable: closable === 'yes', + } + } + }) +}; diff --git a/docs/breadcrumb/adaptor/index.jsx b/docs/breadcrumb/adaptor/index.jsx new file mode 100644 index 0000000000..1f5478ab02 --- /dev/null +++ b/docs/breadcrumb/adaptor/index.jsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { Breadcrumb } from '@alifd/next'; +import { Types, parseData } from '@alifd/adaptor-helper'; + +export default { + name: 'Breadcrumb', + editor: () => ({ + props: [{ + name: 'ellipsis', + type: Types.bool, + default: false + }], + data: { + icon: true, + default: 'Home\nAll Categories\nWomen\'s Clothing\nBlouses & Shirts 78,999 T-shirts' + } + }), + adaptor: ({ ellipsis, data, ...others }) => { + const props = ellipsis ? { maxNode: 3 } : {}; + const list = parseData(data).filter((it) => it.type === 'node'); + return ( + + { + list.map((item, index) => {item.value}) + } + + ); + }, + content: () => ({ + options: [{ + name: 'ellipsis', + options: ['yes', 'no'], + default: 'no' + }], + transform: (props, { ellipsis }) => { + return { + ...props, + ellipsis: ellipsis === 'yes' + }; + } + }) + +}; diff --git a/docs/button/adaptor/index.jsx b/docs/button/adaptor/index.jsx new file mode 100644 index 0000000000..fa300952c1 --- /dev/null +++ b/docs/button/adaptor/index.jsx @@ -0,0 +1,133 @@ +import React from 'react'; +import { Types, ContentType, parseData, STATE_MARK } from '@alifd/adaptor-helper'; +import { Button, Icon } from '@alifd/next'; + +const createContent = (list = []) => { + if (!Array.isArray(list)) return list; + return list.map(({ type, value }, index) => { + if (type === ContentType.icon) { + return ; + } + return value; + }); +}; + +export default { + name: 'Button', + shape: ['normal', 'text', 'warning', 'ghost', 'group'], + editor: (shape) => { + return { + props: [{ + name: 'level', + type: Types.enum, + options: { + normal: ['normal', 'primary', 'secondary'], + text: ['normal', 'primary', 'secondary'], + warning: ['normal', 'primary'], + ghost: ['light', 'dark'], + group: ['normal', 'primary', 'secondary'], + }[shape], + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }], + data: { + icon: true, + ...(shape === 'group' ? {} : { + disable: true, + hover: true, + }), + default: shape === 'group' ? 'Button\nButton\nButton' : 'Button' + } + }; + }, + adaptor: ({ shape, level, size, data, ...others }) => { + const list = parseData(data, { parseContent: true }); + + const buttonProps = { + type: shape === 'ghost' ? 'normal' : level, + warning: shape === 'warning', + text: shape === 'text', + ghost: shape === 'ghost' ? level : false, + }; + + if (list.length === 1) { + const className = (others.className || ''); + return + } + + return ( + + { + list.map((item, index) => ) + } + + ); + }, + content(shape) { + if (shape === 'group') { + return { + options: [{ + name: 'iconType', + options: ['none', 'arrow', 'onlyIcon'], + default: 'none' + }], + transform: (props, { iconType }) => { + if (iconType === 'arrow') { + return { + ...props, + data: ['[arrow-left]Go Back', 'Button', 'Go Forward[arrow-right]'].join('\n'), + }; + } + + if (iconType === 'onlyIcon') { + return { + ...props, + data: ['[set]', '[atm]', '[download]'].join('\n'), + }; + } + + return props; + } + }; + } + + return { + options: [{ + name: 'iconType', + options: ['none', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'atm'], + default: 'none' + }], + transform: (props, { iconType }) => { + if (iconType === 'none') return props; + let { data } = props; + const icon = `[${iconType}]`; + + if (['arrow-right', 'arrow-down', 'arrow-up'].indexOf(iconType) !== -1) { + data = data + icon; + } else { + data = Object.keys(STATE_MARK).filter(v => !!v).indexOf(data.substring(0, 1)) !== -1 ? + [data.substring(0, 1), icon, data.substring(1)].join('') : icon + data; + } + + return { + ...props, + data + }; + } + }; + }, + demoOptions(demo) { + const { node } = demo; + const { level } = node.props; + if (level === 'dark') { + return { + ...demo, + background: '#000', + }; + } + return demo; + } +}; diff --git a/docs/calendar/adaptor/index.jsx b/docs/calendar/adaptor/index.jsx new file mode 100644 index 0000000000..cb6f7f384e --- /dev/null +++ b/docs/calendar/adaptor/index.jsx @@ -0,0 +1,54 @@ +import React from 'react'; +import moment from 'moment'; +import { Calendar } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +const now = new Date(); + + +export default { + name: 'Calendar', + shape: ['fullscreen', 'card', 'panel', 'rangePanel'], + editor: (shape) => { + return { + props: [{ + name: 'level', + type: Types.enum, + options: ['day', 'month', 'year'].filter((level) => { + if (level === 'year') return shape === 'panel'; + if (shape === 'rangePanel') return level === 'day'; + + return true; + }), + default: 'day' + }, { + name: 'width', + type: Types.number, + default: shape === 'fullscreen' ? 600 : shape === 'rangePanel' ? 600 : 320, + }, { + name: 'date', + type: Types.string, + default: `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}` + }] + }; + }, + adaptor: ({ shape, level, width, date, style = {}, ...others }) => { + + if (shape === 'rangePanel') { + if (!Calendar.RangeCalendar) return null; + + return ( + + ); + } + return ( + + ); + } +}; diff --git a/docs/card/adaptor/index.jsx b/docs/card/adaptor/index.jsx new file mode 100644 index 0000000000..005ae47334 --- /dev/null +++ b/docs/card/adaptor/index.jsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { Card } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +let index = 0; +export default { + name: 'Card', + editor: () => ({ + props: [{ + name: 'bullet', + type: Types.bool, + default: false, + }, { + name: 'divider', + type: Types.bool, + default: true, + }, { + name: 'expand', + label: 'Expaned', + type: Types.bool, + default: false + }, { + name: 'width', + type: Types.number, + default: 300, + }, { + name: 'height', + label: 'Content Height', + type: Types.number, + default: 215, + }, { + name: 'title', + type: Types.string, + default: 'Title' + }, { + name: 'subTitle', + type: Types.string, + default: '', + }, { + name: 'extra', + type: Types.string, + default: '', + }], + }), + adaptor: ({ bullet, divider, expand, width, height, title, subTitle, extra, style, ...others }) => { + const cardStyle = { + width: width === 0 ? '' : width, + ...style, + }; + + return ( + +
+
+ ); + }, + content: () => ({ + options: [{ + name: 'bullet', + options: ['show', 'hide'], + default: 'hide' + }, { + name: 'divider', + options: ['show', 'hide'], + default: 'show' + }, { + name: 'expanded', + options: ['yes', 'no'], + default: 'no' + }, { + name: 'subTitle', + options: ['show', 'hide'], + default: 'hide' + }, { + name: 'link', + options: ['show', 'hide'], + default: 'hide' + }], + transform: (props, { bullet, divider, expanded, subTitle, link }) => { + return { + ...props, + bullet: bullet === 'show', + divider: divider === 'show', + expand: expanded === 'yes', + subTitle: subTitle === 'show' ? 'Sub Title' : '', + extra: link === 'show' ? 'Link' : '', + }; + } + }) +}; diff --git a/docs/cascader-select/adaptor/index.jsx b/docs/cascader-select/adaptor/index.jsx new file mode 100644 index 0000000000..03484ee531 --- /dev/null +++ b/docs/cascader-select/adaptor/index.jsx @@ -0,0 +1,105 @@ +import React from 'react'; +import { Types, parseData, NodeType } from '@alifd/adaptor-helper'; +import { CascaderSelect } from '@alifd/next'; + +let index = 1000; +const createDataSource = (list, map = {}) => { + if (!list) return []; + return list.filter((item) => item.type === NodeType.node).map(({ value, children, state }) => { + const key = String(index++); + if (state === 'active') { + if (!children || children.length === 0) { + map.selecteds.push(key); + } else { + map.expandeds.push(key); + } + } + + return { + value: key, + label: value, + disabled: state === 'disabled', + children: createDataSource(children, map), + }; + }); +}; +export default { + name: 'CascaderSelect', + editor: () => ({ + props: [{ + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'state', + type: Types.enum, + options: ['normal', 'expanded', 'disabled'], + default: 'normal' + }, { + name: 'width', + type: Types.number, + default: 300, + }, { + name: 'border', + type: Types.bool, + default: true, + }, { + name: 'checkbox', + type: Types.bool, + default: false + }, { + name: 'label', + type: Types.string, + default: '' + }], + data: { + active: true, + disabled: true, + icon: true, + default: '*1\n\t*1-1\n\t\t1-1-1\n\t\t1-1-2\n\t\t1-1-3\n\t\t1-1-4\n\t\t*1-1-5\n\t1-2\n\t1-3\n\t1-4\n\t1-5\n2\n\t2-1\n\t2-2\n\t2-3\n\t2-4\n\t2-5\n3\n\t3-1\n\t3-2\n\t3-3\n\t3-4\n\t3-5\n4\n\t4-1\n\t4-2\n\t4-3\n\t4-4\n\t4-5\n5\n\t5-1\n\t5-2\n\t5-3\n\t5-4\n\t5-5' + } + }), + adaptor: ({ shape, size, state, width, border, checkbox, label, data, style = {}, ...others}) => { + const list = parseData(data); + const map = { selecteds: [], expandeds: [] }; + const dataSource = createDataSource(list, map); + const value = map.selecteds; + + return ( + node} hasBorder={border} size={size} multiple={checkbox} value={value} visible={state === 'expanded'} disabled={state=== 'disabled'} dataSource={dataSource}/> + ); + }, + content: () => ({ + options: [{ + name: 'checkbox', + options: ['yes', 'no'], + default: 'no' + }, { + name: 'border', + options: ['show', 'hide'], + default: 'show' + }, { + name: 'label', + options: ['yes', 'no'], + default: 'no' + }], + transform: (props, { checkbox, border, label }) => { + return { + ...props, + checkbox: checkbox === 'yes', + border: border === 'show', + label: label === 'yes' ? 'Label' : '' + }; + } + }), + demoOptions: (demo) => { + const { node } = demo; + const { props = {} } = node; + if (props.state === 'expanded') { + return { ...demo, height: 300 }; + } + + return demo; + } +}; diff --git a/docs/cascader/adaptor/index.jsx b/docs/cascader/adaptor/index.jsx new file mode 100644 index 0000000000..8a09f1fa53 --- /dev/null +++ b/docs/cascader/adaptor/index.jsx @@ -0,0 +1,67 @@ +import React from 'react'; +import { Types, NodeType, parseData } from '@alifd/adaptor-helper'; +import { Cascader, Icon } from '@alifd/next'; + +let index = 1000; +const createDataSource = (list, map = {}) => { + if (!list) return []; + return list.filter((item) => item.type === NodeType.node).map(({ value, children, state }) => { + const key = String(index++); + if (state === 'active') { + if (!children || children.length === 0) { + map.selecteds.push(key); + } else { + map.expandeds.push(key); + } + } + + return { + value: key, + label: value, + disabled: state === 'disabled', + children: createDataSource(children, map), + }; + }); +} +export default { + name: 'Cascader', + editor: () => ({ + props: [{ + name: 'checkbox', + type: Types.bool, + default: false + }, { + name: 'width', + type: Types.number, + default: 120 + }], + data: { + active: true, + disable: true, + icon: true, + default: 'Option1\n\tOption1-1\n\tOption1-2\n\tOption1-3\n\tOption1-4\n\tOption1-5\n\tOption1-6\nOption2\n\tOption2-1\n\tOption2-2\n\tOption2-3\n\tOption2-4\n\tOption2-5\n\tOption2-6\nOption3\n\tOption3-1\n\tOption3-2\n\tOption3-3\n\tOption3-4\n\tOption3-5\n\tOption3-6\nOption4\n\tOption4-1\n\tOption4-2\n\tOption4-3\n\tOption4-4\n\tOption4-5\n\tOption4-6\nOption5\n\tOption5-1\n\tOption5-2\n\tOption5-3\n\tOption5-4\n\tOption5-5\n\tOption5-6\nOption6\n\tOption6-1\n\tOption6-2\n\tOption6-3\n\tOption6-4\n\tOption6-5\n\tOption6-6', + } + }), + adaptor: ({ checkbox, width, data, ...others }) => { + const list = parseData(data); + const map = { selecteds: [], expandeds: [] }; + const dataSource = createDataSource(list, map); + const value = map.selecteds; + const itemRender = ({ label = '' }) => { + return label.replace(/(\[.*?\])/g, '\n$1\n').split('\n').filter(v=> !!v) + .map((d, i) => { + let icon; + switch (true) { + case /^\[(.*)\]$/.test(d): + icon = RegExp.$1; + if (!icon) return ''; + return ; + default: + return d; + } + }); + }; + + return ; + } +}; diff --git a/docs/checkbox/adaptor/index.jsx b/docs/checkbox/adaptor/index.jsx new file mode 100644 index 0000000000..28b1ca3d1d --- /dev/null +++ b/docs/checkbox/adaptor/index.jsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { Checkbox } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +export default { + name: 'Checkbox', + editor: () => ({ + props: [{ + name: 'state', + type: Types.enum, + options: ['normal', 'hover', 'disabled', 'indeterminate', 'indeterminateHover', 'indeterminateDisabled', 'checked', 'checkedHover', 'checkedDisabled'], + default: 'normal' + }, { + name: 'label', + type: Types.string, + default: 'pear' + }] + }), + adaptor: ({ state = '', label, className = '', ...others }) => { + const isHovered = ['hover', 'indeterminateHover', 'checkedHover'].indexOf(state) !== -1; + const isChecked = state.indexOf('checked') !== -1; + const isDisabled = ['disabled', 'indeterminateDisabled', 'checkedDisabled'].indexOf(state) !== -1; + const isIndeterminated = state.indexOf('indeterminate') !== -1; + + return ( + {label} + ); + }, + content: () => ({ + options: [{ + name: 'label', + options: ['show', 'hide'], + default: 'show' + }], + transform: (props, { label }) => { + return { + ...props, + label: label === 'show' ? props.label : '' + }; + }, + }) +}; diff --git a/docs/collapse/adaptor/index.jsx b/docs/collapse/adaptor/index.jsx new file mode 100644 index 0000000000..89225e473b --- /dev/null +++ b/docs/collapse/adaptor/index.jsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { Collapse } from '@alifd/next'; +import { Types, parseData, NodeType } from '@alifd/adaptor-helper'; + +export default { + name: 'Collapse', + editor: () => ({ + props: [{ + name: 'state', + type: Types.enum, + options: ['normal', 'disabled'], + default: 'normal' + }, { + name: 'width', + type: Types.number, + default: 400 + }], + data: { + active: true, + disable: true, + default: '*Panel Header 1\n\tPeople always make mistakes, frustrated, nerve-racking, but cannot remain stagnant.\nPanel Header 2\n\tPeople always make mistakes, frustrated, nerve-racking, but cannot remain stagnant.\nPanel Header 3\n\tPeople always make mistakes, frustrated, nerve-racking, but cannot remain stagnant.\n' + } + }), + adaptor: ({ state, width, data, style = {}, ...others }) => { + const list = parseData(data).filter(node => NodeType.node === node.type); + let expandedKeys = []; + const children = list.map(({ state, value, children }, index) => { + if (state === 'active') { + expandedKeys.push(`panel_${index}`); + } + + return ( + + {children && children.length > 0 ? children[0].value : ''} + + ); + }); + return ( + + { + children + } + + ); + } +}; diff --git a/docs/date-picker/adaptor/index.jsx b/docs/date-picker/adaptor/index.jsx new file mode 100644 index 0000000000..7a11c78f8a --- /dev/null +++ b/docs/date-picker/adaptor/index.jsx @@ -0,0 +1,115 @@ +import React from 'react'; +import { DatePicker } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; +import moment from 'moment'; + +export default { + name: 'DatePicker', + shape: ['normal', { + value: 'range', + label: 'Range Picker' + }], + editor: (shape) => { + return { + props: [{ + name: 'state', + type: Types.enum, + options: ['normal', 'expanded', 'selected', 'disabled'], + default: 'normal' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'type', + type: Types.enum, + options: shape === 'range' ? ['dateRange', 'dateTimeRange'] : ['date', 'dateTime'], + default: shape === 'range' ? 'dateRange' : 'date' + }, { + name: 'width', + type: Types.number, + default: 288 + }, { + name: 'label', + type: Types.string, + default: '' + }, { + name: 'placeholder', + type: Types.string, + default: shape === 'range' ? 'Start Date - End Date' : 'Please Select Date' + }] + } + }, + adaptor: ({ shape, state, size, type, width, label, placeholder = '', style = {}, ...others }) => { + const now = moment(); + style = { + minWidth: width, + ...style, + } + + if (shape === 'range') { + return ( + node} + style={style} + size={size} + showTime={'dateTimeRange' === type} + locale={{ + startPlaceholder: placeholder.split('-')[0], + endPlaceholder: placeholder.split('-')[1] + }} + label={label} + value={state !== 'normal' ? [now.clone(), now.clone().add(1, 'month')] : null} + /> + ); + } + + return ( + node} + style={style} + size={size} + showTime={'dateTime' === type} + placeholder={placeholder} + label={label} + value={state !== 'normal' ? now.clone() : null} + /> + ); + }, + content: (shape) => ({ + options: [{ + name: 'type', + options: shape === 'range' ? ['dateRange', 'dateTimeRange'] : ['date', 'dateTime'], + default: shape === 'range' ? 'dateRange' : 'date' + }, { + name: 'label', + options: ['show', 'hide'], + default: 'hide' + }], + transform: (props, { type , label }) => { + return { + ...props, + type, + label: label === 'show' ? 'Label' : '' + }; + } + }), + demoOptions: (demo) => { + const { node } = demo; + const { props = {} } = node; + if (props.state === 'expanded') { + return { ...demo, height: 300 }; + } + + return demo; + } +}; diff --git a/docs/dialog/adaptor/index.jsx b/docs/dialog/adaptor/index.jsx new file mode 100644 index 0000000000..8189cc2583 --- /dev/null +++ b/docs/dialog/adaptor/index.jsx @@ -0,0 +1,137 @@ +import React from 'react'; +import { Dialog, Message } from '@alifd/next'; +import locale from '../../../src/locale/en-us'; +import { Types } from '@alifd/adaptor-helper'; + +export default { + name: 'Dialog', + editor: () => ({ + props: [{ + name: 'level', + type: Types.enum, + options: ['normal', 'alert', 'confirm'], + default: 'normal' + }, { + name: 'footerAlign', + type: Types.enum, + options: ['left', 'right', 'center'], + default: 'right' + }, { + name: 'okButtonPosition', + type: Types.enum, + options: ['left', 'right'], + default: 'left' + }, { + name: 'mask', + type: Types.bool, + default: false + }, { + name: 'width', + type: Types.number, + default: 400 + }, { + name: 'height', + type: Types.number, + default: 160 + }, { + name: 'title', + type: Types.string, + default: 'Welcome to Alibaba.com' + }], + data: { + default: 'Start your business here by searching a popular product' + } + }), + adaptor: ({ level, footerAlign, okButtonPosition, mask, width, height, title, style, className, data, ...others}) => { + const dialogStyle = { + position: mask ? 'absolute' : 'relative', + width: width, + ...(mask ? { + left: 20, + top: 20, + } : style), + }; + + const props = { + ...(mask ? {} : {...others }), + className: level === 'normal' ? className : `${className || ''} next-dialog-quick`, + style: dialogStyle, + footerAlign: footerAlign, + footerActions: okButtonPosition == 'left' ? ['ok', 'cancel'] : ['cancel', 'ok'], + locale: locale.Dialog, + height: `${height}px` + }; + + let dialog; + switch(level) { + case 'alert': + dialog = ( + + + {data} + + + ); + break; + case 'confirm': + dialog = ( + + + {data} + + + ); + break; + default: + dialog = {data} + break; + } + + return mask ? ( +
+
+ {dialog} +
+ ) : dialog; + }, + content: () => ({ + options: [{ + name: 'title', + options: ['show', 'hide'], + default: 'show', + }, { + name: 'overlay', + options: ['show', 'hide'], + default: 'hide', + }, { + name: 'footerAlign', + options: ['left', 'center', 'right'], + default: 'right' + }, { + name: 'okButtonPosition', + options: ['left', 'right'], + default: 'right' + }], + transform: (props, { title, overlay, footerAlign, okButtonPosition }) => { + return { + ...props, + title: title === 'hide' ? '' : title, + mask: overlay === 'show', + footerAlign, + okButtonPosition, + }; + } + }) +} diff --git a/docs/input/adaptor/index.jsx b/docs/input/adaptor/index.jsx new file mode 100644 index 0000000000..82d4878343 --- /dev/null +++ b/docs/input/adaptor/index.jsx @@ -0,0 +1,171 @@ +import React from 'react'; +import { Types } from '@alifd/adaptor-helper'; +import { Input } from '@alifd/next'; + +export default { + name: 'Input', + shape: [{ + label: 'Textfield', + value: 'textfield' + }, { + label: 'Textarea', + value: 'textarea' + }, { + label: 'Addon', + value: 'addon' + }], + editor: (shape = 'textfield') => { + return { + props: [...( + shape === 'textarea' ? [] : [{ + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }] + ), ...( + shape === 'addon' ? [] : [{ + name: 'state', + type: Types.enum, + options: ['normal', 'focused', 'disabled', 'error', ...(shape === 'textfield' ? ['success', 'loading'] : [])], + default: 'normal' + }] + ), { + name: 'widget', + type: Types.enum, + options: shape === 'textarea' ? ['none', 'length'] : ['none', 'length', 'clear'], + default: 'none' + }, { + name: 'width', + type: Types.number, + default: 200 + }, + ...(shape === 'textarea' ? [{ + name: 'rows', + type: Types.number, + default: 4, + }] : []), + ...(shape !== 'addon' ? [{ + name: 'border', + type: Types.bool, + default: true, + }] : []), + { + name: 'label', + type: Types.string, + default: '' + }, { + name: 'placeholder', + type: Types.string, + default: 'Please Input' + }, + ...(shape === 'addon' ? [{ + name: 'prefix', + type: Types.string, + default: 'https://' + }, { + name: 'suffix', + type: Types.string, + default: '.com' + }] : [])], + data: { + default: shape === 'textarea' ? 'multiple line' : shape === 'addon' ? 'alibaba' : '' + } + }; + }, + adaptor: ({ + shape, + size, + state, + widget, + width, + rows, + border, + label, + placeholder, + prefix = '', + suffix = '', + style = {}, + className = '', + data, + ...others + }) => { + const props = { + ...others, + label, + hasBorder: border, + placeholder, + className, + style: { + width, + ...style + }, + value: data + }; + + if (widget === 'length') { + props.hasLimitHint = true; + props.maxLength = 15; + } else if (widget === 'clear') { + props.hasClear = true; + } + + if (size) { + props.size = size; + } + + switch(state) { + case 'focused': + props.className = `${className} next-focus`; + break; + case 'disabled': + props.disabled = true; + break; + case 'error': + case 'loading': + case 'success': + props.state = state; + break; + default: break; + } + + + if (rows && rows > 0) { + props.rows = rows; + } + + if (shape === 'addon') { + props.addonTextAfter = suffix; + props.addonTextBefore = prefix; + } + + if (shape === 'textarea') { + return ; + } + + return ; + }, + content: (shape) => { + if (shape === 'textfield') { + return { + options: [{ + name: 'clear', + options: ['show', 'hide'], + default: 'hide', + }], + transform: (props, { clear }) => { + return { + ...props, + widget: clear === 'show' ? 'clear' : 'none', + data: clear === 'show' ? 'Input ...' : props.value, + }; + } + }; + } + + return { + options: [], + transform: p => p + }; + } +}; diff --git a/docs/loading/adaptor/index.jsx b/docs/loading/adaptor/index.jsx new file mode 100644 index 0000000000..f81f8b148d --- /dev/null +++ b/docs/loading/adaptor/index.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Loading } from '@alifd/next'; + +export default { + name: 'Loading', + editor: () => ({ + props: [{ + name: 'size', + type: 'enum', + options: ['large', 'medium'], + default: 'medium' + }], + }), + adaptor: ({ size, ...others }) => { + return
; + } +}; diff --git a/docs/menu-button/adaptor/index.jsx b/docs/menu-button/adaptor/index.jsx new file mode 100644 index 0000000000..1c67e72b5d --- /dev/null +++ b/docs/menu-button/adaptor/index.jsx @@ -0,0 +1,195 @@ +/* eslint-disable no-use-before-define */ +import React from 'react'; +import { MenuButton, Menu, Icon } from '@alifd/next'; +import { Types, parseData, ContentType } from '@alifd/adaptor-helper'; + +const createDataSouce = (list, keys = { selected: [], expanded: {} }, level = 0, prefix='') => { + const array = []; + let group = []; + let grouping = false; + let index = 0; + + list.forEach((item) => { + switch(item.type) { + // eslint-disable-next-line no-case-declarations + case 'node': + const key = `${prefix || level }-${index++}`; + + if (item.children && item.children.length > 0) { + item.children = createDataSouce(item.children, keys, level + 1, key); + } + + if (grouping) { + group.push({ + ...item, + key, + }); + } else { + array.push({ + ...item, + key + }); + } + + if (item.state === 'active') { + if (item.children && item.children.length > 0) { + keys.expanded.push(key); + } else { + keys.selected.push(key); + } + } + + return; + case 'comment': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = item.value; + return; + case 'divider': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = false; + array.push({ + type: 'divider', + key: `${prefix || level }-${index++}`, + }); + return; + default: return; + } + }); + + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + + return array; +}; + +const createMenuItem = (item) => { + if (item.children.length > 0) { + return ( + type === ContentType.text).map(({ value }) => value).join('') : ''}> + {createContents(item.children)} + + ); + } + + return type === 'icon' ? : value)} />; +}; + +const createContents = (array = []) => { + + return array.map((item) => { + if (item.type === 'group' && item.children.length > 0) { + return {item.children.map(it => createMenuItem(it))}; + } + + if (item.type === 'divider') { + return ; + } + + return createMenuItem(item); + }); +}; + +export default { + name: 'MenuButton', + shape: ['normal', 'text', 'ghost'], + editor: (shape = 'normal') => ({ + props: [{ + name: 'level', + type: Types.enum, + options: shape === 'text' ? ['normal', 'primary'] : shape === 'ghost' ? ['light', 'dark'] : ['normal', 'primary', 'secondary'], + default: shape === 'ghost' ? 'light' : 'normal', + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }], + data: { + icon: true, + active: true, + disable: true, + default: 'Edit Document\n\tUndo\n\t*Redo\n\tCut\n\tCopy\n\tPaste' + } + }), + adaptor: ({ shape, level, size, data, ...others}) => { + const list = parseData(data, { parseContent: true }); + const buttonItem = list[0] ? list[0] : { value: []}; + + if (buttonItem.type !== 'node') return null; + + const keys = { selected: [], expanded: [] }; + const dataSouce = createDataSouce(list[0] ? list[0].children : [], keys); + + const label = buttonItem.value.map(({ type, value}) => { + if (type === 'icon') return ; + return value; + }); + + return ( + node} + ghost={shape === 'ghost' ? level : false} + selectMode="multiple" + text={shape === 'text'} + menuProps={{ openKeys: keys.expanded, style: { textAlign: 'left' } }} + selectedKeys={keys.selected} + label={label} + > + {createContents(dataSouce)} + + ); + }, + demoOptions: (demo) => { + const { node = { props: {} } } = demo; + const { level, data } = node.props; + if (data.indexOf('*') === 0) { + demo = { + ...demo, + height: 250 + }; + } + + if (level === 'dark') { + demo = { + ...demo, + background: '#333' + }; + } else if(level === 'light') { + demo = { + ...demo, + background: 'rgb(235, 236, 240)', + }; + } + + return demo; + } +}; diff --git a/docs/menu/adaptor/index.jsx b/docs/menu/adaptor/index.jsx new file mode 100644 index 0000000000..6bf1700d22 --- /dev/null +++ b/docs/menu/adaptor/index.jsx @@ -0,0 +1,190 @@ +/* eslint-disable no-use-before-define */ +import React from 'react'; +import { Types, parseData, ContentType } from '@alifd/adaptor-helper'; +import { Menu, Icon } from '@alifd/next'; + +const createDataSouce = (list, keys = { selected: [], expanded: [] }, level = 0, prefix='') => { + const array = []; + let group = []; + let grouping = false; + let index = 0; + + list.forEach((item) => { + switch(item.type) { + // eslint-disable-next-line no-case-declarations + case 'node': + const key = `${prefix || level }-${index++}`; + + if (item.children && item.children.length > 0) { + item.children = createDataSouce(item.children, keys, level + 1, key); + } + + if (grouping) { + group.push({ + ...item, + key, + }); + } else { + array.push({ + ...item, + key + }); + } + + if (item.state === 'active') { + if (item.children && item.children.length > 0) { + keys.expanded.push(key); + } else { + keys.selected.push(key); + } + } + + return; + case 'comment': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = item.value; + return; + case 'divider': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = false; + array.push({ + type: 'divider', + key: `${prefix || level }-${index++}`, + }); + return; + default: return; + } + }); + + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + + return array; +}; + +const createMenuItem = (item, selectType) => { + if (item.children.length > 0) { + return ( + type === ContentType.text).map(({ value }) => value).join('') : ''}> + {createContents(item.children, selectType)} + + ); + } + + let Item = Menu.Item; + + if (selectType === 'checkbox') { + Item = Menu.CheckboxItem; + } else if (selectType === 'radio') { + Item = Menu.RadioItem; + } + + return type === 'icon' ? : value)} />; +}; + +const createContents = (array = [], selectType) => { + + return array.map((item) => { + if (item.type === 'group' && item.children.length > 0) { + return {item.children.map(it => createMenuItem(it, selectType))}; + } + + if (item.type === 'divider') { + return ; + } + + return createMenuItem(item, selectType); + }); +}; + +export default { + name: "Menu", + editor: () => ({ + props: [{ + name: 'selectType', + type: Types.enum, + options: ['checkbox', 'radio', 'checkLeft', 'checkRight'], + default: 'checkLeft' + }, { + name: 'nestMode', + type: Types.enum, + options: ['inline', 'popup'], + default: 'inline', + }, { + name: 'width', + type: Types.number, + default: 150 + }], + data: { + active: true, + disable: true, + group: true, + icon: true, + default: '#Group1\noption1\n*option2\n\tsub option3\n\t-sub option4\n\tsub option5\n---\n#Group2\noption1\n*option2' + } + }), + adaptor: ({ selectType, nestMode, width, style, data, ...others }) => { + const list = parseData(data, { parseContent: true }); + const keys = { selected: [], expanded: [] }; + const array = createDataSouce(list, keys); + + return ( + node }} isSelectIconRight={selectType === 'checkRight'} openKeys={keys.expanded} selectedKeys={keys.selected} style={{ width, ...style }} mode={nestMode === 'popup' ? 'popup' : 'inline'}> + { + createContents(array, selectType) + } + + ); + }, + content: () => ({ + options: [{ + name: 'group', + options: ['yes', 'no'], + default: 'no' + }, { + name: 'icon', + options: ['yes', 'no'], + default: 'no' + }, { + name: 'selectType', + options: ['checkbox', 'radio', 'checkLeft', 'checkRight'], + default: 'checkLeft', + }], + transform: (props, { group, icon, selectType }) => { + const iconStr = icon === 'yes' ? '[picture]' : ''; + const prefix = (props.data || '').indexOf('*') !== -1 ? '*' : (props.data || '').indexOf('-') !== -1 ? '-' : ''; + if (group === 'yes') { + props.data = `#group1\n${prefix}${iconStr}option1\n${iconStr}option2\n---\n#group2\n${iconStr}option3\n${iconStr}option4`; + } else if (icon === 'yes') { + props.data = `${iconStr}option1\n${iconStr}option2\n${iconStr}option3\n${iconStr}option4`; + } + return { + ...props, + selectType, + }; + } + }) +}; diff --git a/docs/message/adaptor/index.jsx b/docs/message/adaptor/index.jsx new file mode 100644 index 0000000000..201a57371c --- /dev/null +++ b/docs/message/adaptor/index.jsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { Message } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +export default { + name: 'Message', + editor: () => ({ + props: [{ + name: 'level', + type: Types.enum, + options: ['inline', 'toast', 'addon'], + default: 'inline' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium'], + default: 'medium' + }, { + name: 'state', + type: Types.enum, + options: ['success', 'warning', 'error', 'notice', 'help', 'loading'], + default: 'success', + }, { + name: 'closable', + type: Types.bool, + default: false + }, { + name: 'width', + type: Types.number, + default: 400 + }, { + name: 'title', + type: Types.string, + default: 'Title' + }], + data: { + default: 'This item already has the label "travel", you can add a new label.' + } + }), + adaptor: ({ level, size, state, closable, width, title, data, style, ...others}) => { + return ( + {data} + ); + } +}; diff --git a/docs/nav/adaptor/index.jsx b/docs/nav/adaptor/index.jsx new file mode 100644 index 0000000000..eb54ff844b --- /dev/null +++ b/docs/nav/adaptor/index.jsx @@ -0,0 +1,187 @@ +/* eslint-disable no-use-before-define */ +import React from 'react'; +import { Types, parseData, ContentType } from '@alifd/adaptor-helper'; +import { Nav } from '@alifd/next'; + +const createDataSouce = (list, keys = { selected: [], expanded: {} }, level = 0, prefix='') => { + const array = []; + let group = []; + let grouping = false; + let index = 0; + + list.forEach((item) => { + switch(item.type) { + // eslint-disable-next-line no-case-declarations + case 'node': + const key = `${prefix || level }-${index++}`; + + if (item.children && item.children.length > 0) { + item.children = createDataSouce(item.children, keys, level + 1, key); + } + + if (grouping) { + group.push({ + ...item, + key, + }); + } else { + array.push({ + ...item, + key + }); + } + + if (item.state === 'active') { + if (item.children && item.children.length > 0) { + keys.expanded.push(key); + } else { + keys.selected.push(key); + } + } + + return; + case 'comment': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = item.value; + return; + case 'divider': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = false; + array.push({ + type: 'divider', + key: `${prefix || level }-${index++}`, + }); + return; + default: return; + } + }); + + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + + return array; +}; + +const createMenuItem = (item) => { + const { value } = (item.value || []).find(item => item.type === ContentType.icon) || {}; + if (item.children.length > 0) { + return ( + type === ContentType.text).map(({ value }) => value).join('') : ''}> + {createContents(item.children)} + + ); + } + + return type === 'icon' ? null : value)} />; +}; + +const createContents = (array = []) => { + + return array.map((item) => { + if (item.type === 'group' && item.children.length > 0) { + return {item.children.map(it => createMenuItem(it))}; + } + + if (item.type === 'divider') { + return ; + } + + return createMenuItem(item); + }); +}; + + +export default { + name: 'Nav', + shape: [{ + label: 'Horizontal', + value: 'hoz' + }, { + label: 'Vertical', + value: 'ver' + }], + editor: (shape = 'hoz') => ({ + props: [{ + name: 'level', + type: Types.enum, + options: ['normal', 'primary', 'secondary', 'line'], + default: 'normal' + }, { + name: 'selectLinePosition', + type: Types.enum, + options: shape === 'hoz' ? ['top', 'bottom', 'none'] : ['left', 'right', 'none'], + default: shape === 'hoz' ? 'bottom' : 'right' + }, { + name: 'width', + type: Types.number, + default: shape === 'hoz' ? 640 : 200 + }, + ...(shape === 'ver' ? [{ + name: 'height', + type: Types.number, + default: shape === 'hoz' ? '' : 600 + }, { + name: 'iconOnly', + type: Types.bool, + default: false, + }] : [])], + data: { + active: true, + hover: true, + group: true, + icon: true, + default: `[account]Nav Item 1\n[account]Nav Item 2\n[account]Nav Item 3\n${shape === 'ver' ? '*' : ''}[account]Nav Item 4\n\t[account]Option 1\n\t[account]Option 2\n\t[account]Option 3\n\t[account]Option 4` + } + }), + adaptor: ({ shape, level, selectLinePosition, width, height, data, style, iconOnly = false, ...others}) => { + const list = parseData(data, { parseContent: true }); + const keys = { selected: [], expanded: [] }; + const dataSouce = createDataSouce(list, keys); + + return ( + + ); + } +}; diff --git a/docs/number-picker/adaptor/index.jsx b/docs/number-picker/adaptor/index.jsx new file mode 100644 index 0000000000..cc7243ca3c --- /dev/null +++ b/docs/number-picker/adaptor/index.jsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { NumberPicker } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +export default { + name: 'NumberPicker', + editor: () => ({ + props: [{ + name: 'level', + type: Types.enum, + options: ['normal', 'inline'], + default: 'normal' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium'], + default: 'medium' + }, { + name: 'state', + type: Types.enum, + options: ['normal', 'disabled'], + default: 'normal' + }, { + name: 'width', + type: Types.number, + default: 80 + }, { + name: 'value', + type: Types.number, + default: 1 + }] + }), + adaptor: ({ level, size, state, width, value, style, ...others }) => { + return + } +}; diff --git a/docs/pagination/adaptor/index.jsx b/docs/pagination/adaptor/index.jsx new file mode 100644 index 0000000000..f47110dc22 --- /dev/null +++ b/docs/pagination/adaptor/index.jsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { Pagination } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; +import enUS from '../../../src/locale/en-us'; + +export default { + name: 'Pagination', + shape: ['normal', 'simple', 'mini'], + editor: () => ({ + props: [{ + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'sizeSelector', + type: Types.enum, + options: ['none', 'filter', 'dropdown'], + default: 'none' + }, { + name: 'control', + type: Types.enum, + options: ['textAndIcon', 'onlyIcon', 'noBorder'], + default: 'textAndIcon' + }] + }), + adaptor: ({ shape, size, sizeSelector, control, ...others}) => { + return ( + + ); + }, + content: () => ({ + options: [{ + name: 'control', + options: ['textAndIcon', 'onlyIcon', 'noBorder'], + default: 'textAndIcon' + }], + transform: (props, { control }) => { + return { + ...props, + control + }; + } + }) +}; diff --git a/docs/paragraph/adaptor/index.jsx b/docs/paragraph/adaptor/index.jsx new file mode 100644 index 0000000000..2c4ade5c32 --- /dev/null +++ b/docs/paragraph/adaptor/index.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { Paragraph } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +export default { + name: 'Paragraph', + editor: () => ({ + props: [{ + name: 'size', + type: Types.enum, + options: ['medium', 'small'], + default: 'medium' + }, { + name: 'width', + type: Types.number, + default: 400 + }], + data: { + default: `Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.` + } + }), + adaptor: ({ size, width, style, data, ...others }) => { + return ({data}); + } +}; diff --git a/docs/progress/adaptor/index.jsx b/docs/progress/adaptor/index.jsx new file mode 100644 index 0000000000..b2d4522ed5 --- /dev/null +++ b/docs/progress/adaptor/index.jsx @@ -0,0 +1,106 @@ +import React from 'react'; +import { Types } from '@alifd/adaptor-helper'; +import { Progress } from '@alifd/next'; + +export default { + name: 'Progress', + shape: ['line', 'circle'], + editor: (shape = 'line') => { + return { + props: [{ + name: 'level', + type: Types.enum, + options: ['normal', 'success', 'error'], + default: 'normal' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'mode', + type: Types.enum, + options: ['basic', 'staging'], + default: 'basic' + }, { + name: 'text', + type: Types.bool, + default: false + }, + ...( + shape === 'line' ? + [{ + name: 'border', + type: Types.bool, + default: false + }, { + name: 'width', + type: Types.number, + default: 200 + }] : + [] + ), + { + name: 'percent', + type: Types.number, + default: 25 + }] + }; + }, + adaptor: ({ shape, level, size, mode, text, border, width, percent, style, ...others }) => { + return ( + text ? `${Math.floor(percent)}%` : false} percent={percent} state={level} progressive={mode === 'staging'} hasBorder={border} /> + ); + }, + content: (shape = 'line') => ({ + options: [{ + name: 'staging', + options: ['none', 'started', 'middle', 'finishing'], + default: 'none' + }, { + name: 'text', + options: ['show', 'hide'], + default: shape === 'cirlce' ? 'show' : 'hide' + }, { + name: 'border', + options: ['show', 'hide'], + default: 'hide' + }].filter(({ name }) => name !== 'border' || shape === 'line'), + transform: (props, { staging, text, border }) => { + switch (staging) { + case 'started': + props = { + ...props, + percent: 20, + mode: 'staging' + }; + break; + case 'middle': + props = { + ...props, + percent: 60, + mode: 'staging' + }; + break; + case 'finishing': + props = { + ...props, + percent: 85, + mode: 'staging' + }; + break; + default: break; + } + + return { + ...props, + text: text === 'show', + border: border === 'show' + }; + } + }) + +}; diff --git a/docs/radio/adaptor/index.jsx b/docs/radio/adaptor/index.jsx new file mode 100644 index 0000000000..467c772c72 --- /dev/null +++ b/docs/radio/adaptor/index.jsx @@ -0,0 +1,69 @@ +import React from 'react'; +import { Types, parseData, NodeType } from '@alifd/adaptor-helper'; +import { Radio } from '@alifd/next'; + +export default { + name: 'Radio', + shape: ['normal', {value: 'button', label: 'Radio Button'}], + editor: (shape = 'normal') => { + if (shape === 'button') { + return { + props: [{ + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'state', + type: Types.enum, + options: ['normal', 'disabled'], + default: 'normal' + }], + data: { + hover: true, + disable: true, + active: true, + default: `Cell 1\n*Cell 2\nCell 3` + } + }; + } + return { + props: [{ + name: 'state', + type: Types.enum, + options: ['normal', 'hover', 'disabled', 'checked', 'checkedHover', 'checkedDisabled'], + default: 'normal' + }, { + name: 'label', + type: Types.string, + default: 'label' + }], + } + }, + adaptor: ({ shape, size, state = '', label, data, ...others }) => { + if (shape === 'normal') { + return ( + + ); + } + + const list = parseData(data).filter(({ type }) => type === NodeType.node); + + return ( + item.state === 'active')}> + { + list.map((item, index) => {item.value}) + } + + ); + + } + +}; + diff --git a/docs/range/adaptor/index.jsx b/docs/range/adaptor/index.jsx new file mode 100644 index 0000000000..4047a4b8c7 --- /dev/null +++ b/docs/range/adaptor/index.jsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { Types } from '@alifd/adaptor-helper'; +import { Range } from '@alifd/next'; + +export default { + name: 'Range', + shape: [{ + label: 'Basic', + value: 'basic' + }, { + label: 'With Scale', + value: 'scale', + }], + editor: () => ({ + props: [{ + name: 'level', + label: 'Selection Mode', + type: Types.enum, + options: ['single', 'double'], + default: 'single' + }, { + name: 'type', + type: Types.enum, + options: ['basic', 'scale'], + default: 'basic' + }, { + name: 'scalePosition', + type: Types.enum, + options: ['above', 'below'], + default: 'above' + }, { + name: 'state', + type: Types.enum, + options: ['normal', 'hover', 'clicked', 'disabled'], + default: 'normal' + }, { + name: 'width', + type: Types.number, + default: 400 + }, { + name: 'start', + type: Types.number, + default: 0 + }, { + name: 'end', + type: Types.number, + default: 35 + }], + }), + adaptor: ({ shape, level, type, scalePosition, state, width, start, end, style, className, ...others }) => { + return ( + + ); + }, + demoOptions: (demo) => { + const { node } = demo; + const { props } = node; + if (props.level === 'double') { + props.start = 20; + props.end = 60; + } + + return demo; + } +}; diff --git a/docs/rating/adaptor/index.jsx b/docs/rating/adaptor/index.jsx new file mode 100644 index 0000000000..02d00d69cb --- /dev/null +++ b/docs/rating/adaptor/index.jsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { Types } from '@alifd/adaptor-helper'; +import { Rating } from '@alifd/next'; + +export default { + name: 'Rating', + editor: () => ({ + props: [{ + name: 'type', + type: Types.enum, + options: ['normal', 'level'], + default: 'normal' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'value', + type: Types.number, + default: 3 + }] + }), + adaptor: ({ type, size, value }) => { + return ; + } +}; diff --git a/docs/search/adaptor/index.jsx b/docs/search/adaptor/index.jsx new file mode 100644 index 0000000000..0ce0008432 --- /dev/null +++ b/docs/search/adaptor/index.jsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { Types } from '@alifd/adaptor-helper'; +import { Search } from '@alifd/next'; + +export default { + name: 'Search', + shape: [{ + value: 'normal', + label: 'Basic' + }, { + value: 'simple', + label: 'Simple' + }], + editor: (shape = 'normal') => ({ + props: [{ + name: 'level', + type: Types.enum, + options: shape === 'simple' ? ['normal', 'dark'] : ['normal', 'primary', 'secondary', 'dark'], + default: 'normal' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium'], + default: 'medium' + }, { + name: 'menu', + type: Types.bool, + default: true + }, { + name: 'placeholder', + type: Types.string, + default: 'Please Input' + }, + ...( + shape === 'normal' ? [{ + name: 'label', + type: Types.bool, + default: true + }] : [] + ), { + name: 'width', + type: Types.number, + default: shape === 'normal' ? 400 : 380 + }] + }), + adaptor: ({ shape, level, size, menu, label, width, style, ...others }) => { + return ( + + ); + }, + content: (shape) => ({ + options: [{ + name: 'menu', + options: ['show', 'hide'], + default: 'show' + }, { + name: 'buttonLabel', + options: ['show', 'hide'], + default: 'show' + }].filter(({ name }) => name !== 'buttonLabel' || shape === 'normal'), + transform: (props, { menu, buttonLabel }) => { + return { + ...props, + menu: menu === 'show', + label: buttonLabel === 'show' + }; + } + }), + demoOptions: (demo) => { + if (demo.node.props.level === 'dark') { + return { + ...demo, + background: '#333' + }; + } + return { + ...demo + }; + } +}; + diff --git a/docs/select/adaptor/index.jsx b/docs/select/adaptor/index.jsx new file mode 100644 index 0000000000..b2509b3c11 --- /dev/null +++ b/docs/select/adaptor/index.jsx @@ -0,0 +1,98 @@ +import React from 'react'; +import { Types, parseData, NodeType } from '@alifd/adaptor-helper'; +import { Select } from '@alifd/next'; + +export default { + name: 'Select', + editor: () => ({ + props: [{ + name: 'level', + label: 'Type', + type: Types.enum, + options: ['single', 'multiple'], + default: 'single' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'state', + type: Types.enum, + options: ['normal', 'expanded', 'disabled'], + default: 'normal' + }, { + name: 'border', + type: Types.bool, + default: true + }, { + name: 'width', + type: Types.number, + default: 200 + }, { + name: 'label', + type: Types.string, + default: '' + }, { + name: 'placeholder', + type: Types.string, + default: 'Please Select' + }], + data: { + disable: true, + active: true, + default: 'Option 1\n*Option 2\nOption 3\nOption 4\nOption 5' + } + }), + adaptor: ({ level, size, state, border, width, label, placeholder, data, style, ...others }) => { + const list = parseData(data).filter(({ type }) => NodeType.node === type); + const dataSource = []; + const value = []; + + list.forEach((item, index) => { + dataSource.push({ + label: item.value, + value: index, + disabled: item.state === 'disabled' + }); + if (item.state === 'active') { + value.push(index); + } + }); + + return ( + ; + }, + content: (shape) => { + if (shape === 'textfield') { + return { + options: [{ + name: 'clear', + options: ['show', 'hide'], + default: 'hide', + }], + transform: (props, { clear }) => { + return { + ...props, + widget: clear === 'show' ? 'clear' : 'none', + data: clear === 'show' ? 'Input ...' : props.value, + }; + } + }; + } + + return { + options: [], + transform: p => p + }; + } +}; diff --git a/docs/loading/adaptor/index.jsx b/docs/loading/adaptor/index.jsx new file mode 100644 index 0000000000..f81f8b148d --- /dev/null +++ b/docs/loading/adaptor/index.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Loading } from '@alifd/next'; + +export default { + name: 'Loading', + editor: () => ({ + props: [{ + name: 'size', + type: 'enum', + options: ['large', 'medium'], + default: 'medium' + }], + }), + adaptor: ({ size, ...others }) => { + return
; + } +}; diff --git a/docs/menu-button/adaptor/index.jsx b/docs/menu-button/adaptor/index.jsx new file mode 100644 index 0000000000..1c67e72b5d --- /dev/null +++ b/docs/menu-button/adaptor/index.jsx @@ -0,0 +1,195 @@ +/* eslint-disable no-use-before-define */ +import React from 'react'; +import { MenuButton, Menu, Icon } from '@alifd/next'; +import { Types, parseData, ContentType } from '@alifd/adaptor-helper'; + +const createDataSouce = (list, keys = { selected: [], expanded: {} }, level = 0, prefix='') => { + const array = []; + let group = []; + let grouping = false; + let index = 0; + + list.forEach((item) => { + switch(item.type) { + // eslint-disable-next-line no-case-declarations + case 'node': + const key = `${prefix || level }-${index++}`; + + if (item.children && item.children.length > 0) { + item.children = createDataSouce(item.children, keys, level + 1, key); + } + + if (grouping) { + group.push({ + ...item, + key, + }); + } else { + array.push({ + ...item, + key + }); + } + + if (item.state === 'active') { + if (item.children && item.children.length > 0) { + keys.expanded.push(key); + } else { + keys.selected.push(key); + } + } + + return; + case 'comment': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = item.value; + return; + case 'divider': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = false; + array.push({ + type: 'divider', + key: `${prefix || level }-${index++}`, + }); + return; + default: return; + } + }); + + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + + return array; +}; + +const createMenuItem = (item) => { + if (item.children.length > 0) { + return ( + type === ContentType.text).map(({ value }) => value).join('') : ''}> + {createContents(item.children)} + + ); + } + + return type === 'icon' ? : value)} />; +}; + +const createContents = (array = []) => { + + return array.map((item) => { + if (item.type === 'group' && item.children.length > 0) { + return {item.children.map(it => createMenuItem(it))}; + } + + if (item.type === 'divider') { + return ; + } + + return createMenuItem(item); + }); +}; + +export default { + name: 'MenuButton', + shape: ['normal', 'text', 'ghost'], + editor: (shape = 'normal') => ({ + props: [{ + name: 'level', + type: Types.enum, + options: shape === 'text' ? ['normal', 'primary'] : shape === 'ghost' ? ['light', 'dark'] : ['normal', 'primary', 'secondary'], + default: shape === 'ghost' ? 'light' : 'normal', + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }], + data: { + icon: true, + active: true, + disable: true, + default: 'Edit Document\n\tUndo\n\t*Redo\n\tCut\n\tCopy\n\tPaste' + } + }), + adaptor: ({ shape, level, size, data, ...others}) => { + const list = parseData(data, { parseContent: true }); + const buttonItem = list[0] ? list[0] : { value: []}; + + if (buttonItem.type !== 'node') return null; + + const keys = { selected: [], expanded: [] }; + const dataSouce = createDataSouce(list[0] ? list[0].children : [], keys); + + const label = buttonItem.value.map(({ type, value}) => { + if (type === 'icon') return ; + return value; + }); + + return ( + node} + ghost={shape === 'ghost' ? level : false} + selectMode="multiple" + text={shape === 'text'} + menuProps={{ openKeys: keys.expanded, style: { textAlign: 'left' } }} + selectedKeys={keys.selected} + label={label} + > + {createContents(dataSouce)} + + ); + }, + demoOptions: (demo) => { + const { node = { props: {} } } = demo; + const { level, data } = node.props; + if (data.indexOf('*') === 0) { + demo = { + ...demo, + height: 250 + }; + } + + if (level === 'dark') { + demo = { + ...demo, + background: '#333' + }; + } else if(level === 'light') { + demo = { + ...demo, + background: 'rgb(235, 236, 240)', + }; + } + + return demo; + } +}; diff --git a/docs/menu/adaptor/index.jsx b/docs/menu/adaptor/index.jsx new file mode 100644 index 0000000000..6bf1700d22 --- /dev/null +++ b/docs/menu/adaptor/index.jsx @@ -0,0 +1,190 @@ +/* eslint-disable no-use-before-define */ +import React from 'react'; +import { Types, parseData, ContentType } from '@alifd/adaptor-helper'; +import { Menu, Icon } from '@alifd/next'; + +const createDataSouce = (list, keys = { selected: [], expanded: [] }, level = 0, prefix='') => { + const array = []; + let group = []; + let grouping = false; + let index = 0; + + list.forEach((item) => { + switch(item.type) { + // eslint-disable-next-line no-case-declarations + case 'node': + const key = `${prefix || level }-${index++}`; + + if (item.children && item.children.length > 0) { + item.children = createDataSouce(item.children, keys, level + 1, key); + } + + if (grouping) { + group.push({ + ...item, + key, + }); + } else { + array.push({ + ...item, + key + }); + } + + if (item.state === 'active') { + if (item.children && item.children.length > 0) { + keys.expanded.push(key); + } else { + keys.selected.push(key); + } + } + + return; + case 'comment': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = item.value; + return; + case 'divider': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = false; + array.push({ + type: 'divider', + key: `${prefix || level }-${index++}`, + }); + return; + default: return; + } + }); + + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + + return array; +}; + +const createMenuItem = (item, selectType) => { + if (item.children.length > 0) { + return ( + type === ContentType.text).map(({ value }) => value).join('') : ''}> + {createContents(item.children, selectType)} + + ); + } + + let Item = Menu.Item; + + if (selectType === 'checkbox') { + Item = Menu.CheckboxItem; + } else if (selectType === 'radio') { + Item = Menu.RadioItem; + } + + return type === 'icon' ? : value)} />; +}; + +const createContents = (array = [], selectType) => { + + return array.map((item) => { + if (item.type === 'group' && item.children.length > 0) { + return {item.children.map(it => createMenuItem(it, selectType))}; + } + + if (item.type === 'divider') { + return ; + } + + return createMenuItem(item, selectType); + }); +}; + +export default { + name: "Menu", + editor: () => ({ + props: [{ + name: 'selectType', + type: Types.enum, + options: ['checkbox', 'radio', 'checkLeft', 'checkRight'], + default: 'checkLeft' + }, { + name: 'nestMode', + type: Types.enum, + options: ['inline', 'popup'], + default: 'inline', + }, { + name: 'width', + type: Types.number, + default: 150 + }], + data: { + active: true, + disable: true, + group: true, + icon: true, + default: '#Group1\noption1\n*option2\n\tsub option3\n\t-sub option4\n\tsub option5\n---\n#Group2\noption1\n*option2' + } + }), + adaptor: ({ selectType, nestMode, width, style, data, ...others }) => { + const list = parseData(data, { parseContent: true }); + const keys = { selected: [], expanded: [] }; + const array = createDataSouce(list, keys); + + return ( + node }} isSelectIconRight={selectType === 'checkRight'} openKeys={keys.expanded} selectedKeys={keys.selected} style={{ width, ...style }} mode={nestMode === 'popup' ? 'popup' : 'inline'}> + { + createContents(array, selectType) + } + + ); + }, + content: () => ({ + options: [{ + name: 'group', + options: ['yes', 'no'], + default: 'no' + }, { + name: 'icon', + options: ['yes', 'no'], + default: 'no' + }, { + name: 'selectType', + options: ['checkbox', 'radio', 'checkLeft', 'checkRight'], + default: 'checkLeft', + }], + transform: (props, { group, icon, selectType }) => { + const iconStr = icon === 'yes' ? '[picture]' : ''; + const prefix = (props.data || '').indexOf('*') !== -1 ? '*' : (props.data || '').indexOf('-') !== -1 ? '-' : ''; + if (group === 'yes') { + props.data = `#group1\n${prefix}${iconStr}option1\n${iconStr}option2\n---\n#group2\n${iconStr}option3\n${iconStr}option4`; + } else if (icon === 'yes') { + props.data = `${iconStr}option1\n${iconStr}option2\n${iconStr}option3\n${iconStr}option4`; + } + return { + ...props, + selectType, + }; + } + }) +}; diff --git a/docs/message/adaptor/index.jsx b/docs/message/adaptor/index.jsx new file mode 100644 index 0000000000..201a57371c --- /dev/null +++ b/docs/message/adaptor/index.jsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { Message } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +export default { + name: 'Message', + editor: () => ({ + props: [{ + name: 'level', + type: Types.enum, + options: ['inline', 'toast', 'addon'], + default: 'inline' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium'], + default: 'medium' + }, { + name: 'state', + type: Types.enum, + options: ['success', 'warning', 'error', 'notice', 'help', 'loading'], + default: 'success', + }, { + name: 'closable', + type: Types.bool, + default: false + }, { + name: 'width', + type: Types.number, + default: 400 + }, { + name: 'title', + type: Types.string, + default: 'Title' + }], + data: { + default: 'This item already has the label "travel", you can add a new label.' + } + }), + adaptor: ({ level, size, state, closable, width, title, data, style, ...others}) => { + return ( + {data} + ); + } +}; diff --git a/docs/nav/adaptor/index.jsx b/docs/nav/adaptor/index.jsx new file mode 100644 index 0000000000..eb54ff844b --- /dev/null +++ b/docs/nav/adaptor/index.jsx @@ -0,0 +1,187 @@ +/* eslint-disable no-use-before-define */ +import React from 'react'; +import { Types, parseData, ContentType } from '@alifd/adaptor-helper'; +import { Nav } from '@alifd/next'; + +const createDataSouce = (list, keys = { selected: [], expanded: {} }, level = 0, prefix='') => { + const array = []; + let group = []; + let grouping = false; + let index = 0; + + list.forEach((item) => { + switch(item.type) { + // eslint-disable-next-line no-case-declarations + case 'node': + const key = `${prefix || level }-${index++}`; + + if (item.children && item.children.length > 0) { + item.children = createDataSouce(item.children, keys, level + 1, key); + } + + if (grouping) { + group.push({ + ...item, + key, + }); + } else { + array.push({ + ...item, + key + }); + } + + if (item.state === 'active') { + if (item.children && item.children.length > 0) { + keys.expanded.push(key); + } else { + keys.selected.push(key); + } + } + + return; + case 'comment': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = item.value; + return; + case 'divider': + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + grouping = false; + array.push({ + type: 'divider', + key: `${prefix || level }-${index++}`, + }); + return; + default: return; + } + }); + + if (group.length > 0) { + array.push({ + type: 'group', + value: grouping, + children: group, + key: `${prefix || level }-${index++}` + }); + group = []; + } + + return array; +}; + +const createMenuItem = (item) => { + const { value } = (item.value || []).find(item => item.type === ContentType.icon) || {}; + if (item.children.length > 0) { + return ( + type === ContentType.text).map(({ value }) => value).join('') : ''}> + {createContents(item.children)} + + ); + } + + return type === 'icon' ? null : value)} />; +}; + +const createContents = (array = []) => { + + return array.map((item) => { + if (item.type === 'group' && item.children.length > 0) { + return {item.children.map(it => createMenuItem(it))}; + } + + if (item.type === 'divider') { + return ; + } + + return createMenuItem(item); + }); +}; + + +export default { + name: 'Nav', + shape: [{ + label: 'Horizontal', + value: 'hoz' + }, { + label: 'Vertical', + value: 'ver' + }], + editor: (shape = 'hoz') => ({ + props: [{ + name: 'level', + type: Types.enum, + options: ['normal', 'primary', 'secondary', 'line'], + default: 'normal' + }, { + name: 'selectLinePosition', + type: Types.enum, + options: shape === 'hoz' ? ['top', 'bottom', 'none'] : ['left', 'right', 'none'], + default: shape === 'hoz' ? 'bottom' : 'right' + }, { + name: 'width', + type: Types.number, + default: shape === 'hoz' ? 640 : 200 + }, + ...(shape === 'ver' ? [{ + name: 'height', + type: Types.number, + default: shape === 'hoz' ? '' : 600 + }, { + name: 'iconOnly', + type: Types.bool, + default: false, + }] : [])], + data: { + active: true, + hover: true, + group: true, + icon: true, + default: `[account]Nav Item 1\n[account]Nav Item 2\n[account]Nav Item 3\n${shape === 'ver' ? '*' : ''}[account]Nav Item 4\n\t[account]Option 1\n\t[account]Option 2\n\t[account]Option 3\n\t[account]Option 4` + } + }), + adaptor: ({ shape, level, selectLinePosition, width, height, data, style, iconOnly = false, ...others}) => { + const list = parseData(data, { parseContent: true }); + const keys = { selected: [], expanded: [] }; + const dataSouce = createDataSouce(list, keys); + + return ( + + ); + } +}; diff --git a/docs/number-picker/adaptor/index.jsx b/docs/number-picker/adaptor/index.jsx new file mode 100644 index 0000000000..cc7243ca3c --- /dev/null +++ b/docs/number-picker/adaptor/index.jsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { NumberPicker } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +export default { + name: 'NumberPicker', + editor: () => ({ + props: [{ + name: 'level', + type: Types.enum, + options: ['normal', 'inline'], + default: 'normal' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium'], + default: 'medium' + }, { + name: 'state', + type: Types.enum, + options: ['normal', 'disabled'], + default: 'normal' + }, { + name: 'width', + type: Types.number, + default: 80 + }, { + name: 'value', + type: Types.number, + default: 1 + }] + }), + adaptor: ({ level, size, state, width, value, style, ...others }) => { + return + } +}; diff --git a/docs/pagination/adaptor/index.jsx b/docs/pagination/adaptor/index.jsx new file mode 100644 index 0000000000..f47110dc22 --- /dev/null +++ b/docs/pagination/adaptor/index.jsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { Pagination } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; +import enUS from '../../../src/locale/en-us'; + +export default { + name: 'Pagination', + shape: ['normal', 'simple', 'mini'], + editor: () => ({ + props: [{ + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'sizeSelector', + type: Types.enum, + options: ['none', 'filter', 'dropdown'], + default: 'none' + }, { + name: 'control', + type: Types.enum, + options: ['textAndIcon', 'onlyIcon', 'noBorder'], + default: 'textAndIcon' + }] + }), + adaptor: ({ shape, size, sizeSelector, control, ...others}) => { + return ( + + ); + }, + content: () => ({ + options: [{ + name: 'control', + options: ['textAndIcon', 'onlyIcon', 'noBorder'], + default: 'textAndIcon' + }], + transform: (props, { control }) => { + return { + ...props, + control + }; + } + }) +}; diff --git a/docs/paragraph/adaptor/index.jsx b/docs/paragraph/adaptor/index.jsx new file mode 100644 index 0000000000..2c4ade5c32 --- /dev/null +++ b/docs/paragraph/adaptor/index.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { Paragraph } from '@alifd/next'; +import { Types } from '@alifd/adaptor-helper'; + +export default { + name: 'Paragraph', + editor: () => ({ + props: [{ + name: 'size', + type: Types.enum, + options: ['medium', 'small'], + default: 'medium' + }, { + name: 'width', + type: Types.number, + default: 400 + }], + data: { + default: `Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.` + } + }), + adaptor: ({ size, width, style, data, ...others }) => { + return ({data}); + } +}; diff --git a/docs/progress/adaptor/index.jsx b/docs/progress/adaptor/index.jsx new file mode 100644 index 0000000000..b2d4522ed5 --- /dev/null +++ b/docs/progress/adaptor/index.jsx @@ -0,0 +1,106 @@ +import React from 'react'; +import { Types } from '@alifd/adaptor-helper'; +import { Progress } from '@alifd/next'; + +export default { + name: 'Progress', + shape: ['line', 'circle'], + editor: (shape = 'line') => { + return { + props: [{ + name: 'level', + type: Types.enum, + options: ['normal', 'success', 'error'], + default: 'normal' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'mode', + type: Types.enum, + options: ['basic', 'staging'], + default: 'basic' + }, { + name: 'text', + type: Types.bool, + default: false + }, + ...( + shape === 'line' ? + [{ + name: 'border', + type: Types.bool, + default: false + }, { + name: 'width', + type: Types.number, + default: 200 + }] : + [] + ), + { + name: 'percent', + type: Types.number, + default: 25 + }] + }; + }, + adaptor: ({ shape, level, size, mode, text, border, width, percent, style, ...others }) => { + return ( + text ? `${Math.floor(percent)}%` : false} percent={percent} state={level} progressive={mode === 'staging'} hasBorder={border} /> + ); + }, + content: (shape = 'line') => ({ + options: [{ + name: 'staging', + options: ['none', 'started', 'middle', 'finishing'], + default: 'none' + }, { + name: 'text', + options: ['show', 'hide'], + default: shape === 'cirlce' ? 'show' : 'hide' + }, { + name: 'border', + options: ['show', 'hide'], + default: 'hide' + }].filter(({ name }) => name !== 'border' || shape === 'line'), + transform: (props, { staging, text, border }) => { + switch (staging) { + case 'started': + props = { + ...props, + percent: 20, + mode: 'staging' + }; + break; + case 'middle': + props = { + ...props, + percent: 60, + mode: 'staging' + }; + break; + case 'finishing': + props = { + ...props, + percent: 85, + mode: 'staging' + }; + break; + default: break; + } + + return { + ...props, + text: text === 'show', + border: border === 'show' + }; + } + }) + +}; diff --git a/docs/radio/adaptor/index.jsx b/docs/radio/adaptor/index.jsx new file mode 100644 index 0000000000..467c772c72 --- /dev/null +++ b/docs/radio/adaptor/index.jsx @@ -0,0 +1,69 @@ +import React from 'react'; +import { Types, parseData, NodeType } from '@alifd/adaptor-helper'; +import { Radio } from '@alifd/next'; + +export default { + name: 'Radio', + shape: ['normal', {value: 'button', label: 'Radio Button'}], + editor: (shape = 'normal') => { + if (shape === 'button') { + return { + props: [{ + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'state', + type: Types.enum, + options: ['normal', 'disabled'], + default: 'normal' + }], + data: { + hover: true, + disable: true, + active: true, + default: `Cell 1\n*Cell 2\nCell 3` + } + }; + } + return { + props: [{ + name: 'state', + type: Types.enum, + options: ['normal', 'hover', 'disabled', 'checked', 'checkedHover', 'checkedDisabled'], + default: 'normal' + }, { + name: 'label', + type: Types.string, + default: 'label' + }], + } + }, + adaptor: ({ shape, size, state = '', label, data, ...others }) => { + if (shape === 'normal') { + return ( + + ); + } + + const list = parseData(data).filter(({ type }) => type === NodeType.node); + + return ( + item.state === 'active')}> + { + list.map((item, index) => {item.value}) + } + + ); + + } + +}; + diff --git a/docs/range/adaptor/index.jsx b/docs/range/adaptor/index.jsx new file mode 100644 index 0000000000..4047a4b8c7 --- /dev/null +++ b/docs/range/adaptor/index.jsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { Types } from '@alifd/adaptor-helper'; +import { Range } from '@alifd/next'; + +export default { + name: 'Range', + shape: [{ + label: 'Basic', + value: 'basic' + }, { + label: 'With Scale', + value: 'scale', + }], + editor: () => ({ + props: [{ + name: 'level', + label: 'Selection Mode', + type: Types.enum, + options: ['single', 'double'], + default: 'single' + }, { + name: 'type', + type: Types.enum, + options: ['basic', 'scale'], + default: 'basic' + }, { + name: 'scalePosition', + type: Types.enum, + options: ['above', 'below'], + default: 'above' + }, { + name: 'state', + type: Types.enum, + options: ['normal', 'hover', 'clicked', 'disabled'], + default: 'normal' + }, { + name: 'width', + type: Types.number, + default: 400 + }, { + name: 'start', + type: Types.number, + default: 0 + }, { + name: 'end', + type: Types.number, + default: 35 + }], + }), + adaptor: ({ shape, level, type, scalePosition, state, width, start, end, style, className, ...others }) => { + return ( + + ); + }, + demoOptions: (demo) => { + const { node } = demo; + const { props } = node; + if (props.level === 'double') { + props.start = 20; + props.end = 60; + } + + return demo; + } +}; diff --git a/docs/rating/adaptor/index.jsx b/docs/rating/adaptor/index.jsx new file mode 100644 index 0000000000..02d00d69cb --- /dev/null +++ b/docs/rating/adaptor/index.jsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { Types } from '@alifd/adaptor-helper'; +import { Rating } from '@alifd/next'; + +export default { + name: 'Rating', + editor: () => ({ + props: [{ + name: 'type', + type: Types.enum, + options: ['normal', 'level'], + default: 'normal' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'value', + type: Types.number, + default: 3 + }] + }), + adaptor: ({ type, size, value }) => { + return ; + } +}; diff --git a/docs/search/adaptor/index.jsx b/docs/search/adaptor/index.jsx new file mode 100644 index 0000000000..0ce0008432 --- /dev/null +++ b/docs/search/adaptor/index.jsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { Types } from '@alifd/adaptor-helper'; +import { Search } from '@alifd/next'; + +export default { + name: 'Search', + shape: [{ + value: 'normal', + label: 'Basic' + }, { + value: 'simple', + label: 'Simple' + }], + editor: (shape = 'normal') => ({ + props: [{ + name: 'level', + type: Types.enum, + options: shape === 'simple' ? ['normal', 'dark'] : ['normal', 'primary', 'secondary', 'dark'], + default: 'normal' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium'], + default: 'medium' + }, { + name: 'menu', + type: Types.bool, + default: true + }, { + name: 'placeholder', + type: Types.string, + default: 'Please Input' + }, + ...( + shape === 'normal' ? [{ + name: 'label', + type: Types.bool, + default: true + }] : [] + ), { + name: 'width', + type: Types.number, + default: shape === 'normal' ? 400 : 380 + }] + }), + adaptor: ({ shape, level, size, menu, label, width, style, ...others }) => { + return ( + + ); + }, + content: (shape) => ({ + options: [{ + name: 'menu', + options: ['show', 'hide'], + default: 'show' + }, { + name: 'buttonLabel', + options: ['show', 'hide'], + default: 'show' + }].filter(({ name }) => name !== 'buttonLabel' || shape === 'normal'), + transform: (props, { menu, buttonLabel }) => { + return { + ...props, + menu: menu === 'show', + label: buttonLabel === 'show' + }; + } + }), + demoOptions: (demo) => { + if (demo.node.props.level === 'dark') { + return { + ...demo, + background: '#333' + }; + } + return { + ...demo + }; + } +}; + diff --git a/docs/select/adaptor/index.jsx b/docs/select/adaptor/index.jsx new file mode 100644 index 0000000000..b2509b3c11 --- /dev/null +++ b/docs/select/adaptor/index.jsx @@ -0,0 +1,98 @@ +import React from 'react'; +import { Types, parseData, NodeType } from '@alifd/adaptor-helper'; +import { Select } from '@alifd/next'; + +export default { + name: 'Select', + editor: () => ({ + props: [{ + name: 'level', + label: 'Type', + type: Types.enum, + options: ['single', 'multiple'], + default: 'single' + }, { + name: 'size', + type: Types.enum, + options: ['large', 'medium', 'small'], + default: 'medium' + }, { + name: 'state', + type: Types.enum, + options: ['normal', 'expanded', 'disabled'], + default: 'normal' + }, { + name: 'border', + type: Types.bool, + default: true + }, { + name: 'width', + type: Types.number, + default: 200 + }, { + name: 'label', + type: Types.string, + default: '' + }, { + name: 'placeholder', + type: Types.string, + default: 'Please Select' + }], + data: { + disable: true, + active: true, + default: 'Option 1\n*Option 2\nOption 3\nOption 4\nOption 5' + } + }), + adaptor: ({ level, size, state, border, width, label, placeholder, data, style, ...others }) => { + const list = parseData(data).filter(({ type }) => NodeType.node === type); + const dataSource = []; + const value = []; + + list.forEach((item, index) => { + dataSource.push({ + label: item.value, + value: index, + disabled: item.state === 'disabled' + }); + if (item.state === 'active') { + value.push(index); + } + }); + + return ( +