├── examples ├── assets │ ├── styles │ │ ├── common.css │ │ └── fonts │ │ │ ├── icomoon.eot │ │ │ ├── icomoon.ttf │ │ │ ├── icomoon.woff │ │ │ └── style.css │ └── images │ │ ├── guide.png │ │ ├── qrcode.png │ │ ├── stars.png │ │ ├── feedback.png │ │ ├── navbar_0.png │ │ ├── navbar_1.png │ │ ├── navbar_2.png │ │ ├── navbar_3.png │ │ ├── resource.png │ │ ├── component.png │ │ ├── consistency.png │ │ ├── efficiency.png │ │ ├── hamburger.png │ │ ├── element-demo.jpeg │ │ └── controllability.png ├── versions.json ├── favicon.ico ├── i18n │ ├── route.json │ ├── title.json │ └── component.json ├── docs │ ├── zh-CN │ │ ├── home.md │ │ ├── breadcrumb.md │ │ ├── installation.md │ │ └── icon.md │ └── en-US │ │ ├── home.md │ │ ├── icon.md │ │ ├── breadcrumb.md │ │ ├── installation.md │ │ └── color-picker.md ├── play.js ├── play │ ├── index.vue │ └── component.vue ├── icon.json ├── dom │ └── class.js ├── entry.js ├── index.tpl └── pages │ └── template │ └── guide.tpl ├── packages ├── theme-default │ ├── src │ │ ├── submenu.css │ │ ├── button-group.css │ │ ├── form-item.css │ │ ├── menu-item.css │ │ ├── tab-pane.css │ │ ├── breadcrumb-item.css │ │ ├── checkbox-group.css │ │ ├── collapse-item.css │ │ ├── dropdown-item.css │ │ ├── dropdown-menu.css │ │ ├── menu-item-group.css │ │ ├── base.css │ │ ├── fonts │ │ │ ├── element-icons.ttf │ │ │ └── element-icons.woff │ │ ├── time-picker.css │ │ ├── radio-group.css │ │ ├── steps.css │ │ ├── date-picker.css │ │ ├── common │ │ │ ├── popup.css │ │ │ └── transition.css │ │ ├── option-group.css │ │ ├── core │ │ │ ├── tag.css │ │ │ ├── dropdown.css │ │ │ ├── input.css │ │ │ └── option.css │ │ ├── card.css │ │ ├── date-picker │ │ │ ├── time-range-picker.css │ │ │ ├── picker.css │ │ │ ├── month-table.css │ │ │ ├── year-table.css │ │ │ ├── time-spinner.css │ │ │ ├── date-picker.css │ │ │ ├── time-picker.css │ │ │ └── date-table.css │ │ ├── row.css │ │ ├── time-select.css │ │ ├── spinner.css │ │ ├── breadcrumb.css │ │ ├── rate.css │ │ ├── badge.css │ │ ├── carousel-item.css │ │ ├── option.css │ │ ├── reset.css │ │ ├── collapse.css │ │ ├── scrollbar.css │ │ ├── mixins │ │ │ └── _button.css │ │ ├── select-dropdown.css │ │ ├── index.css │ │ ├── dropdown.css │ │ ├── loading.css │ │ ├── autocomplete.css │ │ ├── message.css │ │ ├── alert.css │ │ ├── notification.css │ │ └── table-column.css │ ├── .gitignore │ ├── salad.config.json │ ├── gulpfile.js │ ├── README.md │ └── package.json ├── message │ ├── index.js │ ├── assets │ │ ├── success.svg │ │ ├── info.svg │ │ ├── warning.svg │ │ └── error.svg │ └── src │ │ └── main.js ├── message-box │ └── index.js ├── notification │ └── index.js ├── popover │ ├── src │ │ └── directive.js │ └── index.js ├── card │ ├── index.js │ └── src │ │ └── main.vue ├── rate │ └── index.js ├── tag │ ├── index.js │ └── src │ │ └── tag.vue ├── tree │ ├── index.js │ └── src │ │ └── model │ │ └── util.js ├── alert │ └── index.js ├── badge │ ├── index.js │ └── src │ │ └── main.vue ├── form │ └── index.js ├── menu │ ├── index.js │ └── src │ │ ├── menu-item-group.vue │ │ ├── menu-item.vue │ │ └── menu-mixin.js ├── radio │ ├── index.js │ └── src │ │ ├── radio-group.vue │ │ ├── radio-button.vue │ │ └── radio.vue ├── row │ ├── index.js │ └── src │ │ └── row.vue ├── step │ └── index.js ├── steps │ ├── index.js │ ├── src │ │ └── steps.vue │ └── README.md ├── tabs │ ├── index.js │ └── src │ │ ├── tab-pane.vue │ │ └── tab-bar.vue ├── upload │ ├── index.js │ ├── cooking.conf.js │ ├── package.json │ └── src │ │ ├── upload-dragger.vue │ │ └── ajax.js ├── icon │ ├── index.js │ └── src │ │ └── icon.vue ├── select │ ├── index.js │ └── src │ │ ├── option-group.vue │ │ └── select-dropdown.vue ├── slider │ └── index.js ├── col │ ├── index.js │ └── src │ │ └── col.js ├── input │ └── index.js ├── loading │ ├── cooking.conf.js │ ├── index.js │ ├── package.json │ ├── src │ │ └── loading.vue │ └── README.md ├── table │ ├── index.js │ ├── cooking.conf.js │ ├── _index.js │ ├── package.json │ └── src │ │ └── dropdown.js ├── tooltip │ └── index.js ├── button │ ├── index.js │ └── src │ │ ├── button-group.vue │ │ └── button.vue ├── carousel │ ├── index.js │ ├── cooking.conf.js │ ├── _index.js │ └── package.json ├── cascader │ ├── index.js │ ├── package.json │ └── cooking.conf.js ├── pagination │ ├── cooking.conf.js │ ├── index.js │ ├── package.json │ └── README.md ├── spinner │ ├── index.js │ └── src │ │ └── spinner.vue ├── color-picker │ ├── cooking.conf.js │ ├── index.js │ ├── package.json │ └── src │ │ └── draggable.js ├── dialog │ └── index.js ├── scrollbar │ ├── index.js │ └── src │ │ └── util.js ├── option │ └── index.js ├── switch │ └── index.js ├── tab-pane │ └── index.js ├── checkbox │ ├── index.js │ └── src │ │ └── checkbox-group.vue ├── date-picker │ ├── cooking.conf.js │ ├── index.js │ ├── src │ │ └── picker │ │ │ ├── time-select.js │ │ │ ├── time-picker.js │ │ │ └── date-picker.js │ ├── package.json │ ├── _index.js │ └── README.md ├── dropdown │ ├── index.js │ └── src │ │ ├── dropdown-item.vue │ │ └── dropdown-menu.vue ├── progress │ └── index.js ├── submenu │ └── index.js ├── form-item │ └── index.js ├── menu-item │ └── index.js ├── breadcrumb │ ├── index.js │ └── src │ │ ├── breadcrumb.vue │ │ └── breadcrumb-item.vue ├── collapse │ ├── index.js │ └── src │ │ ├── collapse.vue │ │ └── collapse-item.vue ├── radio-group │ └── index.js ├── input-number │ └── index.js ├── radio-button │ └── index.js ├── time-picker │ └── index.js ├── time-select │ └── index.js ├── autocomplete │ └── index.js ├── button-group │ └── index.js ├── carousel-item │ └── index.js ├── option-group │ └── index.js ├── table-column │ └── index.js ├── dropdown-item │ └── index.js ├── dropdown-menu │ └── index.js ├── collapse-item │ └── index.js ├── menu-item-group │ └── index.js ├── checkbox-group │ └── index.js └── breadcrumb-item │ └── index.js ├── .gitattributes ├── .eslintignore ├── src ├── mixins │ ├── locale.js │ ├── emitter.js │ └── migrating.js ├── utils │ ├── vdom.js │ ├── merge.js │ ├── util.js │ ├── scrollbar-width.js │ ├── sync.js │ └── clickoutside.js └── locale │ ├── format.js │ ├── index.js │ └── lang │ ├── zh-CN.js │ ├── zh-TW.js │ ├── ja.js │ ├── ko.js │ └── sv-SE.js ├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── CONTRIBUTING.zh-CN.md ├── .gitignore ├── .eslintrc ├── lerna.json ├── .babelrc ├── .travis.yml ├── test └── unit │ ├── index.js │ ├── specs │ ├── breadcrumb.spec.js │ ├── card.spec.js │ ├── badge.spec.js │ ├── row.spec.js │ └── alert.spec.js │ └── karma.conf.js ├── LICENSE └── Makefile /examples/assets/styles/common.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/theme-default/src/submenu.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/button-group.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/form-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/menu-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/tab-pane.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/breadcrumb-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/checkbox-group.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/collapse-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/dropdown-item.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/dropdown-menu.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/theme-default/src/menu-item-group.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | test/**/*.js linguist-language=Vue 2 | -------------------------------------------------------------------------------- /examples/versions.json: -------------------------------------------------------------------------------- 1 | {"1.0.9":"1.0","1.1.6":"1.1","1.2.7":"1.2"} -------------------------------------------------------------------------------- /packages/theme-default/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | npm-debug* 4 | -------------------------------------------------------------------------------- /examples/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/favicon.ico -------------------------------------------------------------------------------- /packages/message/index.js: -------------------------------------------------------------------------------- 1 | import Message from './src/main.js'; 2 | export default Message; 3 | -------------------------------------------------------------------------------- /packages/theme-default/src/base.css: -------------------------------------------------------------------------------- 1 | @import "./common/transition.css"; 2 | @import "./icon.css"; 3 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | src/utils/popper.js 2 | src/utils/date.js 3 | *.sh 4 | node_modules 5 | lib 6 | coverage 7 | -------------------------------------------------------------------------------- /packages/message-box/index.js: -------------------------------------------------------------------------------- 1 | import MessageBox from './src/main.js'; 2 | export default MessageBox; 3 | -------------------------------------------------------------------------------- /packages/notification/index.js: -------------------------------------------------------------------------------- 1 | import Notification from './src/main.js'; 2 | export default Notification; 3 | -------------------------------------------------------------------------------- /examples/assets/images/guide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/guide.png -------------------------------------------------------------------------------- /examples/assets/images/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/qrcode.png -------------------------------------------------------------------------------- /examples/assets/images/stars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/stars.png -------------------------------------------------------------------------------- /examples/i18n/route.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "lang": "zh-CN" 4 | }, 5 | { 6 | "lang": "en-US" 7 | } 8 | ] 9 | -------------------------------------------------------------------------------- /examples/assets/images/feedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/feedback.png -------------------------------------------------------------------------------- /examples/assets/images/navbar_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/navbar_0.png -------------------------------------------------------------------------------- /examples/assets/images/navbar_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/navbar_1.png -------------------------------------------------------------------------------- /examples/assets/images/navbar_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/navbar_2.png -------------------------------------------------------------------------------- /examples/assets/images/navbar_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/navbar_3.png -------------------------------------------------------------------------------- /examples/assets/images/resource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/resource.png -------------------------------------------------------------------------------- /examples/assets/images/component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/component.png -------------------------------------------------------------------------------- /examples/assets/images/consistency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/consistency.png -------------------------------------------------------------------------------- /examples/assets/images/efficiency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/efficiency.png -------------------------------------------------------------------------------- /examples/assets/images/hamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/hamburger.png -------------------------------------------------------------------------------- /examples/assets/images/element-demo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/element-demo.jpeg -------------------------------------------------------------------------------- /examples/assets/styles/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/styles/fonts/icomoon.eot -------------------------------------------------------------------------------- /examples/assets/styles/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/styles/fonts/icomoon.ttf -------------------------------------------------------------------------------- /examples/assets/images/controllability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/images/controllability.png -------------------------------------------------------------------------------- /examples/assets/styles/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/examples/assets/styles/fonts/icomoon.woff -------------------------------------------------------------------------------- /packages/theme-default/src/fonts/element-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/packages/theme-default/src/fonts/element-icons.ttf -------------------------------------------------------------------------------- /packages/theme-default/src/fonts/element-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/element/dev/packages/theme-default/src/fonts/element-icons.woff -------------------------------------------------------------------------------- /packages/popover/src/directive.js: -------------------------------------------------------------------------------- 1 | export default { 2 | bind(el, binding, vnode) { 3 | vnode.context.$refs[binding.arg].$refs.reference = el; 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /packages/card/index.js: -------------------------------------------------------------------------------- 1 | import Card from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | Card.install = function(Vue) { 5 | Vue.component(Card.name, Card); 6 | }; 7 | 8 | export default Card; 9 | -------------------------------------------------------------------------------- /packages/rate/index.js: -------------------------------------------------------------------------------- 1 | import Rate from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | Rate.install = function(Vue) { 5 | Vue.component(Rate.name, Rate); 6 | }; 7 | 8 | export default Rate; 9 | -------------------------------------------------------------------------------- /packages/tag/index.js: -------------------------------------------------------------------------------- 1 | import ElTag from './src/tag'; 2 | 3 | /* istanbul ignore next */ 4 | ElTag.install = function(Vue) { 5 | Vue.component(ElTag.name, ElTag); 6 | }; 7 | 8 | export default ElTag; 9 | -------------------------------------------------------------------------------- /packages/tree/index.js: -------------------------------------------------------------------------------- 1 | import Tree from './src/tree.vue'; 2 | 3 | /* istanbul ignore next */ 4 | Tree.install = function(Vue) { 5 | Vue.component(Tree.name, Tree); 6 | }; 7 | 8 | export default Tree; 9 | -------------------------------------------------------------------------------- /src/mixins/locale.js: -------------------------------------------------------------------------------- 1 | import { t } from 'element-ui/src/locale'; 2 | 3 | export default { 4 | methods: { 5 | t(...args) { 6 | return t.apply(this, args); 7 | } 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /packages/alert/index.js: -------------------------------------------------------------------------------- 1 | import Alert from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | Alert.install = function(Vue) { 5 | Vue.component(Alert.name, Alert); 6 | }; 7 | 8 | export default Alert; 9 | -------------------------------------------------------------------------------- /packages/badge/index.js: -------------------------------------------------------------------------------- 1 | import Badge from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | Badge.install = function(Vue) { 5 | Vue.component(Badge.name, Badge); 6 | }; 7 | 8 | export default Badge; 9 | -------------------------------------------------------------------------------- /packages/form/index.js: -------------------------------------------------------------------------------- 1 | import ElForm from './src/form'; 2 | 3 | /* istanbul ignore next */ 4 | ElForm.install = function(Vue) { 5 | Vue.component(ElForm.name, ElForm); 6 | }; 7 | 8 | export default ElForm; 9 | -------------------------------------------------------------------------------- /packages/menu/index.js: -------------------------------------------------------------------------------- 1 | import ElMenu from './src/menu'; 2 | 3 | /* istanbul ignore next */ 4 | ElMenu.install = function(Vue) { 5 | Vue.component(ElMenu.name, ElMenu); 6 | }; 7 | 8 | export default ElMenu; 9 | -------------------------------------------------------------------------------- /packages/radio/index.js: -------------------------------------------------------------------------------- 1 | import Radio from './src/radio'; 2 | 3 | /* istanbul ignore next */ 4 | Radio.install = function(Vue) { 5 | Vue.component('el-radio', Radio); 6 | }; 7 | 8 | export default Radio; 9 | -------------------------------------------------------------------------------- /packages/row/index.js: -------------------------------------------------------------------------------- 1 | import Row from './src/row'; 2 | 3 | /* istanbul ignore next */ 4 | Row.install = function(Vue) { 5 | Vue.component(Row.name, Row); 6 | }; 7 | 8 | export default Row; 9 | 10 | -------------------------------------------------------------------------------- /packages/step/index.js: -------------------------------------------------------------------------------- 1 | import Step from '../steps/src/step'; 2 | 3 | /* istanbul ignore next */ 4 | Step.install = function(Vue) { 5 | Vue.component(Step.name, Step); 6 | }; 7 | 8 | export default Step; 9 | -------------------------------------------------------------------------------- /packages/steps/index.js: -------------------------------------------------------------------------------- 1 | import Steps from './src/steps'; 2 | 3 | /* istanbul ignore next */ 4 | Steps.install = function(Vue) { 5 | Vue.component(Steps.name, Steps); 6 | }; 7 | 8 | export default Steps; 9 | -------------------------------------------------------------------------------- /packages/tabs/index.js: -------------------------------------------------------------------------------- 1 | import ElTabs from './src/tabs'; 2 | 3 | /* istanbul ignore next */ 4 | ElTabs.install = function(Vue) { 5 | Vue.component(ElTabs.name, ElTabs); 6 | }; 7 | 8 | export default ElTabs; 9 | -------------------------------------------------------------------------------- /packages/upload/index.js: -------------------------------------------------------------------------------- 1 | import Upload from './src'; 2 | 3 | /* istanbul ignore next */ 4 | Upload.install = function(Vue) { 5 | Vue.component(Upload.name, Upload); 6 | }; 7 | 8 | export default Upload; 9 | -------------------------------------------------------------------------------- /packages/icon/index.js: -------------------------------------------------------------------------------- 1 | import ElIcon from './src/icon.vue'; 2 | 3 | /* istanbul ignore next */ 4 | ElIcon.install = function(Vue) { 5 | Vue.component(ElIcon.name, ElIcon); 6 | }; 7 | 8 | export default ElIcon; 9 | -------------------------------------------------------------------------------- /packages/select/index.js: -------------------------------------------------------------------------------- 1 | import Select from './src/select'; 2 | 3 | /* istanbul ignore next */ 4 | Select.install = function(Vue) { 5 | Vue.component(Select.name, Select); 6 | }; 7 | 8 | export default Select; 9 | -------------------------------------------------------------------------------- /packages/slider/index.js: -------------------------------------------------------------------------------- 1 | import Slider from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | Slider.install = function(Vue) { 5 | Vue.component(Slider.name, Slider); 6 | }; 7 | 8 | export default Slider; 9 | -------------------------------------------------------------------------------- /packages/col/index.js: -------------------------------------------------------------------------------- 1 | import ElCol from './src/col'; 2 | 3 | /* istanbul ignore next */ 4 | ElCol.install = function(Vue) { 5 | Vue.component(ElCol.name, ElCol); 6 | }; 7 | 8 | export default ElCol; 9 | 10 | -------------------------------------------------------------------------------- /packages/input/index.js: -------------------------------------------------------------------------------- 1 | import ElInput from './src/input'; 2 | 3 | /* istanbul ignore next */ 4 | ElInput.install = function(Vue) { 5 | Vue.component(ElInput.name, ElInput); 6 | }; 7 | 8 | export default ElInput; 9 | -------------------------------------------------------------------------------- /packages/loading/cooking.conf.js: -------------------------------------------------------------------------------- 1 | var cooking = require('cooking'); 2 | var gen = require('../../build/gen-single-config'); 3 | 4 | cooking.set(gen(__dirname, 'ElLoading')); 5 | 6 | module.exports = cooking.resolve(); 7 | -------------------------------------------------------------------------------- /packages/table/index.js: -------------------------------------------------------------------------------- 1 | import ElTable from './src/table'; 2 | 3 | /* istanbul ignore next */ 4 | ElTable.install = function(Vue) { 5 | Vue.component(ElTable.name, ElTable); 6 | }; 7 | 8 | export default ElTable; 9 | -------------------------------------------------------------------------------- /packages/tooltip/index.js: -------------------------------------------------------------------------------- 1 | import Tooltip from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | Tooltip.install = function(Vue) { 5 | Vue.component(Tooltip.name, Tooltip); 6 | }; 7 | 8 | export default Tooltip; 9 | -------------------------------------------------------------------------------- /packages/upload/cooking.conf.js: -------------------------------------------------------------------------------- 1 | var cooking = require('cooking'); 2 | var gen = require('../../build/gen-single-config'); 3 | 4 | cooking.set(gen(__dirname, 'ElUpload')); 5 | 6 | module.exports = cooking.resolve(); 7 | -------------------------------------------------------------------------------- /packages/button/index.js: -------------------------------------------------------------------------------- 1 | import ElButton from './src/button'; 2 | 3 | /* istanbul ignore next */ 4 | ElButton.install = function(Vue) { 5 | Vue.component(ElButton.name, ElButton); 6 | }; 7 | 8 | export default ElButton; 9 | -------------------------------------------------------------------------------- /packages/carousel/index.js: -------------------------------------------------------------------------------- 1 | import Carousel from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | Carousel.install = function(Vue) { 5 | Vue.component(Carousel.name, Carousel); 6 | }; 7 | 8 | export default Carousel; 9 | -------------------------------------------------------------------------------- /packages/cascader/index.js: -------------------------------------------------------------------------------- 1 | import Cascader from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | Cascader.install = function(Vue) { 5 | Vue.component(Cascader.name, Cascader); 6 | }; 7 | 8 | export default Cascader; 9 | -------------------------------------------------------------------------------- /packages/pagination/cooking.conf.js: -------------------------------------------------------------------------------- 1 | var cooking = require('cooking'); 2 | var gen = require('../../build/gen-single-config'); 3 | 4 | cooking.set(gen(__dirname, 'ElPagination')); 5 | 6 | module.exports = cooking.resolve(); 7 | -------------------------------------------------------------------------------- /packages/spinner/index.js: -------------------------------------------------------------------------------- 1 | import Spinner from './src/spinner'; 2 | 3 | /* istanbul ignore next */ 4 | Spinner.install = function(Vue) { 5 | Vue.component(Spinner.name, Spinner); 6 | }; 7 | 8 | export default Spinner; 9 | -------------------------------------------------------------------------------- /packages/color-picker/cooking.conf.js: -------------------------------------------------------------------------------- 1 | var cooking = require('cooking'); 2 | var gen = require('../../build/gen-single-config'); 3 | 4 | cooking.set(gen(__dirname, 'ElColorPicker')); 5 | 6 | module.exports = cooking.resolve(); 7 | -------------------------------------------------------------------------------- /packages/dialog/index.js: -------------------------------------------------------------------------------- 1 | import ElDialog from './src/component'; 2 | 3 | /* istanbul ignore next */ 4 | ElDialog.install = function(Vue) { 5 | Vue.component(ElDialog.name, ElDialog); 6 | }; 7 | 8 | export default ElDialog; 9 | -------------------------------------------------------------------------------- /packages/scrollbar/index.js: -------------------------------------------------------------------------------- 1 | import Scrollbar from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | Scrollbar.install = function(Vue) { 5 | Vue.component(Scrollbar.name, Scrollbar); 6 | }; 7 | 8 | export default Scrollbar; 9 | -------------------------------------------------------------------------------- /packages/table/cooking.conf.js: -------------------------------------------------------------------------------- 1 | var cooking = require('cooking'); 2 | var gen = require('../../build/gen-single-config'); 3 | 4 | cooking.set(gen(__dirname, 'ElTable', '_index.js')); 5 | 6 | module.exports = cooking.resolve(); 7 | -------------------------------------------------------------------------------- /packages/theme-default/src/time-picker.css: -------------------------------------------------------------------------------- 1 | @import "./date-picker/picker.css"; 2 | @import "./date-picker/time-spinner.css"; 3 | @import "./date-picker/time-picker.css"; 4 | @import "./input.css"; 5 | @import "./scrollbar.css"; 6 | -------------------------------------------------------------------------------- /packages/carousel/cooking.conf.js: -------------------------------------------------------------------------------- 1 | var cooking = require('cooking'); 2 | var gen = require('../../build/gen-single-config'); 3 | 4 | cooking.set(gen(__dirname, 'ElCarousel', '_index.js')); 5 | 6 | module.exports = cooking.resolve(); 7 | -------------------------------------------------------------------------------- /packages/option/index.js: -------------------------------------------------------------------------------- 1 | import ElOption from '../select/src/option'; 2 | 3 | /* istanbul ignore next */ 4 | ElOption.install = function(Vue) { 5 | Vue.component(ElOption.name, ElOption); 6 | }; 7 | 8 | export default ElOption; 9 | -------------------------------------------------------------------------------- /packages/switch/index.js: -------------------------------------------------------------------------------- 1 | import Switch from './src/component'; 2 | 3 | /* istanbul ignore next */ 4 | Switch.install = function(Vue) { 5 | Vue.component(Switch.name, Switch); 6 | }; 7 | 8 | export default Switch; 9 | 10 | -------------------------------------------------------------------------------- /packages/tab-pane/index.js: -------------------------------------------------------------------------------- 1 | import TabPane from '../tabs/src/tab-pane.vue'; 2 | 3 | /* istanbul ignore next */ 4 | TabPane.install = function(Vue) { 5 | Vue.component(TabPane.name, TabPane); 6 | }; 7 | 8 | export default TabPane; 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/checkbox/index.js: -------------------------------------------------------------------------------- 1 | import ElCheckbox from './src/checkbox'; 2 | 3 | /* istanbul ignore next */ 4 | ElCheckbox.install = function(Vue) { 5 | Vue.component(ElCheckbox.name, ElCheckbox); 6 | }; 7 | 8 | export default ElCheckbox; 9 | -------------------------------------------------------------------------------- /packages/date-picker/cooking.conf.js: -------------------------------------------------------------------------------- 1 | var cooking = require('cooking'); 2 | var gen = require('../../build/gen-single-config'); 3 | 4 | cooking.set(gen(__dirname, 'ElDatePicker', '_index.js')); 5 | 6 | module.exports = cooking.resolve(); 7 | -------------------------------------------------------------------------------- /packages/dropdown/index.js: -------------------------------------------------------------------------------- 1 | import ElDropdown from './src/dropdown'; 2 | 3 | /* istanbul ignore next */ 4 | ElDropdown.install = function(Vue) { 5 | Vue.component(ElDropdown.name, ElDropdown); 6 | }; 7 | 8 | export default ElDropdown; 9 | -------------------------------------------------------------------------------- /packages/progress/index.js: -------------------------------------------------------------------------------- 1 | import ElProgress from './src/progress'; 2 | 3 | /* istanbul ignore next */ 4 | ElProgress.install = function(Vue) { 5 | Vue.component(ElProgress.name, ElProgress); 6 | }; 7 | 8 | export default ElProgress; 9 | -------------------------------------------------------------------------------- /packages/submenu/index.js: -------------------------------------------------------------------------------- 1 | import ElSubmenu from '../menu/src/submenu'; 2 | 3 | /* istanbul ignore next */ 4 | ElSubmenu.install = function(Vue) { 5 | Vue.component(ElSubmenu.name, ElSubmenu); 6 | }; 7 | 8 | export default ElSubmenu; 9 | -------------------------------------------------------------------------------- /packages/color-picker/index.js: -------------------------------------------------------------------------------- 1 | import ColorPicker from './src/main'; 2 | 3 | /* istanbul ignore next */ 4 | ColorPicker.install = function(Vue) { 5 | Vue.component(ColorPicker.name, ColorPicker); 6 | }; 7 | 8 | export default ColorPicker; 9 | -------------------------------------------------------------------------------- /packages/pagination/index.js: -------------------------------------------------------------------------------- 1 | import Pagination from './src/pagination'; 2 | 3 | /* istanbul ignore next */ 4 | Pagination.install = function(Vue) { 5 | Vue.component(Pagination.name, Pagination); 6 | }; 7 | 8 | export default Pagination; 9 | -------------------------------------------------------------------------------- /examples/docs/zh-CN/home.md: -------------------------------------------------------------------------------- 1 | # 组件说明文档 2 | 3 | -------------------------------------------------------------------------------- /packages/form-item/index.js: -------------------------------------------------------------------------------- 1 | import ElFormItem from '../form/src/form-item'; 2 | 3 | /* istanbul ignore next */ 4 | ElFormItem.install = function(Vue) { 5 | Vue.component(ElFormItem.name, ElFormItem); 6 | }; 7 | 8 | export default ElFormItem; 9 | -------------------------------------------------------------------------------- /packages/menu-item/index.js: -------------------------------------------------------------------------------- 1 | import ElMenuItem from '../menu/src/menu-item'; 2 | 3 | /* istanbul ignore next */ 4 | ElMenuItem.install = function(Vue) { 5 | Vue.component(ElMenuItem.name, ElMenuItem); 6 | }; 7 | 8 | export default ElMenuItem; 9 | -------------------------------------------------------------------------------- /packages/breadcrumb/index.js: -------------------------------------------------------------------------------- 1 | import ElBreadcrumb from './src/breadcrumb'; 2 | 3 | /* istanbul ignore next */ 4 | ElBreadcrumb.install = function(Vue) { 5 | Vue.component(ElBreadcrumb.name, ElBreadcrumb); 6 | }; 7 | 8 | export default ElBreadcrumb; 9 | -------------------------------------------------------------------------------- /packages/collapse/index.js: -------------------------------------------------------------------------------- 1 | import ElCollapse from './src/collapse'; 2 | 3 | /* istanbul ignore next */ 4 | ElCollapse.install = function(Vue) { 5 | Vue.component(ElCollapse.name, ElCollapse); 6 | }; 7 | 8 | export default ElCollapse; 9 | 10 | -------------------------------------------------------------------------------- /packages/icon/src/icon.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 14 | -------------------------------------------------------------------------------- /packages/radio-group/index.js: -------------------------------------------------------------------------------- 1 | import RadioGroup from '../radio/src/radio-group.vue'; 2 | 3 | /* istanbul ignore next */ 4 | RadioGroup.install = function(Vue) { 5 | Vue.component(RadioGroup.name, RadioGroup); 6 | }; 7 | 8 | export default RadioGroup; 9 | -------------------------------------------------------------------------------- /examples/docs/en-US/home.md: -------------------------------------------------------------------------------- 1 | # Components Document 2 | 3 | -------------------------------------------------------------------------------- /packages/date-picker/index.js: -------------------------------------------------------------------------------- 1 | import DatePicker from './src/picker/date-picker'; 2 | 3 | /* istanbul ignore next */ 4 | DatePicker.install = function install(Vue) { 5 | Vue.component(DatePicker.name, DatePicker); 6 | }; 7 | 8 | export default DatePicker; 9 | -------------------------------------------------------------------------------- /packages/input-number/index.js: -------------------------------------------------------------------------------- 1 | import ElInputNumber from './src/input-number'; 2 | 3 | /* istanbul ignore next */ 4 | ElInputNumber.install = function(Vue) { 5 | Vue.component(ElInputNumber.name, ElInputNumber); 6 | }; 7 | 8 | export default ElInputNumber; 9 | -------------------------------------------------------------------------------- /packages/radio-button/index.js: -------------------------------------------------------------------------------- 1 | import RadioButton from '../radio/src/radio-button.vue'; 2 | 3 | /* istanbul ignore next */ 4 | RadioButton.install = function(Vue) { 5 | Vue.component(RadioButton.name, RadioButton); 6 | }; 7 | 8 | export default RadioButton; 9 | -------------------------------------------------------------------------------- /packages/time-picker/index.js: -------------------------------------------------------------------------------- 1 | import TimePicker from '../date-picker/src/picker/time-picker'; 2 | 3 | /* istanbul ignore next */ 4 | TimePicker.install = function(Vue) { 5 | Vue.component(TimePicker.name, TimePicker); 6 | }; 7 | 8 | export default TimePicker; 9 | -------------------------------------------------------------------------------- /packages/time-select/index.js: -------------------------------------------------------------------------------- 1 | import TimeSelect from '../date-picker/src/picker/time-select'; 2 | 3 | /* istanbul ignore next */ 4 | TimeSelect.install = function(Vue) { 5 | Vue.component(TimeSelect.name, TimeSelect); 6 | }; 7 | 8 | export default TimeSelect; 9 | -------------------------------------------------------------------------------- /packages/autocomplete/index.js: -------------------------------------------------------------------------------- 1 | import ElAutocomplete from './src/autocomplete'; 2 | 3 | /* istanbul ignore next */ 4 | ElAutocomplete.install = function(Vue) { 5 | Vue.component(ElAutocomplete.name, ElAutocomplete); 6 | }; 7 | 8 | export default ElAutocomplete; 9 | -------------------------------------------------------------------------------- /packages/button-group/index.js: -------------------------------------------------------------------------------- 1 | import ElButtonGroup from '../button/src/button-group'; 2 | 3 | /* istanbul ignore next */ 4 | ElButtonGroup.install = function(Vue) { 5 | Vue.component(ElButtonGroup.name, ElButtonGroup); 6 | }; 7 | 8 | export default ElButtonGroup; 9 | -------------------------------------------------------------------------------- /packages/carousel-item/index.js: -------------------------------------------------------------------------------- 1 | import ElCarouselItem from '../carousel/src/item'; 2 | 3 | /* istanbul ignore next */ 4 | ElCarouselItem.install = function(Vue) { 5 | Vue.component(ElCarouselItem.name, ElCarouselItem); 6 | }; 7 | 8 | export default ElCarouselItem; 9 | -------------------------------------------------------------------------------- /packages/option-group/index.js: -------------------------------------------------------------------------------- 1 | import ElOptionGroup from '../select/src/option-group'; 2 | 3 | /* istanbul ignore next */ 4 | ElOptionGroup.install = function(Vue) { 5 | Vue.component(ElOptionGroup.name, ElOptionGroup); 6 | }; 7 | 8 | export default ElOptionGroup; 9 | -------------------------------------------------------------------------------- /packages/table-column/index.js: -------------------------------------------------------------------------------- 1 | import ElTableColumn from '../table/src/table-column'; 2 | 3 | /* istanbul ignore next */ 4 | ElTableColumn.install = function(Vue) { 5 | Vue.component(ElTableColumn.name, ElTableColumn); 6 | }; 7 | 8 | export default ElTableColumn; 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | npm-debug.log 4 | lerna-debug.log 5 | npm-debug.log.* 6 | lerna-debug.log.* 7 | lib 8 | .idea 9 | examples/element-ui 10 | examples/pages/en-US 11 | examples/pages/zh-CN 12 | fe.element/element-ui 13 | .npmrc 14 | coverage 15 | -------------------------------------------------------------------------------- /packages/dropdown-item/index.js: -------------------------------------------------------------------------------- 1 | import ElDropdownItem from '../dropdown/src/dropdown-item'; 2 | 3 | /* istanbul ignore next */ 4 | ElDropdownItem.install = function(Vue) { 5 | Vue.component(ElDropdownItem.name, ElDropdownItem); 6 | }; 7 | 8 | export default ElDropdownItem; 9 | -------------------------------------------------------------------------------- /packages/dropdown-menu/index.js: -------------------------------------------------------------------------------- 1 | import ElDropdownMenu from '../dropdown/src/dropdown-menu'; 2 | 3 | /* istanbul ignore next */ 4 | ElDropdownMenu.install = function(Vue) { 5 | Vue.component(ElDropdownMenu.name, ElDropdownMenu); 6 | }; 7 | 8 | export default ElDropdownMenu; 9 | -------------------------------------------------------------------------------- /packages/collapse-item/index.js: -------------------------------------------------------------------------------- 1 | import ElCollapseItem from '../collapse/src/collapse-item.vue'; 2 | 3 | /* istanbul ignore next */ 4 | ElCollapseItem.install = function(Vue) { 5 | Vue.component(ElCollapseItem.name, ElCollapseItem); 6 | }; 7 | 8 | export default ElCollapseItem; 9 | -------------------------------------------------------------------------------- /packages/loading/index.js: -------------------------------------------------------------------------------- 1 | import directive from './src/directive'; 2 | import service from './src/index'; 3 | 4 | export default { 5 | install(Vue) { 6 | Vue.use(directive); 7 | Vue.prototype.$loading = service; 8 | }, 9 | directive, 10 | service 11 | }; 12 | -------------------------------------------------------------------------------- /packages/menu-item-group/index.js: -------------------------------------------------------------------------------- 1 | import ElMenuItemGroup from '../menu/src/menu-item-group'; 2 | 3 | /* istanbul ignore next */ 4 | ElMenuItemGroup.install = function(Vue) { 5 | Vue.component(ElMenuItemGroup.name, ElMenuItemGroup); 6 | }; 7 | 8 | export default ElMenuItemGroup; 9 | -------------------------------------------------------------------------------- /packages/checkbox-group/index.js: -------------------------------------------------------------------------------- 1 | import ElCheckboxGroup from '../checkbox/src/checkbox-group.vue'; 2 | 3 | /* istanbul ignore next */ 4 | ElCheckboxGroup.install = function(Vue) { 5 | Vue.component(ElCheckboxGroup.name, ElCheckboxGroup); 6 | }; 7 | 8 | export default ElCheckboxGroup; 9 | -------------------------------------------------------------------------------- /packages/breadcrumb-item/index.js: -------------------------------------------------------------------------------- 1 | import ElBreadcrumbItem from '../breadcrumb/src/breadcrumb-item'; 2 | 3 | /* istanbul ignore next */ 4 | ElBreadcrumbItem.install = function(Vue) { 5 | Vue.component(ElBreadcrumbItem.name, ElBreadcrumbItem); 6 | }; 7 | 8 | export default ElBreadcrumbItem; 9 | -------------------------------------------------------------------------------- /examples/play.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Element from 'main/index.js'; 3 | import App from './play/index.vue'; 4 | import 'packages/theme-default/src/index.css'; 5 | 6 | Vue.use(Element); 7 | 8 | new Vue({ // eslint-disable-line 9 | render: h => h(App) 10 | }).$mount('#app'); 11 | -------------------------------------------------------------------------------- /packages/date-picker/src/picker/time-select.js: -------------------------------------------------------------------------------- 1 | import Picker from '../picker'; 2 | import Panel from '../panel/time-select'; 3 | 4 | export default { 5 | mixins: [Picker], 6 | 7 | name: 'ElTimeSelect', 8 | 9 | beforeCreate() { 10 | this.type = 'time-select'; 11 | this.panel = Panel; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /src/utils/vdom.js: -------------------------------------------------------------------------------- 1 | import { hasOwn } from 'element-ui/src/utils/util'; 2 | 3 | export function isVNode(node) { 4 | return typeof node === 'object' && hasOwn(node, 'componentOptions'); 5 | }; 6 | 7 | export function getFirstComponentChild(children) { 8 | return children && children.filter(c => c && c.tag)[0]; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/table/_index.js: -------------------------------------------------------------------------------- 1 | import ElTableColumn from './src/table-column'; 2 | import ElTable from './src/table'; 3 | 4 | /* istanbul ignore next */ 5 | export default function(Vue) { 6 | Vue.component(ElTable.name, ElTable); 7 | Vue.component(ElTableColumn.name, ElTableColumn); 8 | }; 9 | 10 | export { ElTable, ElTableColumn }; 11 | -------------------------------------------------------------------------------- /packages/theme-default/src/radio-group.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | @b radio-group { 6 | display: inline-block; 7 | font-size: 0; 8 | line-height: 1; 9 | 10 | & .el-radio { 11 | font-size: var(--radio-font-size); 12 | } 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "expect": true, 7 | "sinon": true 8 | }, 9 | "plugins": ['vue'], 10 | "extends": 'elemefe', 11 | "parserOptions": { 12 | "ecmaFeatures": { 13 | "experimentalObjectRestSpread": true, 14 | "jsx": true 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.0.0-beta.32", 3 | "version": "independent", 4 | "publishConfig": { 5 | "ignore": [ 6 | "node_modules", 7 | "log.*" 8 | ] 9 | }, 10 | "packages": ["packages/carousel", "packages/table", "packages/upload", "packages/date-picker", "packages/loading", "packages/pagination"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/carousel/_index.js: -------------------------------------------------------------------------------- 1 | import ElCarousel from './src/main'; 2 | import ElCarouselItem from './src/item'; 3 | 4 | /* istanbul ignore next */ 5 | export default function(Vue) { 6 | Vue.component(ElCarousel.name, ElCarousel); 7 | Vue.component(ElCarouselItem.name, ElCarouselItem); 8 | }; 9 | 10 | export { ElCarousel, ElCarouselItem }; 11 | -------------------------------------------------------------------------------- /packages/breadcrumb/src/breadcrumb.vue: -------------------------------------------------------------------------------- 1 | 6 | 18 | -------------------------------------------------------------------------------- /packages/button/src/button-group.vue: -------------------------------------------------------------------------------- 1 | 6 | 17 | -------------------------------------------------------------------------------- /examples/play/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 15 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["es2015", { "loose": true }]], 3 | "plugins": ["transform-vue-jsx"], 4 | "env": { 5 | "utils": { 6 | "plugins": [ 7 | ["module-resolver", { 8 | "root": ["element-ui"], 9 | "alias": { 10 | "element-ui/src": "element-ui/lib" 11 | } 12 | }] 13 | ] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/theme-default/salad.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "browsers": ["ie > 8", "last 2 versions"], 3 | "features": { 4 | "bem": { 5 | "shortcuts": { 6 | "component": "b", 7 | "modifier": "m", 8 | "descendent": "e" 9 | }, 10 | "separators": { 11 | "descendent": "__", 12 | "modifier": "--" 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/i18n/title.json: -------------------------------------------------------------------------------- 1 | { 2 | "zh-CN": { 3 | "home": "Element - 网站快速成型工具", 4 | "guide": "指南 | Element", 5 | "component": "组件 | Element", 6 | "resource": "资源 | Element" 7 | }, 8 | "en-US": { 9 | "home": "Element - A Desktop UI Toolkit for Web", 10 | "guide": "Guide | Element", 11 | "component": "Component | Element", 12 | "resource": "Resource | Element" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/theme-default/src/steps.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | @b steps { 6 | font-size: 0; 7 | 8 | > :last-child .el-step__line { 9 | display: none; 10 | } 11 | 12 | @when horizontal { 13 | white-space: nowrap; 14 | 15 | @when center { 16 | text-align: center; 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/popover/index.js: -------------------------------------------------------------------------------- 1 | import Popover from './src/main'; 2 | import directive from './src/directive'; 3 | import Vue from 'vue'; 4 | 5 | Vue.directive('popover', directive); 6 | 7 | /* istanbul ignore next */ 8 | Popover.install = function(Vue) { 9 | Vue.directive('popover', directive); 10 | Vue.component(Popover.name, Popover); 11 | }; 12 | Popover.directive = directive; 13 | 14 | export default Popover; 15 | -------------------------------------------------------------------------------- /examples/icon.json: -------------------------------------------------------------------------------- 1 | ["arrow-down","arrow-left","arrow-right","arrow-up","caret-bottom","caret-left","caret-right","caret-top","check","circle-check","circle-close","circle-cross","close","upload","d-arrow-left","d-arrow-right","d-caret","date","delete","document","edit","information","loading","menu","message","minus","more","picture","plus","search","setting","share","star-off","star-on","time","warning","delete2","upload2","view"] -------------------------------------------------------------------------------- /src/utils/merge.js: -------------------------------------------------------------------------------- 1 | export default function(target) { 2 | for (let i = 1, j = arguments.length; i < j; i++) { 3 | let source = arguments[i] || {}; 4 | for (let prop in source) { 5 | if (source.hasOwnProperty(prop)) { 6 | let value = source[prop]; 7 | if (value !== undefined) { 8 | target[prop] = value; 9 | } 10 | } 11 | } 12 | } 13 | 14 | return target; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/loading/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-loading", 3 | "version": "1.0.0", 4 | "description": "A loading component for Vue.js.", 5 | "keywords": [ 6 | "element", 7 | "vue", 8 | "component" 9 | ], 10 | "main": "./lib/index.js", 11 | "repository": "https://github.com/ElemeFE/element/tree/master/packages/loading", 12 | "author": "elemefe", 13 | "license": "MIT", 14 | "dependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /packages/cascader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-cascader", 3 | "version": "0.0.0", 4 | "description": "A cascader component for Vue.js.", 5 | "keywords": [ 6 | "element", 7 | "vue", 8 | "component" 9 | ], 10 | "main": "./lib/index.js", 11 | "repository": "https://github.com/ElemeFE/element/tree/master/packages/cascader", 12 | "author": "elemefe", 13 | "license": "MIT", 14 | "dependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: stable 4 | before_install: 5 | - export TRAVIS_COMMIT_MSG="[deploy] $(git log --format='%h - %B' --no-merges -n 1)" 6 | - export TRAVIS_COMMIT_USER="$(git log --no-merges -n 1 --format=%an)" 7 | - export TRAVIS_COMMIT_EMAIL="$(git log --no-merges -n 1 --format=%ae)" 8 | after_success: 9 | - sh build/deploy-ci.sh 10 | - cat ./test/unit/coverage/lcov.info | ./node_modules/.bin/coveralls 11 | -------------------------------------------------------------------------------- /packages/color-picker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-color-picker", 3 | "version": "0.0.0", 4 | "description": "A color-picker component for Vue.js.", 5 | "keywords": [ 6 | "element", 7 | "vue", 8 | "component" 9 | ], 10 | "main": "./lib/index.js", 11 | "repository": "https://github.com/ElemeFE/element/tree/master/packages/color-picker", 12 | "author": "elemefe", 13 | "license": "MIT", 14 | "dependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /packages/date-picker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-datepicker", 3 | "version": "1.0.0", 4 | "description": "A datepicker component for Vue.", 5 | "keywords": [ 6 | "element", 7 | "vue", 8 | "component" 9 | ], 10 | "main": "./lib/index.js", 11 | "repository": "https://github.com/ElemeFE/element/tree/master/packages/date-picker", 12 | "author": "long.zhang@ele.me", 13 | "license": "MIT", 14 | "dependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /packages/card/src/main.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /packages/upload/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-upload", 3 | "version": "1.0.0", 4 | "description": "A upload component for Vue.js.", 5 | "keywords": [ 6 | "element", 7 | "vue", 8 | "component" 9 | ], 10 | "main": "./lib/index.js", 11 | "repository": "https://github.com/ElemeFE/element/tree/master/packages/upload", 12 | "author": "elemefe", 13 | "license": "MIT", 14 | "dependencies": {}, 15 | "devDependencies": {} 16 | } 17 | -------------------------------------------------------------------------------- /packages/tree/src/model/util.js: -------------------------------------------------------------------------------- 1 | export const NODE_KEY = '$treeNodeId'; 2 | 3 | export const markNodeData = function(node, data) { 4 | if (data[NODE_KEY]) return; 5 | Object.defineProperty(data, NODE_KEY, { 6 | value: node.id, 7 | enumerable: false, 8 | configurable: false, 9 | writable: false 10 | }); 11 | }; 12 | 13 | export const getNodeKey = function(key, data) { 14 | if (!key) return data[NODE_KEY]; 15 | return data[key]; 16 | }; 17 | -------------------------------------------------------------------------------- /packages/pagination/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-pagination", 3 | "version": "1.0.0", 4 | "description": "A pagination component for Vue.js.", 5 | "keywords": [ 6 | "element", 7 | "vue", 8 | "component" 9 | ], 10 | "main": "./lib/index.js", 11 | "repository": "https://github.com/ElemeFE/element/tree/master/packages/pagination", 12 | "author": "qingwei-li", 13 | "license": "MIT", 14 | "dependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /packages/table/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-table", 3 | "version": "1.0.0", 4 | "description": "A table component for Vue.", 5 | "keywords": [ 6 | "element", 7 | "vue", 8 | "component" 9 | ], 10 | "main": "./lib/index.js", 11 | "repository": "https://github.com/ElemeFE/element/tree/master/packages/table", 12 | "author": "elemefe", 13 | "license": "MIT", 14 | "dependencies": { 15 | "throttle-debounce": "^1.0.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please makes sure these boxes are checked before submitting your PR, thank you! 2 | 3 | * [ ] Make sure you follow Element's contributing guide ([中文](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.zh-CN.md) | [English](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.en-US.md)). 4 | * [ ] Make sure you are merging your commits to `dev` branch. 5 | * [ ] Add some descriptions and refer relative issues for you PR. 6 | -------------------------------------------------------------------------------- /packages/carousel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-carousel", 3 | "version": "1.0.0", 4 | "description": "A carousel component for Vue.js.", 5 | "main": "lib/index.js", 6 | "keywords": [ 7 | "element", 8 | "vue", 9 | "component" 10 | ], 11 | "repository": "https://github.com/ElemeFE/element/tree/master/packages/carousel", 12 | "author": "elemefe", 13 | "license": "MIT", 14 | "dependencies": { 15 | "throttle-debounce": "^1.0.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/date-picker/_index.js: -------------------------------------------------------------------------------- 1 | import DatePicker from './src/picker/date-picker'; 2 | import TimePicker from './src/picker/time-picker'; 3 | import TimeSelect from './src/picker/time-select'; 4 | 5 | /* istanbul ignore next */ 6 | export default function install(Vue) { 7 | Vue.component(DatePicker.name, DatePicker); 8 | Vue.component(TimePicker.name, TimePicker); 9 | Vue.component(TimeSelect.name, TimeSelect); 10 | }; 11 | 12 | export { DatePicker, TimePicker, TimeSelect }; 13 | -------------------------------------------------------------------------------- /packages/theme-default/src/date-picker.css: -------------------------------------------------------------------------------- 1 | @import "./date-picker/date-table.css"; 2 | @import "./date-picker/month-table.css"; 3 | @import "./date-picker/year-table.css"; 4 | @import "./date-picker/time-spinner.css"; 5 | @import "./date-picker/picker.css"; 6 | @import "./date-picker/date-picker.css"; 7 | @import "./date-picker/date-range-picker.css"; 8 | @import "./date-picker/time-range-picker.css"; 9 | @import "./date-picker/time-picker.css"; 10 | @import "./input.css"; 11 | @import "./scrollbar.css"; -------------------------------------------------------------------------------- /src/utils/util.js: -------------------------------------------------------------------------------- 1 | const hasOwnProperty = Object.prototype.hasOwnProperty; 2 | export function hasOwn(obj, key) { 3 | return hasOwnProperty.call(obj, key); 4 | }; 5 | 6 | function extend(to, _from) { 7 | for (let key in _from) { 8 | to[key] = _from[key]; 9 | } 10 | return to; 11 | }; 12 | 13 | export function toObject(arr) { 14 | var res = {}; 15 | for (let i = 0; i < arr.length; i++) { 16 | if (arr[i]) { 17 | extend(res, arr[i]); 18 | } 19 | } 20 | return res; 21 | }; 22 | -------------------------------------------------------------------------------- /packages/cascader/cooking.conf.js: -------------------------------------------------------------------------------- 1 | var cooking = require('cooking'); 2 | var path = require('path'); 3 | var config = require('../../build/config'); 4 | 5 | cooking.set({ 6 | entry: { 7 | index: path.join(__dirname, 'index.js') 8 | }, 9 | dist: path.join(__dirname, 'lib'), 10 | template: false, 11 | format: 'umd', 12 | moduleName: 'ElCascader', 13 | extends: ['vue2'], 14 | alias: config.alias, 15 | externals: { vue: config.vue } 16 | }); 17 | 18 | module.exports = cooking.resolve(); 19 | -------------------------------------------------------------------------------- /packages/date-picker/src/picker/time-picker.js: -------------------------------------------------------------------------------- 1 | import Picker from '../picker'; 2 | import TimePanel from '../panel/time'; 3 | import TimeRangePanel from '../panel/time-range'; 4 | 5 | export default { 6 | mixins: [Picker], 7 | 8 | name: 'ElTimePicker', 9 | 10 | props: { 11 | isRange: Boolean 12 | }, 13 | 14 | data() { 15 | return { 16 | type: '' 17 | }; 18 | }, 19 | 20 | created() { 21 | this.type = this.isRange ? 'timerange' : 'time'; 22 | this.panel = this.isRange ? TimeRangePanel : TimePanel; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /packages/theme-default/src/common/popup.css: -------------------------------------------------------------------------------- 1 | .v-modal-enter { 2 | animation: v-modal-in .2s ease; 3 | } 4 | 5 | .v-modal-leave { 6 | animation: v-modal-out .2s ease forwards; 7 | } 8 | 9 | @keyframes v-modal-in { 10 | 0% { 11 | opacity: 0; 12 | } 13 | 100% { 14 | } 15 | } 16 | 17 | @keyframes v-modal-out { 18 | 0% { 19 | } 20 | 100% { 21 | opacity: 0; 22 | } 23 | } 24 | 25 | .v-modal { 26 | position: fixed; 27 | left: 0; 28 | top: 0; 29 | width: 100%; 30 | height: 100%; 31 | opacity: 0.5; 32 | background: #000; 33 | } 34 | -------------------------------------------------------------------------------- /packages/checkbox/src/checkbox-group.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /packages/date-picker/src/picker/date-picker.js: -------------------------------------------------------------------------------- 1 | import Picker from '../picker'; 2 | import DatePanel from '../panel/date'; 3 | import DateRangePanel from '../panel/date-range'; 4 | 5 | const getPanel = function(type) { 6 | if (type === 'daterange' || type === 'datetimerange') { 7 | return DateRangePanel; 8 | } 9 | return DatePanel; 10 | }; 11 | 12 | export default { 13 | mixins: [Picker], 14 | 15 | name: 'ElDatePicker', 16 | 17 | props: { 18 | type: { 19 | type: String, 20 | default: 'date' 21 | } 22 | }, 23 | 24 | created() { 25 | this.panel = getPanel(this.type); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /packages/theme-default/gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var gulp = require('gulp'); 4 | var postcss = require('gulp-postcss'); 5 | var cssmin = require('gulp-cssmin'); 6 | var salad = require('postcss-salad')(require('./salad.config.json')); 7 | 8 | gulp.task('compile', function() { 9 | return gulp.src('./src/*.css') 10 | .pipe(postcss([salad])) 11 | .pipe(cssmin()) 12 | .pipe(gulp.dest('./lib')); 13 | }); 14 | 15 | gulp.task('copyfont', function() { 16 | return gulp.src('./src/fonts/**') 17 | .pipe(cssmin()) 18 | .pipe(gulp.dest('./lib/fonts')); 19 | }); 20 | 21 | gulp.task('build', ['compile', 'copyfont']); 22 | -------------------------------------------------------------------------------- /examples/play/component.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 14 | 15 | 28 | -------------------------------------------------------------------------------- /packages/theme-default/src/option-group.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | 6 | @b select-group { 7 | margin: 0; 8 | padding: 0; 9 | 10 | @e wrap { 11 | list-style: none; 12 | margin: 0; 13 | padding: 0; 14 | } 15 | 16 | @e title { 17 | padding-left: 10px; 18 | font-size: var(--select-group-font-size); 19 | color: var(--select-group-color); 20 | height: var(--select-group-height); 21 | line-height: var(--select-group-height); 22 | } 23 | 24 | & .el-select-dropdown__item { 25 | padding-left: 20px; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/dom/class.js: -------------------------------------------------------------------------------- 1 | export const hasClass = function(obj, cls) { 2 | return obj.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')); 3 | }; 4 | 5 | export const addClass = function(obj, cls) { 6 | if (!hasClass(obj, cls)) obj.className += ' ' + cls; 7 | }; 8 | 9 | export const removeClass = function(obj, cls) { 10 | if (hasClass(obj, cls)) { 11 | const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)'); 12 | obj.className = obj.className.replace(reg, ' '); 13 | } 14 | }; 15 | 16 | export const toggleClass = function(obj, cls) { 17 | if (hasClass(obj, cls)) { 18 | removeClass(obj, cls); 19 | } else { 20 | addClass(obj, cls); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | // Polyfill fn.bind() for PhantomJS 2 | /* eslint-disable no-extend-native */ 3 | Function.prototype.bind = require('function-bind'); 4 | require('packages/theme-default/src/index.css'); 5 | 6 | // require all test files (files that ends with .spec.js) 7 | const testsContext = require.context('./specs', true, /\.spec$/); 8 | testsContext.keys().forEach(testsContext); 9 | 10 | // require all src files except main.js for coverage. 11 | // you can also change this to match only the subset of files that 12 | // you want coverage for. 13 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/); 14 | srcContext.keys().forEach(srcContext); 15 | -------------------------------------------------------------------------------- /packages/theme-default/README.md: -------------------------------------------------------------------------------- 1 | # element-theme-default 2 | > element component defualt theme. 3 | 4 | 5 | ## Installation 6 | ```shell 7 | npm i element-theme-default -S 8 | ``` 9 | 10 | ## Usage 11 | 12 | Use Sass Or postcss-import 13 | ```css 14 | @import 'element-theme-default'; 15 | ``` 16 | 17 | Or Use webpack 18 | ```javascript 19 | import 'element-theme-default'; 20 | ``` 21 | 22 | Or 23 | ```html 24 | 25 | ``` 26 | 27 | ## Import your need 28 | ```javascript 29 | import 'element-theme-default/lib/input.css'; 30 | import 'element-theme-default/lib/select.css'; 31 | 32 | // ... 33 | ``` 34 | -------------------------------------------------------------------------------- /packages/upload/src/upload-dragger.vue: -------------------------------------------------------------------------------- 1 | 14 | 31 | 32 | -------------------------------------------------------------------------------- /packages/theme-default/src/core/tag.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "../common/var.css"; 3 | 4 | @component-namespace element-core { 5 | 6 | @b tag { 7 | background-color: var(--tag-fill); 8 | border: 0; 9 | border-radius: var(--tag-border-radius); 10 | color: var(--tag-color); 11 | height: 22px; 12 | margin: 1px; 13 | outline: 0; 14 | padding: 3px 16px 3px 3px; 15 | position: relative; 16 | 17 | @e button { 18 | color: var(--tag-close-color); 19 | cursor: pointer; 20 | line-height: 1; 21 | 22 | /* 增大可点击面积 */ 23 | padding: 5px; 24 | position: absolute; 25 | right: 0; 26 | top: 0; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/radio/src/radio-group.vue: -------------------------------------------------------------------------------- 1 | 6 | 31 | 32 | -------------------------------------------------------------------------------- /packages/theme-default/src/card.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | @b card { 6 | border: 1px solid var(--card-border-color); 7 | border-radius: var(--card-border-radius); 8 | background-color: var(--color-white); 9 | overflow: hidden; 10 | box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, .12), 11 | 0px 0px 6px 0px rgba(0, 0, 0, .04); 12 | 13 | @e header { 14 | padding: calc(var(--card-padding) - 2) var(--card-padding); 15 | border-bottom: 1px solid var(--card-border-color); 16 | box-sizing: border-box; 17 | } 18 | 19 | @e body { 20 | padding: var(--card-padding); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/unit/specs/breadcrumb.spec.js: -------------------------------------------------------------------------------- 1 | import { createVue, destroyVM } from '../util'; 2 | 3 | describe('Breadcrumb', () => { 4 | let vm; 5 | afterEach(() => { 6 | destroyVM(vm); 7 | }); 8 | 9 | it('create', done => { 10 | vm = createVue(` 11 | 12 | 首页 13 | 活动管理 14 | 活动列表 15 | 活动详情 16 | 17 | `); 18 | vm.$nextTick(_ => { 19 | expect(vm.$el.querySelector('.el-breadcrumb__separator').innerText).to.equal('>'); 20 | done(); 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/theme-default/src/date-picker/time-range-picker.css: -------------------------------------------------------------------------------- 1 | @import "../common/var.css"; 2 | 3 | @component-namespace el { 4 | @b time-range-picker { 5 | min-width: 354px; 6 | overflow: visible; 7 | 8 | @e content { 9 | position: relative; 10 | text-align: center; 11 | padding: 10px; 12 | } 13 | 14 | @e cell { 15 | box-sizing: border-box; 16 | margin: 0; 17 | padding: 4px 7px 7px; 18 | width: 50%; 19 | display: inline-block; 20 | } 21 | 22 | @e header { 23 | margin-bottom: 5px; 24 | text-align: center; 25 | font-size: 14px; 26 | } 27 | 28 | @e body { 29 | border-radius:2px; 30 | border: 1px solid var(--datepicker-border-color); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/dropdown/src/dropdown-item.vue: -------------------------------------------------------------------------------- 1 | 13 | 34 | -------------------------------------------------------------------------------- /packages/spinner/src/spinner.vue: -------------------------------------------------------------------------------- 1 | 8 | 28 | -------------------------------------------------------------------------------- /packages/theme-default/src/date-picker/picker.css: -------------------------------------------------------------------------------- 1 | @import "../common/var.css"; 2 | @import "../common/transition.css"; 3 | 4 | @component-namespace el { 5 | @b date-editor { 6 | position: relative; 7 | display: inline-block; 8 | 9 | &.el-input { 10 | width: 193px; 11 | } 12 | 13 | @m daterange { 14 | &.el-input { 15 | width: 220px; 16 | } 17 | } 18 | 19 | @m datetimerange { 20 | &.el-input { 21 | width: 350px; 22 | } 23 | } 24 | 25 | .el-picker-panel { 26 | position: absolute; 27 | min-width: 180px; 28 | box-sizing: border-box; 29 | box-shadow: 0 2px 6px #ccc; 30 | background: var(--color-white); 31 | z-index: 10; 32 | top: 41px; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/table/src/dropdown.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | var dropdowns = []; 3 | 4 | !Vue.prototype.$isServer && document.addEventListener('click', function(event) { 5 | dropdowns.forEach(function(dropdown) { 6 | var target = event.target; 7 | if (!dropdown || !dropdown.$el) return; 8 | if (target === dropdown.$el || dropdown.$el.contains(target)) { 9 | return; 10 | } 11 | dropdown.handleOutsideClick && dropdown.handleOutsideClick(event); 12 | }); 13 | }); 14 | 15 | export default { 16 | open(instance) { 17 | if (instance) { 18 | dropdowns.push(instance); 19 | } 20 | }, 21 | 22 | close(instance) { 23 | var index = dropdowns.indexOf(instance); 24 | if (index !== -1) { 25 | dropdowns.splice(instance, 1); 26 | } 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /examples/docs/en-US/icon.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ## Icon 14 | 15 | Element provides a set of common icons. 16 | 17 | ### Basic usage 18 | 19 | Just assign the class name to `el-icon-iconName`. 20 | 21 | :::demo 22 | 23 | ```html 24 | 25 | 26 | 27 | Search 28 | 29 | ``` 30 | ::: 31 | 32 | ### Icons 33 | 34 | -------------------------------------------------------------------------------- /packages/tag/src/tag.vue: -------------------------------------------------------------------------------- 1 | 14 | 32 | -------------------------------------------------------------------------------- /packages/scrollbar/src/util.js: -------------------------------------------------------------------------------- 1 | export const BAR_MAP = { 2 | vertical: { 3 | offset: 'offsetHeight', 4 | scroll: 'scrollTop', 5 | scrollSize: 'scrollHeight', 6 | size: 'height', 7 | key: 'vertical', 8 | axis: 'Y', 9 | client: 'clientY', 10 | direction: 'top' 11 | }, 12 | horizontal: { 13 | offset: 'offsetWidth', 14 | scroll: 'scrollLeft', 15 | scrollSize: 'scrollWidth', 16 | size: 'width', 17 | key: 'horizontal', 18 | axis: 'X', 19 | client: 'clientX', 20 | direction: 'left' 21 | } 22 | }; 23 | 24 | export function renderThumbStyle({ move, size, bar }) { 25 | const style = {}; 26 | const translate = `translate${bar.axis}(${ move }%)`; 27 | 28 | style[bar.size] = size; 29 | style.transform = translate; 30 | style.msTransform = translate; 31 | style.webkitTransform = translate; 32 | 33 | return style; 34 | }; 35 | -------------------------------------------------------------------------------- /src/utils/scrollbar-width.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | let scrollBarWidth; 4 | 5 | export default function() { 6 | if (Vue.prototype.$isServer) return 0; 7 | if (scrollBarWidth !== undefined) return scrollBarWidth; 8 | 9 | const outer = document.createElement('div'); 10 | outer.className = 'el-scrollbar__wrap'; 11 | outer.style.visibility = 'hidden'; 12 | outer.style.width = '100px'; 13 | outer.style.position = 'absolute'; 14 | outer.style.top = '-9999px'; 15 | document.body.appendChild(outer); 16 | 17 | const widthNoScroll = outer.offsetWidth; 18 | outer.style.overflow = 'scroll'; 19 | 20 | const inner = document.createElement('div'); 21 | inner.style.width = '100%'; 22 | outer.appendChild(inner); 23 | 24 | const widthWithScroll = inner.offsetWidth; 25 | outer.parentNode.removeChild(outer); 26 | 27 | return widthNoScroll - widthWithScroll; 28 | }; 29 | -------------------------------------------------------------------------------- /packages/theme-default/src/row.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | @b row { 6 | position: relative; 7 | box-sizing: border-box; 8 | @utils-clearfix; 9 | 10 | @m flex { 11 | display: flex; 12 | &:before, 13 | &:after { 14 | display: none; 15 | } 16 | 17 | @when justify-center { 18 | justify-content: center; 19 | } 20 | @when justify-end { 21 | justify-content: flex-end; 22 | } 23 | @when justify-space-between { 24 | justify-content: space-between; 25 | } 26 | @when justify-space-around { 27 | justify-content: space-around; 28 | } 29 | 30 | @when align-middle { 31 | align-items: center; 32 | } 33 | @when align-bottom { 34 | align-items: flex-end; 35 | } 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/breadcrumb/src/breadcrumb-item.vue: -------------------------------------------------------------------------------- 1 | 6 | 32 | -------------------------------------------------------------------------------- /packages/theme-default/src/time-select.css: -------------------------------------------------------------------------------- 1 | @import "./date-picker/picker.css"; 2 | @import "./date-picker/date-picker.css"; 3 | @import "./common/var.css"; 4 | @import "./scrollbar.css"; 5 | 6 | .time-select { 7 | margin: 5px 0; 8 | min-width: 0; 9 | } 10 | 11 | .time-select .el-picker-panel__content { 12 | max-height: 200px; 13 | margin: 0; 14 | } 15 | 16 | .time-select-item { 17 | padding: 8px 10px; 18 | font-size: 14px; 19 | } 20 | 21 | .time-select-item.selected:not(.disabled) { 22 | background-color: var(--datepicker-active-color); 23 | color: var(--color-white); 24 | 25 | &:hover { 26 | background-color: var(--color-primary); 27 | } 28 | } 29 | 30 | .time-select-item.disabled { 31 | color: var(--datepicker-border-color); 32 | cursor: not-allowed; 33 | } 34 | 35 | .time-select-item:hover { 36 | background-color: var(--datepicker-cell-hover-color); 37 | cursor: pointer; 38 | } 39 | -------------------------------------------------------------------------------- /packages/badge/src/main.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 42 | -------------------------------------------------------------------------------- /packages/dropdown/src/dropdown-menu.vue: -------------------------------------------------------------------------------- 1 | 8 | 39 | -------------------------------------------------------------------------------- /packages/theme-default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-theme-default", 3 | "version": "1.2.7", 4 | "description": "Element component default theme.", 5 | "main": "lib/index.css", 6 | "style": "lib/index.css", 7 | "files": [ 8 | "lib", 9 | "src" 10 | ], 11 | "scripts": { 12 | "build": "gulp build" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/ElementUI/theme-default.git" 17 | }, 18 | "keywords": [ 19 | "element", 20 | "theme" 21 | ], 22 | "author": "haiping.zeng ", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/ElementUI/theme-default/issues" 26 | }, 27 | "homepage": "https://github.com/ElementUI/theme-default#readme", 28 | "devDependencies": { 29 | "gulp": "^3.9.1", 30 | "gulp-cssmin": "^0.1.7", 31 | "gulp-postcss": "^6.1.1", 32 | "postcss-salad": "^1.0.5" 33 | }, 34 | "dependencies": {} 35 | } 36 | -------------------------------------------------------------------------------- /test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | var webpackConfig = require('../../build/cooking.test'); 2 | 3 | // no need for app entry during tests 4 | delete webpackConfig.entry; 5 | 6 | module.exports = function(config) { 7 | config.set({ 8 | // to run in additional browsers: 9 | // 1. install corresponding karma launcher 10 | // http://karma-runner.github.io/0.13/config/browsers.html 11 | // 2. add it to the `browsers` array below. 12 | browsers: ['PhantomJS'], 13 | frameworks: ['mocha', 'sinon-chai'], 14 | reporters: ['spec', 'coverage'], 15 | files: ['./index.js'], 16 | preprocessors: { 17 | './index.js': ['webpack', 'sourcemap'] 18 | }, 19 | webpack: webpackConfig, 20 | webpackMiddleware: { 21 | noInfo: true 22 | }, 23 | coverageReporter: { 24 | dir: './coverage', 25 | reporters: [ 26 | { type: 'lcov', subdir: '.' }, 27 | { type: 'text-summary' } 28 | ] 29 | } 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /packages/theme-default/src/date-picker/month-table.css: -------------------------------------------------------------------------------- 1 | @import "../common/var.css"; 2 | 3 | @component-namespace el { 4 | @b month-table { 5 | font-size: 12px; 6 | margin: -1px; 7 | border-collapse: collapse; 8 | 9 | td { 10 | text-align: center; 11 | padding: 20px 3px; 12 | cursor: pointer; 13 | 14 | &.disabled .cell { 15 | background-color: #f4f4f4; 16 | cursor: not-allowed; 17 | color: #ccc; 18 | } 19 | 20 | .cell { 21 | width: 48px; 22 | height: 32px; 23 | display: block; 24 | line-height: 32px; 25 | color: var(--datepicker-color); 26 | 27 | &:hover { 28 | background-color: var(--datepicker-cell-hover-color); 29 | } 30 | } 31 | 32 | &.current:not(.disabled) .cell { 33 | background-color: var(--datepicker-active-color) !important; 34 | color: var(--color-white); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/theme-default/src/spinner.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | @b time-spinner { 6 | width: 100%; 7 | white-space: nowrap; 8 | } 9 | 10 | @b spinner { 11 | display: inline-block; 12 | vertical-align: middle; 13 | } 14 | @b spinner-inner { 15 | animation: rotate 2s linear infinite; 16 | width: 50px; 17 | height: 50px; 18 | 19 | & .path { 20 | stroke: #ececec; 21 | stroke-linecap: round; 22 | animation: dash 1.5s ease-in-out infinite; 23 | } 24 | 25 | } 26 | } 27 | @keyframes rotate { 28 | 100% { 29 | transform: rotate(360deg); 30 | } 31 | } 32 | 33 | @keyframes dash { 34 | 0% { 35 | stroke-dasharray: 1, 150; 36 | stroke-dashoffset: 0; 37 | } 38 | 50% { 39 | stroke-dasharray: 90, 150; 40 | stroke-dashoffset: -35; 41 | } 42 | 100% { 43 | stroke-dasharray: 90, 150; 44 | stroke-dashoffset: -124; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/unit/specs/card.spec.js: -------------------------------------------------------------------------------- 1 | import { createVue, createTest, destroyVM } from '../util'; 2 | import Card from 'packages/card'; 3 | 4 | describe('Card', () => { 5 | let vm; 6 | afterEach(() => { 7 | destroyVM(vm); 8 | }); 9 | 10 | it('slot:header', () => { 11 | vm = createVue(` 12 | 13 |
二师兄叫我埋梗 啦啦啦
14 |
15 | `); 16 | 17 | expect(vm.$el.querySelector('.el-card__header')).to.property('textContent').to.include('二师兄叫我埋梗 啦啦啦'); 18 | }); 19 | 20 | it('header', () => { 21 | vm = createTest(Card, { 22 | header: '好烦' 23 | }); 24 | 25 | expect(vm.$el.querySelector('.el-card__header')).to.property('textContent').to.include('好烦'); 26 | }); 27 | 28 | it('bodyStyle', () => { 29 | vm = createTest(Card, { 30 | bodyStyle: { padding: '10px' } 31 | }); 32 | 33 | expect(vm.$el.querySelector('.el-card__body').style.padding).to.equal('10px'); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/row/src/row.vue: -------------------------------------------------------------------------------- 1 | 16 | 47 | -------------------------------------------------------------------------------- /packages/loading/src/loading.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 38 | -------------------------------------------------------------------------------- /packages/steps/src/steps.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 52 | -------------------------------------------------------------------------------- /packages/theme-default/src/date-picker/year-table.css: -------------------------------------------------------------------------------- 1 | @import "../common/var.css"; 2 | 3 | @component-namespace el { 4 | @b year-table { 5 | font-size: 12px; 6 | margin: -1px; 7 | border-collapse: collapse; 8 | 9 | .el-icon { 10 | color: var(--datepicker-icon-color); 11 | } 12 | 13 | td { 14 | text-align: center; 15 | padding: 20px 3px; 16 | cursor: pointer; 17 | 18 | &.disabled .cell { 19 | background-color: #f4f4f4; 20 | cursor: not-allowed; 21 | color: #ccc; 22 | } 23 | 24 | .cell { 25 | width: 48px; 26 | height: 32px; 27 | display: block; 28 | line-height: 32px; 29 | color: var(--datepicker-color); 30 | 31 | &:hover { 32 | background-color: var(--datepicker-cell-hover-color); 33 | } 34 | } 35 | 36 | &.current:not(.disabled) .cell { 37 | background-color: var(--datepicker-active-color) !important; 38 | color: var(--color-white); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/theme-default/src/breadcrumb.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | 6 | @b breadcrumb { 7 | font-size:13px; 8 | line-height: 1; 9 | @utils-clearfix; 10 | 11 | @e separator { 12 | margin: 0 8px; 13 | color: var(--color-extra-light-silver); 14 | } 15 | @e item { 16 | float: left; 17 | 18 | @e inner { 19 | &, & a { 20 | transition: color .15s linear; 21 | color:var(--color-extra-light-black); 22 | 23 | &:hover { 24 | color: var(--color-primary); 25 | cursor: pointer; 26 | } 27 | } 28 | } 29 | 30 | &:last-child { 31 | .el-breadcrumb__item__inner, 32 | .el-breadcrumb__item__inner a { 33 | &, &:hover { 34 | color: var(--color-light-silver); 35 | cursor: text; 36 | } 37 | } 38 | 39 | .el-breadcrumb__separator { 40 | display: none; 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/mixins/emitter.js: -------------------------------------------------------------------------------- 1 | function broadcast(componentName, eventName, params) { 2 | this.$children.forEach(child => { 3 | var name = child.$options.componentName; 4 | 5 | if (name === componentName) { 6 | child.$emit.apply(child, [eventName].concat(params)); 7 | } else { 8 | broadcast.apply(child, [componentName, eventName].concat([params])); 9 | } 10 | }); 11 | } 12 | export default { 13 | methods: { 14 | dispatch(componentName, eventName, params) { 15 | var parent = this.$parent || this.$root; 16 | var name = parent.$options.componentName; 17 | 18 | while (parent && (!name || name !== componentName)) { 19 | parent = parent.$parent; 20 | 21 | if (parent) { 22 | name = parent.$options.componentName; 23 | } 24 | } 25 | if (parent) { 26 | parent.$emit.apply(parent, [eventName].concat(params)); 27 | } 28 | }, 29 | broadcast(componentName, eventName, params) { 30 | broadcast.call(this, componentName, eventName, params); 31 | } 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /packages/theme-default/src/rate.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | 6 | @b rate { 7 | height: var(--rate-height); 8 | line-height: 1; 9 | 10 | @e item { 11 | display: inline-block; 12 | position: relative; 13 | font-size: 0; 14 | vertical-align: middle; 15 | } 16 | 17 | @e icon { 18 | position: relative; 19 | display: inline-block; 20 | font-size: var(--rate-icon-size); 21 | margin-right: var(--rate-icon-margin); 22 | color: var(--rate-icon-color); 23 | transition: .3s; 24 | &.hover { 25 | transform: scale(1.15); 26 | } 27 | 28 | .path2 { 29 | position: absolute; 30 | left: 0; 31 | top: 0; 32 | } 33 | } 34 | 35 | @e decimal { 36 | position: absolute; 37 | top: 0; 38 | left: 0; 39 | display: inline-block; 40 | overflow: hidden; 41 | } 42 | 43 | @e text { 44 | font-size: var(--rate-font-size); 45 | vertical-align: middle; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/color-picker/src/draggable.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | let isDragging = false; 3 | 4 | export default function(element, options) { 5 | if (Vue.prototype.$isServer) return; 6 | const moveFn = function(event) { 7 | if (options.drag) { 8 | options.drag(event); 9 | } 10 | }; 11 | const upFn = function(event) { 12 | document.removeEventListener('mousemove', moveFn); 13 | document.removeEventListener('mouseup', upFn); 14 | document.onselectstart = null; 15 | document.ondragstart = null; 16 | 17 | isDragging = false; 18 | 19 | if (options.end) { 20 | options.end(event); 21 | } 22 | }; 23 | element.addEventListener('mousedown', function(event) { 24 | if (isDragging) return; 25 | document.onselectstart = function() { return false; }; 26 | document.ondragstart = function() { return false; }; 27 | 28 | document.addEventListener('mousemove', moveFn); 29 | document.addEventListener('mouseup', upFn); 30 | isDragging = true; 31 | 32 | if (options.start) { 33 | options.start(event); 34 | } 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /packages/theme-default/src/badge.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | @b badge { 6 | position: relative; 7 | vertical-align: middle; 8 | display: inline-block; 9 | 10 | @e content { 11 | background-color: var(--badge-fill); 12 | border-radius: var(--badge-radius); 13 | color: var(--color-white); 14 | display: inline-block; 15 | font-size: var(--badge-font-size); 16 | height: var(--badge-size); 17 | line-height: var(--badge-size); 18 | padding: 0 var(--badge-padding); 19 | text-align: center; 20 | white-space: nowrap; 21 | border: 1px solid var(--color-white); 22 | 23 | @when fixed { 24 | position: absolute 0 calc(var(--badge-size) / 2 + 1) * *; 25 | transform: translateY(-50%) translateX(100%); 26 | 27 | @when dot { 28 | right: 5px; 29 | } 30 | } 31 | 32 | @when dot { 33 | size: 8px 8px; 34 | padding: 0; 35 | right: 0; 36 | border-radius: 50%; 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/unit/specs/badge.spec.js: -------------------------------------------------------------------------------- 1 | import { createTest, createVue, destroyVM } from '../util'; 2 | import Badge from 'packages/badge'; 3 | 4 | describe('Badge', () => { 5 | let vm; 6 | afterEach(() => { 7 | destroyVM(vm); 8 | }); 9 | 10 | it('value', () => { 11 | vm = createTest(Badge, { value: 80 }); 12 | expect(vm.content).to.equal(80); 13 | }); 14 | 15 | it('is fixed', () => { 16 | vm = createVue(` 17 | 18 | 19 | 20 | `); 21 | 22 | expect(vm.$el.querySelector('.el-badge__content.is-fixed')).to.exist; 23 | }); 24 | 25 | it('is dot', () => { 26 | vm = createVue(` 27 | 28 | 29 | 30 | `); 31 | 32 | expect(vm.$el.querySelector('.el-badge__content.is-dot')).to.exist; 33 | }); 34 | 35 | it('max', () => { 36 | vm = createTest(Badge, { max: 100, value: 200 }); 37 | expect(vm.content).to.equal('100+'); 38 | vm = createTest(Badge, { max: 100, value: 80 }); 39 | expect(vm.content).to.equal(80); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /examples/i18n/component.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "lang": "zh-CN", 4 | "demo-block": { 5 | "hide-text": "隐藏代码", 6 | "show-text": "显示代码", 7 | "button-text": "在线运行", 8 | "tooltip-text": "前往 jsfiddle.net 运行此示例" 9 | }, 10 | "footer": { 11 | "feedback": "反馈建议", 12 | "contribution": "贡献指南", 13 | "eleme": "饿了么" 14 | }, 15 | "header": { 16 | "guide": "指南", 17 | "components": "组件", 18 | "resource": "资源" 19 | }, 20 | "nav": { 21 | "dropdown": "版本:" 22 | } 23 | }, 24 | { 25 | "lang": "en-US", 26 | "demo-block": { 27 | "hide-text": "Hide", 28 | "show-text": "Expand", 29 | "button-text": "Try it!", 30 | "tooltip-text": "Run this demo on jsfiddle.net" 31 | }, 32 | "footer": { 33 | "feedback": "Feedback", 34 | "contribution": "Contribution", 35 | "eleme": "Eleme" 36 | }, 37 | "header": { 38 | "guide": "Guide", 39 | "components": "Component", 40 | "resource": "Resource" 41 | }, 42 | "nav": { 43 | "dropdown": "Version: " 44 | } 45 | } 46 | ] 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 ElemeFE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /examples/assets/styles/fonts/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src: url('icomoon.eot?h6xgdm'); 4 | src: url('icomoon.eot?h6xgdm#iefix') format('embedded-opentype'), 5 | url('icomoon.ttf?h6xgdm') format('truetype'), 6 | url('icomoon.woff?h6xgdm') format('woff'), 7 | url('icomoon.svg?h6xgdm#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], [class*=" icon-"] { 13 | /* use !important to prevent issues with browser extensions that change fonts */ 14 | font-family: 'icomoon' !important; 15 | speak: none; 16 | font-style: normal; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | 22 | /* Better Font Rendering =========== */ 23 | -webkit-font-smoothing: antialiased; 24 | -moz-osx-font-smoothing: grayscale; 25 | } 26 | 27 | .icon-rate-face-off:before { 28 | content: "\e900"; 29 | } 30 | .icon-rate-face-1:before { 31 | content: "\e901"; 32 | } 33 | .icon-rate-face-2:before { 34 | content: "\e902"; 35 | } 36 | .icon-rate-face-3:before { 37 | content: "\e903"; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /packages/theme-default/src/core/dropdown.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "../common/var.css"; 3 | @import "./option.css"; 4 | 5 | @component-namespace element { 6 | 7 | @b dropdown { 8 | background-color: var(--dropdown-fill); 9 | border: var(--dropdown-border); 10 | border-radius: var(--dropdown-radius); 11 | box-shadow: var(--dropdown-shadow); 12 | left: 0; 13 | list-style-type: none; 14 | margin: -var(--dropdown-border-width); 15 | margin-top: 5px; 16 | min-width: calc(var(--input-width) + 4); 17 | padding: 0; 18 | position: absolute; 19 | white-space: nowrap; 20 | z-index: var(--index-normal); 21 | 22 | @e empty { 23 | color: var(--dropdown-option-empty-color); 24 | font-size: var(--input-font-size); 25 | padding: 7px; 26 | text-align: center; 27 | } 28 | 29 | @e list { 30 | margin: 0; 31 | max-height: var(--cascader-height); 32 | overflow: auto; 33 | padding: 0; 34 | } 35 | 36 | @e option { 37 | max-height: 250px; 38 | overflow: auto; 39 | } 40 | 41 | &:empty { 42 | display: none; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/menu/src/menu-item-group.vue: -------------------------------------------------------------------------------- 1 | 12 | 44 | 45 | -------------------------------------------------------------------------------- /packages/tabs/src/tab-pane.vue: -------------------------------------------------------------------------------- 1 | 6 | 53 | -------------------------------------------------------------------------------- /src/locale/format.js: -------------------------------------------------------------------------------- 1 | import { hasOwn } from 'element-ui/src/utils/util'; 2 | 3 | const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g; 4 | /** 5 | * String format template 6 | * - Inspired: 7 | * https://github.com/Matt-Esch/string-template/index.js 8 | */ 9 | export default function(Vue) { 10 | 11 | /** 12 | * template 13 | * 14 | * @param {String} string 15 | * @param {Array} ...args 16 | * @return {String} 17 | */ 18 | 19 | function template(string, ...args) { 20 | if (args.length === 1 && typeof args[0] === 'object') { 21 | args = args[0]; 22 | } 23 | 24 | if (!args || !args.hasOwnProperty) { 25 | args = {}; 26 | } 27 | 28 | return string.replace(RE_NARGS, (match, prefix, i, index) => { 29 | let result; 30 | 31 | if (string[index - 1] === '{' && 32 | string[index + match.length] === '}') { 33 | return i; 34 | } else { 35 | result = hasOwn(args, i) ? args[i] : null; 36 | if (result === null || result === undefined) { 37 | return ''; 38 | } 39 | 40 | return result; 41 | } 42 | }); 43 | } 44 | 45 | return template; 46 | } 47 | -------------------------------------------------------------------------------- /examples/docs/zh-CN/breadcrumb.md: -------------------------------------------------------------------------------- 1 | ## Breadcrumb 面包屑 2 | 显示当前页面的路径,快速返回之前的任意页面。 3 | 4 | ### 基础用法 5 | 6 | 适用广泛的基础用法。 7 | 8 | :::demo 在`el-breadcrumb`中使用`el-breadcrumb-item`标签表示从首页开始的每一级。Element 提供了一个`separator`属性,在`el-breadcrumb`标签中设置它来决定分隔符,它只能是字符串,默认为斜杠`/`。 9 | 10 | ```html 11 | 12 | 首页 13 | 活动管理 14 | 活动列表 15 | 活动详情 16 | 17 | ``` 18 | ::: 19 | 20 | ### Breadcrumb Attributes 21 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 22 | |---------- |-------------- |---------- |-------------------------------- |-------- | 23 | | separator | 分隔符 | string | — | 斜杠'/' | 24 | 25 | ### Breadcrumb Item Attributes 26 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 27 | |---------- |-------------- |---------- |-------------------------------- |-------- | 28 | | to | 路由跳转对象,同 `vue-router` 的 `to` | string/object | — | — | 29 | | replace | 在使用 to 进行路由跳转时,启用 replace 将不会向 history 添加新记录 | boolean | — | false | 30 | -------------------------------------------------------------------------------- /packages/theme-default/src/carousel-item.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | 6 | @b carousel { 7 | @e item { 8 | position: absolute; 9 | top: 0; 10 | left: 0; 11 | width: 100%; 12 | height: 100%; 13 | display: inline-block; 14 | transition: .4s ease-in-out; 15 | overflow: hidden; 16 | z-index: calc(var(--index-normal) - 1); 17 | @when active { 18 | z-index: calc(var(--index-normal) + 1); 19 | } 20 | 21 | @modifier card { 22 | width: 50%; 23 | &.is-in-stage { 24 | cursor: pointer; 25 | z-index: var(--index-normal); 26 | &:hover .el-carousel__mask, 27 | &.is-hover .el-carousel__mask { 28 | opacity: 0.12; 29 | } 30 | } 31 | &.is-active { 32 | z-index: calc(var(--index-normal) + 1); 33 | } 34 | } 35 | } 36 | 37 | @e mask { 38 | position: absolute; 39 | width: 100%; 40 | height: 100%; 41 | top: 0; 42 | left: 0; 43 | background-color: var(--color-white); 44 | opacity: 0.24; 45 | transition: .2s; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /packages/tabs/src/tab-bar.vue: -------------------------------------------------------------------------------- 1 | 4 | 46 | -------------------------------------------------------------------------------- /packages/theme-default/src/option.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | 6 | @b select-dropdown { 7 | @e item { 8 | font-size: var(--select-font-size); 9 | padding: 8px 10px; 10 | position: relative; 11 | white-space: nowrap; 12 | overflow: hidden; 13 | text-overflow: ellipsis; 14 | color: var(--select-option-color); 15 | height: var(--select-option-height); 16 | line-height: 1.5; 17 | box-sizing: border-box; 18 | cursor: pointer; 19 | 20 | @when disabled { 21 | color: var(--select-option-disabled-color); 22 | cursor: not-allowed; 23 | 24 | &:hover { 25 | background-color: var(--color-white); 26 | } 27 | } 28 | 29 | &.hover { 30 | background-color: var(--select-option-hover-background); 31 | } 32 | 33 | &.selected { 34 | color: var(--color-white); 35 | background-color: var(--select-option-selected); 36 | 37 | &.hover { 38 | background-color: var(--select-option-selected-hover); 39 | } 40 | } 41 | 42 | & span { 43 | line-height: 1.5 !important; 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/button/src/button.vue: -------------------------------------------------------------------------------- 1 | 21 | 52 | -------------------------------------------------------------------------------- /test/unit/specs/row.spec.js: -------------------------------------------------------------------------------- 1 | import { createTest, destroyVM } from '../util'; 2 | import Row from 'packages/row'; 3 | 4 | describe('Row', () => { 5 | let vm; 6 | afterEach(() => { 7 | destroyVM(vm); 8 | }); 9 | 10 | it('create', () => { 11 | vm = createTest(Row, true); 12 | let rowElm = vm.$el; 13 | expect(rowElm.classList.contains('el-row')).to.be.true; 14 | }); 15 | it('gutter', () => { 16 | vm = createTest(Row, { 17 | gutter: 20 18 | }, true); 19 | let rowElm = vm.$el; 20 | expect(rowElm.style.marginLeft).to.be.equal('-10px'); 21 | expect(rowElm.style.marginRight).to.be.equal('-10px'); 22 | }); 23 | it('type', () => { 24 | vm = createTest(Row, { 25 | type: 'flex' 26 | }, true); 27 | let rowElm = vm.$el; 28 | expect(rowElm.classList.contains('el-row--flex')).to.be.true; 29 | }); 30 | it('justify', () => { 31 | vm = createTest(Row, { 32 | justify: 'end' 33 | }, true); 34 | let rowElm = vm.$el; 35 | expect(rowElm.classList.contains('is-justify-end')).to.be.true; 36 | }); 37 | it('align', () => { 38 | vm = createTest(Row, { 39 | align: 'bottom' 40 | }, true); 41 | let rowElm = vm.$el; 42 | expect(rowElm.classList.contains('is-align-bottom')).to.be.true; 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /examples/entry.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import entry from './app'; 3 | import VueRouter from 'vue-router'; 4 | import routes from './route.config'; 5 | import Element from 'main/index.js'; 6 | import 'packages/theme-default/src/index.css'; 7 | import demoBlock from './components/demo-block.vue'; 8 | import MainFooter from './components/footer.vue'; 9 | import MainHeader from './components/header.vue'; 10 | import SideNav from './components/side-nav'; 11 | import FooterNav from './components/footer-nav'; 12 | import title from './i18n/title.json'; 13 | 14 | Vue.use(Element); 15 | Vue.use(VueRouter); 16 | Vue.component('demo-block', demoBlock); 17 | Vue.component('main-footer', MainFooter); 18 | Vue.component('main-header', MainHeader); 19 | Vue.component('side-nav', SideNav); 20 | Vue.component('footer-nav', FooterNav); 21 | 22 | const router = new VueRouter({ 23 | mode: 'hash', 24 | base: __dirname, 25 | routes 26 | }); 27 | 28 | router.afterEach(route => { 29 | const data = title[route.meta.lang]; 30 | for (let val in data) { 31 | if (new RegExp('^' + val, 'g').test(route.name)) { 32 | document.title = data[val]; 33 | return; 34 | } 35 | } 36 | document.title = 'Element'; 37 | }); 38 | 39 | new Vue({ // eslint-disable-line 40 | render: h => h(entry), 41 | router 42 | }).$mount('#app'); 43 | -------------------------------------------------------------------------------- /examples/index.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Element 8 | 9 | 10 |
<% if (process.env.NODE_ENV === 'production') { %> 11 | 12 | <% } %> 13 | 14 | <% if (process.env.NODE_ENV === 'production') { %><% } %> 28 | 29 | -------------------------------------------------------------------------------- /packages/menu/src/menu-item.vue: -------------------------------------------------------------------------------- 1 | 12 | 58 | -------------------------------------------------------------------------------- /packages/menu/src/menu-mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | computed: { 3 | indexPath() { 4 | var path = [this.index]; 5 | var parent = this.$parent; 6 | while (parent.$options.componentName !== 'ElMenu') { 7 | if (parent.index) { 8 | path.unshift(parent.index); 9 | } 10 | parent = parent.$parent; 11 | } 12 | return path; 13 | }, 14 | rootMenu() { 15 | var parent = this.$parent; 16 | while ( 17 | parent && 18 | parent.$options.componentName !== 'ElMenu' 19 | ) { 20 | parent = parent.$parent; 21 | } 22 | return parent; 23 | }, 24 | parentMenu() { 25 | let parent = this.$parent; 26 | while ( 27 | parent && 28 | ['ElMenu', 'ElSubmenu'].indexOf(parent.$options.componentName) === -1 29 | ) { 30 | parent = parent.$parent; 31 | } 32 | return parent; 33 | }, 34 | paddingStyle() { 35 | if (this.rootMenu.mode !== 'vertical') return {}; 36 | 37 | let padding = 20; 38 | let parent = this.$parent; 39 | while (parent && parent.$options.componentName !== 'ElMenu') { 40 | if (parent.$options.componentName === 'ElSubmenu') { 41 | padding += 20; 42 | } 43 | parent = parent.$parent; 44 | } 45 | return {paddingLeft: padding + 'px'}; 46 | } 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /src/locale/index.js: -------------------------------------------------------------------------------- 1 | import defaultLang from 'element-ui/src/locale/lang/zh-CN'; 2 | import Vue from 'vue'; 3 | import deepmerge from 'deepmerge'; 4 | import Format from './format'; 5 | 6 | const format = Format(Vue); 7 | let lang = defaultLang; 8 | let merged = false; 9 | let i18nHandler = function() { 10 | const vuei18n = Object.getPrototypeOf(this || Vue).$t; 11 | if (typeof vuei18n === 'function') { 12 | if (!merged) { 13 | merged = true; 14 | Vue.locale( 15 | Vue.config.lang, 16 | deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true }) 17 | ); 18 | } 19 | return vuei18n.apply(this, arguments); 20 | } 21 | }; 22 | 23 | export const t = function(path, options) { 24 | let value = i18nHandler.apply(this, arguments); 25 | if (value !== null && value !== undefined) return value; 26 | 27 | const array = path.split('.'); 28 | let current = lang; 29 | 30 | for (let i = 0, j = array.length; i < j; i++) { 31 | const property = array[i]; 32 | value = current[property]; 33 | if (i === j - 1) return format(value, options); 34 | if (!value) return ''; 35 | current = value; 36 | } 37 | return ''; 38 | }; 39 | 40 | export const use = function(l) { 41 | lang = l || lang; 42 | }; 43 | 44 | export const i18n = function(fn) { 45 | i18nHandler = fn || i18nHandler; 46 | }; 47 | 48 | export default { use, t, i18n }; 49 | -------------------------------------------------------------------------------- /packages/select/src/option-group.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 61 | -------------------------------------------------------------------------------- /packages/theme-default/src/core/input.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "../common/var.css"; 3 | 4 | @component-namespace element-core { 5 | 6 | @b input { 7 | background-color: var(--input-fill); 8 | border: var(--input-border); 9 | border-radius: var(--input-border-radius); 10 | box-sizing: border-box; 11 | color: var(--input-color); 12 | cursor: text; 13 | display: inline-block; 14 | font-size: var(--input-font-size); 15 | min-height: var(--input-height); 16 | min-width: var(--input-width); 17 | padding: 2px; 18 | position: relative; 19 | vertical-align: middle; 20 | 21 | @when disabled { 22 | background-color: var(--input-fill-disabled); 23 | border-color: inherit; 24 | box-shadow: none; 25 | color: var(--input-color-disabled); 26 | cursor: not-allowed; 27 | } 28 | 29 | @when readonly { 30 | cursor: pointer; 31 | } 32 | 33 | @when multiple { 34 | cursor: text; 35 | } 36 | 37 | &:hover, 38 | &.is-active { 39 | border-color: var(--input-focus-border); 40 | box-shadow: var(--input-shadow-hover); 41 | } 42 | 43 | @e original { 44 | background-color: inherit; 45 | border: none; 46 | box-sizing: border-box; 47 | cursor: inherit; 48 | height: 100%; 49 | line-height: 1.2; 50 | outline: none; 51 | padding: 5px 7px; 52 | width: auto; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /examples/docs/en-US/breadcrumb.md: -------------------------------------------------------------------------------- 1 | ## Breadcrumb 2 | 3 | Displays the location of the current page, making it easier to browser back. 4 | 5 | ### Basic usage 6 | 7 | 8 | :::demo In `el-breadcrumb`, each `el-breadcrumb-item` is a tag that stands for every level starting from homepage. This component has a `String` attribute `separator`, and it determines the separator. Its default value is '/'. 9 | 10 | ```html 11 | 12 | homepage 13 | promotion management 14 | promotion list 15 | promotion detail 16 | 17 | ``` 18 | ::: 19 | 20 | ### Breadcrumb Attributes 21 | | Attribute | Description | Type | Accepted Values | Default| 22 | |---------- |-------------- |---------- |-------------------------------- |-------- | 23 | | separator | separator character | string | — | / | 24 | 25 | ### Breadcrumb Item Attributes 26 | | Attribute | Description | Type | Accepted Values | Default| 27 | |---------- |-------------- |---------- |-------------------------------- |-------- | 28 | | to | target route of the link, same as `to` of `vue-router` | string/object | — | — | 29 | | replace | if `true`, the navigation will not leave a history record | boolean | — | false | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /packages/theme-default/src/reset.css: -------------------------------------------------------------------------------- 1 | @import './common/var.css'; 2 | 3 | @reset-global pc; 4 | body { 5 | font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; 6 | font-weight: 400; 7 | font-size: var(--font-size-base); 8 | color: var(--color-base-black); 9 | } 10 | 11 | a { 12 | color: var(--color-primary); 13 | text-decoration: none; 14 | 15 | &:hover, 16 | &:focus { 17 | color: tint(var(--color-primary), var(--button-hover-tint-percent)); 18 | } 19 | 20 | &:active { 21 | color: shade(var(--color-primary), var(--button-active-shade-percent)); 22 | } 23 | } 24 | 25 | h1, h2, h3, h4, h5, h6 { 26 | color: var(--font-color-base); 27 | font-weight: inherit; 28 | 29 | &:first-child { 30 | margin-top: 0; 31 | } 32 | 33 | &:last-child { 34 | margin-bottom: 0; 35 | } 36 | } 37 | 38 | h1 { 39 | font-size: calc(var(--font-size-base) + 6px); 40 | } 41 | 42 | h2 { 43 | font-size: calc(var(--font-size-base) + 4px); 44 | } 45 | 46 | h3 { 47 | font-size: calc(var(--font-size-base) + 2px); 48 | } 49 | 50 | h4, h5, h6, p { 51 | font-size: inherit; 52 | } 53 | 54 | p { 55 | line-height: 1.8; 56 | 57 | &:first-child { 58 | margin-top: 0; 59 | } 60 | 61 | &:last-child { 62 | margin-bottom: 0; 63 | } 64 | } 65 | 66 | sup, sub { 67 | font-size: calc(var(--font-size-base) - 1px); 68 | } 69 | 70 | small { 71 | font-size: calc(var(--font-size-base) - 2px); 72 | } 73 | -------------------------------------------------------------------------------- /packages/theme-default/src/date-picker/time-spinner.css: -------------------------------------------------------------------------------- 1 | @import "../common/var.css"; 2 | 3 | @component-namespace el { 4 | @b time-spinner { 5 | &.has-seconds { 6 | .el-time-spinner__wrapper { 7 | width: 33%; 8 | 9 | .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) { 10 | padding-bottom: 15px; 11 | } 12 | } 13 | 14 | .el-time-spinner__wrapper:nth-child(2) { 15 | margin-left: 1%; 16 | } 17 | } 18 | 19 | @e wrapper { 20 | max-height: 190px; 21 | overflow: auto; 22 | display: inline-block; 23 | width: 50%; 24 | vertical-align: top; 25 | position: relative; 26 | } 27 | 28 | @e list { 29 | padding: 0; 30 | margin: 0; 31 | list-style: none; 32 | text-align: center; 33 | 34 | &::after, 35 | &::before { 36 | content: ''; 37 | display: block; 38 | width: 100%; 39 | height: 80px; 40 | } 41 | } 42 | 43 | @e item { 44 | height: 32px; 45 | line-height: 32px; 46 | font-size: 12px; 47 | 48 | &:hover:not(.disabled):not(.active) { 49 | background: var(--datepicker-cell-hover-color); 50 | cursor: pointer; 51 | } 52 | 53 | &.active:not(.disabled) { 54 | color: var(--color-white); 55 | } 56 | 57 | &.disabled { 58 | color: var(--datepicker-border-color); 59 | cursor: not-allowed; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /examples/docs/zh-CN/installation.md: -------------------------------------------------------------------------------- 1 | ## 安装 2 | 3 | ### npm 安装 4 | 推荐使用 npm 的方式安装,它能更好地和 [webpack](https://webpack.js.org/) 打包工具配合使用。 5 | 6 | ```shell 7 | npm i element-ui -S 8 | ``` 9 | 10 | ### CDN 11 | 目前可以通过 [unpkg.com/element-ui](https://unpkg.com/element-ui/) 获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用。 12 | 13 | ```html 14 | 15 | 16 | 17 | 18 | ``` 19 | 20 | ### Hello world 21 | 通过 CDN 的方式我们可以很容易地使用 Element 写出一个 Hello world 页面。[在线演示](http://codepen.io/QingWei-Li/pen/vXwJrY) 22 | 23 | ```html 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 | 按钮 34 | 35 |

欢迎使用 Element

36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 51 | 52 | ``` 53 | 如果是通过 npm 安装,并希望配合 webpack 使用,请阅读下一节:快速上手。 54 | -------------------------------------------------------------------------------- /packages/theme-default/src/collapse.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | @b collapse { 6 | border: 1px solid var(--collapse-border-color); 7 | border-radius: var(--collapse-border-radius); 8 | } 9 | @b collapse-item { 10 | @e header { 11 | height: var(--collapse-header-height); 12 | line-height: @height; 13 | padding-left: 15px; 14 | background-color: var(--collapse-header-fill); 15 | color: var(--collapse-header-color); 16 | cursor: pointer; 17 | border-bottom: 1px solid var(--collapse-border-color); 18 | font-size: var(--collapse-header-size); 19 | 20 | @e arrow { 21 | margin-right: 8px; 22 | transition: transform .3s; 23 | } 24 | } 25 | 26 | @e wrap { 27 | will-change: height; 28 | background-color: var(--collapse-content-fill); 29 | overflow: hidden; 30 | box-sizing: border-box; 31 | border-bottom: 1px solid var(--collapse-border-color); 32 | } 33 | 34 | @e content { 35 | padding: 10px 15px; 36 | font-size: var(--collapse-content-size); 37 | color: var(--collapse-content-color); 38 | line-height: 1.769230769230769; 39 | } 40 | 41 | @when active { 42 | > .el-collapse-item__header { 43 | .el-collapse-item__header__arrow { 44 | transform: rotate(90deg); 45 | } 46 | } 47 | } 48 | 49 | &:last-child { 50 | margin-bottom: -1px; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/unit/specs/alert.spec.js: -------------------------------------------------------------------------------- 1 | import { createTest, createVue, destroyVM } from '../util'; 2 | import Alert from 'packages/alert'; 3 | 4 | describe('Alert', () => { 5 | let vm; 6 | afterEach(() => { 7 | destroyVM(vm); 8 | }); 9 | 10 | it('create', () => { 11 | vm = createTest(Alert, { 12 | title: 'test', 13 | showIcon: true 14 | }, true); 15 | expect(vm.$el.querySelector('.el-alert__title').textContent).to.equal('test'); 16 | expect(vm.$el.classList.contains('el-alert--info')).to.true; 17 | }); 18 | 19 | it('type', () => { 20 | vm = createTest(Alert, { 21 | title: 'test', 22 | type: 'success', 23 | showIcon: true 24 | }, true); 25 | expect(vm.$el.classList.contains('el-alert--success')).to.true; 26 | expect(vm.$el.querySelector('.el-icon-circle-check')).to.exist; 27 | }); 28 | 29 | it('description', () => { 30 | vm = createTest(Alert, { 31 | title: 'Dorne', 32 | description: 'Unbowed, Unbent, Unbroken', 33 | showIcon: true 34 | }, true); 35 | expect(vm.$el.querySelector('.el-alert__description').textContent) 36 | .to.equal('Unbowed, Unbent, Unbroken'); 37 | }); 38 | 39 | it('close', () => { 40 | vm = createVue({ 41 | template: ` 42 |
43 | 46 |
47 | ` 48 | }, true); 49 | vm.$el.querySelector('.el-alert__closebtn').click(); 50 | expect(vm.$children[0].visible).to.false; 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /packages/select/src/select-dropdown.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 65 | -------------------------------------------------------------------------------- /packages/theme-default/src/scrollbar.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | @b scrollbar { 6 | overflow: hidden; 7 | position: relative; 8 | 9 | &:hover, 10 | &:active, 11 | &:focus { 12 | .el-scrollbar__bar { 13 | opacity: 1; 14 | transition: opacity 340ms ease-out; 15 | } 16 | } 17 | 18 | @e wrap { 19 | overflow: scroll; 20 | 21 | @m hidden-default { 22 | &::-webkit-scrollbar { 23 | width: 0; 24 | height: 0; 25 | } 26 | } 27 | } 28 | 29 | @e thumb { 30 | position: relative; 31 | display: block; 32 | size: 0; 33 | cursor: pointer; 34 | border-radius: inherit; 35 | background-color: var(--scrollbar-background-color); 36 | transition: .3s background-color; 37 | 38 | &:hover { 39 | background-color: var(--scrollbar-hover-background-color); 40 | } 41 | } 42 | 43 | @e bar { 44 | position: absolute; 45 | right: 2px; 46 | bottom: 2px; 47 | z-index: 1; 48 | border-radius: 4px; 49 | opacity: 0; 50 | transition: opacity 120ms ease-out; 51 | 52 | @when vertical { 53 | width: 6px; 54 | top: 2px; 55 | 56 | > div { 57 | width: 100%; 58 | } 59 | } 60 | 61 | @when horizontal { 62 | height: 6px; 63 | left: 2px; 64 | 65 | > div { 66 | height: 100%; 67 | } 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: dist test 2 | default: help 3 | 4 | # build all theme 5 | build-theme: 6 | npm run build:theme 7 | 8 | install: 9 | npm install 10 | 11 | install-cn: 12 | npm install --registry=http://registry.npm.taobao.org 13 | 14 | dev: 15 | npm run dev 16 | 17 | play: 18 | npm run dev:play 19 | 20 | new: 21 | node build/bin/new.js $(filter-out $@,$(MAKECMDGOALS)) 22 | 23 | new-lang: 24 | node build/bin/new-lang.js $(filter-out $@,$(MAKECMDGOALS)) 25 | 26 | dist: install 27 | npm run dist 28 | 29 | dist-all: 30 | npm run dist:all 31 | 32 | deploy: 33 | @npm run deploy 34 | 35 | pub: 36 | npm run pub 37 | 38 | pub-all: 39 | npm run pub:all 40 | 41 | test: 42 | npm run test:watch 43 | 44 | help: 45 | @echo " \033[35mmake\033[0m \033[1m命令使用说明\033[0m" 46 | @echo " \033[35mmake install\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 安装依赖" 47 | @echo " \033[35mmake new [中文名]\033[0m\t--- 创建新组件 package. 例如 'make new button 按钮'" 48 | @echo " \033[35mmake dev\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 开发模式" 49 | @echo " \033[35mmake dist\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 编译项目,生成目标文件" 50 | @echo " \033[35mmake dist-all\033[0m\t\033[0m\t\033[0m\t--- 分别编译每个组件项目" 51 | @echo " \033[35mmake deploy\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 部署 demo" 52 | @echo " \033[35mmake pub\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 发布到 npm 上" 53 | @echo " \033[35mmake pub-all\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 发布各组件到 npm 上" 54 | @echo " \033[35mmake new-lang \033[0m\t\033[0m\t\033[0m\t--- 为网站添加新语言. 例如 'make new-lang fr'" 55 | -------------------------------------------------------------------------------- /src/mixins/migrating.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Show migrating guide in browser console. 3 | * 4 | * Usage: 5 | * import Migrating from 'element-ui/src/mixins/migrating'; 6 | * 7 | * mixins: [Migrating] 8 | * 9 | * add getMigratingConfig method for your component. 10 | * getMigratingConfig() { 11 | * return { 12 | * props: { 13 | * 'allow-no-selection': 'allow-no-selection is removed.', 14 | * 'selection-mode': 'selection-mode is removed.' 15 | * }, 16 | * events: { 17 | * selectionchange: 'selectionchange is renamed to selection-change.' 18 | * } 19 | * }; 20 | * }, 21 | */ 22 | export default { 23 | mounted() { 24 | if (process.env.NODE_ENV === 'production') return; 25 | if (!this.$vnode) return; 26 | const { props, events } = this.getMigratingConfig(); 27 | const { data, componentOptions } = this.$vnode; 28 | const definedProps = data.attrs || {}; 29 | const definedEvents = componentOptions.listeners || {}; 30 | 31 | for (let propName in definedProps) { 32 | if (definedProps.hasOwnProperty(propName) && props[propName]) { 33 | console.warn(`[Element Migrating][Attribute]: ${props[propName]}`); 34 | } 35 | } 36 | 37 | for (let eventName in definedEvents) { 38 | if (definedEvents.hasOwnProperty(eventName) && events[eventName]) { 39 | console.warn(`[Element Migrating][Event]: ${events[eventName]}`); 40 | } 41 | } 42 | }, 43 | methods: { 44 | getMigratingConfig() { 45 | return { 46 | props: {}, 47 | events: {} 48 | }; 49 | } 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /src/utils/sync.js: -------------------------------------------------------------------------------- 1 | const SYNC_HOOK_PROP = '$v-sync'; 2 | 3 | /** 4 | * v-sync directive 5 | * 6 | * Usage: 7 | * v-sync:component-prop="context prop name" 8 | * 9 | * If your want to sync component's prop "visible" to context prop "myVisible", use like this: 10 | * v-sync:visible="myVisible" 11 | */ 12 | export default { 13 | bind(el, binding, vnode) { 14 | const context = vnode.context; 15 | const component = vnode.child; 16 | const expression = binding.expression; 17 | const prop = binding.arg; 18 | 19 | if (!expression || !prop) { 20 | console.warn('v-sync should specify arg & expression, for example: v-sync:visible="myVisible"'); 21 | return; 22 | } 23 | 24 | if (!component || !component.$watch) { 25 | console.warn('v-sync is only available on Vue Component'); 26 | return; 27 | } 28 | 29 | const unwatchContext = context.$watch(expression, (val) => { 30 | component[prop] = val; 31 | }); 32 | 33 | const unwatchComponent = component.$watch(prop, (val) => { 34 | context[expression] = val; 35 | }); 36 | 37 | Object.defineProperty(component, SYNC_HOOK_PROP, { 38 | value: { 39 | unwatchContext, 40 | unwatchComponent 41 | }, 42 | enumerable: false 43 | }); 44 | }, 45 | 46 | unbind(el, binding, vnode) { 47 | const component = vnode.child; 48 | if (component && component[SYNC_HOOK_PROP]) { 49 | const { unwatchContext, unwatchComponent } = component[SYNC_HOOK_PROP]; 50 | unwatchContext && unwatchContext(); 51 | unwatchComponent && unwatchComponent(); 52 | } 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /examples/docs/en-US/installation.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | ### npm 4 | Installing with npm is recommended and it works seamlessly with [webpack](https://webpack.js.org/). 5 | 6 | ```shell 7 | npm i element-ui -S 8 | ``` 9 | 10 | ### CDN 11 | Get the latest version from [unpkg.com/element-ui](https://unpkg.com/element-ui/) , and import JavaScript and CSS file in your page. 12 | 13 | ```html 14 | 15 | 16 | 17 | 18 | ``` 19 | 20 | ### Hello world 21 | If you are using CDN, a hello-world page is easy with Element. [Online Demo](http://codepen.io/QingWei-Li/pen/vXwJrY) 22 | 23 | ```html 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 | Button 34 | 35 |

Try Element

36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 51 | 52 | ``` 53 | If you are using npm and wish to apply webpack, please continue to the next page: Quick Start. 54 | -------------------------------------------------------------------------------- /packages/theme-default/src/mixins/_button.css: -------------------------------------------------------------------------------- 1 | @define-mixin button-variant $color, $background-color, $border-color { 2 | color: $color; 3 | background-color: $background-color; 4 | border-color: $border-color; 5 | 6 | &:hover, 7 | &:focus { 8 | background: tint($background-color, var(--button-hover-tint-percent)); 9 | border-color: tint($border-color, var(--button-hover-tint-percent)); 10 | color: $color; 11 | } 12 | 13 | &:active { 14 | background: shade($background-color, var(--button-active-shade-percent)); 15 | border-color: shade($border-color, var(--button-active-shade-percent)); 16 | color: $color; 17 | outline: none; 18 | } 19 | 20 | &.is-active { 21 | background: shade($background-color, var(--button-active-shade-percent)); 22 | border-color: shade($border-color, var(--button-active-shade-percent)); 23 | color: $color; 24 | } 25 | 26 | &.is-plain { 27 | background: var(--button-default-fill); 28 | border: var(--border-base); 29 | color: var(--button-default-color); 30 | 31 | &:hover, 32 | &:focus { 33 | background: var(--color-white); 34 | border-color: $border-color; 35 | color: $background-color; 36 | } 37 | 38 | &:active { 39 | background: var(--color-white); 40 | border-color: shade($border-color, var(--button-active-shade-percent)); 41 | color: shade($background-color, var(--button-active-shade-percent)); 42 | outline: none; 43 | } 44 | } 45 | } 46 | 47 | @define-mixin button-size $padding-vertical, $padding-horizontal, $font-size, $border-radius { 48 | padding: $padding-vertical $padding-horizontal; 49 | font-size: $font-size; 50 | border-radius: $border-radius; 51 | } 52 | -------------------------------------------------------------------------------- /packages/theme-default/src/select-dropdown.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | 6 | @b select-dropdown { 7 | position: absolute; 8 | z-index: 1001; 9 | border: var(--select-dropdown-border); 10 | border-radius: var(--border-radius-small); 11 | background-color: var(--select-dropdown-background); 12 | box-shadow: var(--select-dropdown-shadow); 13 | box-sizing: border-box; 14 | margin: 5px 0; 15 | 16 | @when multiple { 17 | & .el-select-dropdown__item.selected { 18 | color: var(--select-option-selected); 19 | background-color: var(--select-dropdown-background); 20 | 21 | &.hover { 22 | background-color: var(--select-option-hover-background); 23 | } 24 | 25 | &::after { 26 | position: absolute; 27 | right: 10px; 28 | font-family: 'element-icons'; 29 | content: "\E608"; 30 | font-size: 11px; 31 | -webkit-font-smoothing: antialiased; 32 | -moz-osx-font-smoothing: grayscale; 33 | } 34 | } 35 | } 36 | 37 | .el-scrollbar.is-empty .el-select-dropdown__list{ 38 | padding: 0; 39 | } 40 | } 41 | 42 | @b select-dropdown__empty { 43 | padding: var(--select-dropdown-empty-padding); 44 | margin: 0; 45 | text-align: center; 46 | color: var(--select-dropdown-empty-color); 47 | font-size: var(--select-font-size); 48 | } 49 | 50 | @b select-dropdown__wrap { 51 | max-height: var(--select-dropdown-max-height); 52 | } 53 | 54 | @b select-dropdown__list { 55 | list-style: none; 56 | padding: var(--select-dropdown-padding); 57 | margin: 0; 58 | box-sizing: border-box; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/col/src/col.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'ElCol', 3 | 4 | props: { 5 | span: { 6 | type: Number, 7 | default: 24 8 | }, 9 | offset: Number, 10 | pull: Number, 11 | push: Number, 12 | xs: [Number, Object], 13 | sm: [Number, Object], 14 | md: [Number, Object], 15 | lg: [Number, Object] 16 | }, 17 | 18 | computed: { 19 | gutter() { 20 | return this.$parent.gutter; 21 | }, 22 | 23 | style() { 24 | var ret = {}; 25 | 26 | if (this.gutter) { 27 | ret.paddingLeft = this.gutter / 2 + 'px'; 28 | ret.paddingRight = ret.paddingLeft; 29 | } 30 | 31 | return ret; 32 | } 33 | }, 34 | render(h) { 35 | let { style } = this; 36 | let classList = []; 37 | 38 | ['span', 'offset', 'pull', 'push'].forEach(prop => { 39 | if (this[prop]) { 40 | classList.push( 41 | prop !== 'span' 42 | ? `el-col-${prop}-${this[prop]}` 43 | : `el-col-${this[prop]}` 44 | ); 45 | } 46 | }); 47 | 48 | ['xs', 'sm', 'md', 'lg'].forEach(size => { 49 | if (typeof this[size] === 'number') { 50 | classList.push(`el-col-${size}-${this[size]}`); 51 | } else if (typeof this[size] === 'object') { 52 | let props = this[size]; 53 | Object.keys(props).forEach(prop => { 54 | classList.push( 55 | prop !== 'span' 56 | ? `el-col-${size}-${prop}-${props[prop]}` 57 | : `el-col-${size}-${props[prop]}` 58 | ); 59 | }); 60 | } 61 | }); 62 | 63 | return ( 64 |
67 | {this.$slots.default} 68 |
69 | ); 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /packages/collapse/src/collapse.vue: -------------------------------------------------------------------------------- 1 | 6 | 68 | -------------------------------------------------------------------------------- /packages/message/assets/success.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon_success 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/theme-default/src/common/transition.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import './var.css'; 3 | 4 | .fade-in-linear-enter-active, 5 | .fade-in-linear-leave-active { 6 | transition: var(--fade-linear-transition); 7 | } 8 | .fade-in-linear-enter, 9 | .fade-in-linear-leave, 10 | .fade-in-linear-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | .el-fade-in-enter-active, 15 | .el-fade-in-leave-active { 16 | transition: all .3s cubic-bezier(.55,0,.1,1); 17 | } 18 | .el-fade-in-enter, 19 | .el-fade-in-leave-active { 20 | opacity: 0; 21 | } 22 | 23 | .el-zoom-in-center-enter-active, 24 | .el-zoom-in-center-leave-active { 25 | transition: all .3s cubic-bezier(.55,0,.1,1); 26 | } 27 | .el-zoom-in-center-enter, 28 | .el-zoom-in-center-leave-active { 29 | opacity: 0; 30 | transform: scaleX(0); 31 | } 32 | 33 | .el-zoom-in-top-enter-active, 34 | .el-zoom-in-top-leave-active { 35 | opacity: 1; 36 | transform: scaleY(1); 37 | transition: var(--md-fade-transition); 38 | transform-origin: center top; 39 | } 40 | .el-zoom-in-top-enter, 41 | .el-zoom-in-top-leave-active { 42 | opacity: 0; 43 | transform: scaleY(0); 44 | } 45 | 46 | .el-zoom-in-bottom-enter-active, 47 | .el-zoom-in-bottom-leave-active { 48 | opacity: 1; 49 | transform: scaleY(1); 50 | transition: var(--md-fade-transition); 51 | transform-origin: center bottom; 52 | } 53 | .el-zoom-in-bottom-enter, 54 | .el-zoom-in-bottom-leave-active { 55 | opacity: 0; 56 | transform: scaleY(0); 57 | } 58 | 59 | .collapse-transition { 60 | transition: 0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out; 61 | } 62 | 63 | .list-enter-active, .list-leave-active { 64 | transition: all 1s; 65 | } 66 | .list-enter, .list-leave-active { 67 | opacity: 0; 68 | transform: translateY(-30px); 69 | } 70 | -------------------------------------------------------------------------------- /packages/collapse/src/collapse-item.vue: -------------------------------------------------------------------------------- 1 | 16 | 72 | -------------------------------------------------------------------------------- /packages/pagination/README.md: -------------------------------------------------------------------------------- 1 | # element-pagination 2 | > A element-pagination component for Vue.js. 3 | 4 | ## Demo 5 | http://element-component.github.io/element-pagination 6 | 7 | ## Installation 8 | ```shell 9 | npm i element-pagination -D 10 | ``` 11 | 12 | ## Usage 13 | ```javascript 14 | import Vue from 'vue' 15 | import ElPagination from 'element-pagination' 16 | import 'element-theme-default/dist/pagination.css' 17 | 18 | Vue.use(ElPagination) 19 | ``` 20 | 21 | or 22 | 23 | ```javascript 24 | import Vue from 'vue' 25 | import ElPagination from 'element-pagination' 26 | 27 | Vue.component('el-pagination', ElPagination) 28 | ``` 29 | 30 | ### Attributes 31 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 32 | |--------------------|----------------------------------------------------------|-------------------|-------------|--------| 33 | | small | 是否使用小型分页样式 | Boolean | — | false | 34 | | page-size | 每页显示条目个数 | Number | — | 10 | 35 | | total | 总条目数 | Number | — | - | 36 | | page-count | 总页数,total 和 page-count 设置任意一个就可以达到显示页码的功能;如果要支持 page-sizes 的更改,则需要使用 total 属性 | Number | — | - | 37 | | current-page | 当前页数 | Number | — | 1 | 38 | | layout | 组件布局,子组件名用逗号分隔| String | `sizes`, `prev`, `pager`, `next`, `jumper`, `->`, `total` | 'prev, pager, next, jumper, ->, total' | 39 | | page-sizes | 每页显示个数选择器的选项设置 | Number[] | — | [10, 20, 30, 40, 50, 100] | 40 | 41 | ### Events 42 | | 事件名称 | 说明 | 回调参数 | 43 | |---------|--------|---------| 44 | | size-change | pageSize 改变时会触发 | 每页条数`size` | 45 | | current-change | currentPage 改变时会触发 | 当前页`currentPage` | 46 | 47 | ## Development 48 | ```shell 49 | make dev 50 | 51 | ## test 52 | make test 53 | 54 | ## build 55 | make build 56 | ``` 57 | 58 | # License 59 | [MIT](https://opensource.org/licenses/MIT) 60 | -------------------------------------------------------------------------------- /packages/steps/README.md: -------------------------------------------------------------------------------- 1 | # element-steps 2 | > A element-steps component for Vue.js. 3 | 4 | ## Demo 5 | http://element-component.github.io/element-steps 6 | 7 | ## Installation 8 | ```shell 9 | npm i element-steps -D 10 | ``` 11 | 12 | ## Usage 13 | ```javascript 14 | import Vue from 'vue' 15 | import ElStep from 'element-steps' 16 | import 'element-theme-default/dist/step.css' 17 | 18 | Vue.use(ElStep) 19 | ``` 20 | 21 | or 22 | 23 | ```javascript 24 | import Vue from 'vue' 25 | import { ElSteps, ElStep } from 'element-steps' 26 | 27 | Vue.component('el-steps', ElSteps) 28 | Vue.component('el-step', ElStep) 29 | ``` 30 | 31 | ### Steps Attributes 32 | 33 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 34 | |---------- |-------- |---------- |------------- |-------- | 35 | | space | 每个 step 的间距,不填写将自适应间距 | Number | — | — | 36 | | direction | 显示方向 | string | vertical/horizontal | horizontal | 37 | | active | 设置当前激活步骤 | number | — | 0 | 38 | | process-status | 设置当前步骤的状态 | string | wait/process/finish/error/success | process | 39 | | finish-status | 设置结束步骤的状态 | string | wait/process/finish/error/success | finish | 40 | | align-center | 标题描述居中对齐 | boolean | - | false | 41 | 42 | ### Step Attributes 43 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 44 | |---------- |-------- |---------- |------------- |-------- | 45 | | title | 标题 | string | — | — | 46 | | description | 描述性文字 | string | — | — | 47 | | icon | 图标 | Element Icon 提供的图标,如果要使用自定义图标可以通过 slot 方式写入 | string | — | 48 | 49 | ### Step Slot 50 | | name | 说明 | 51 | |----|----| 52 | | icon | 图标 | 53 | | title | 标题 | 54 | | description | 描述性文字 | 55 | 56 | 57 | ## Development 58 | ```shell 59 | make dev 60 | 61 | ## test 62 | make test 63 | 64 | ## build 65 | make build 66 | ``` 67 | 68 | # License 69 | [MIT](https://opensource.org/licenses/MIT) 70 | -------------------------------------------------------------------------------- /src/utils/clickoutside.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import { on } from 'element-ui/src/utils/dom'; 3 | 4 | const nodeList = []; 5 | const ctx = '@@clickoutsideContext'; 6 | 7 | let startClick; 8 | 9 | !Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e)); 10 | 11 | !Vue.prototype.$isServer && on(document, 'mouseup', e => { 12 | nodeList.forEach(node => node[ctx].documentHandler(e, startClick)); 13 | }); 14 | /** 15 | * v-clickoutside 16 | * @desc 点击元素外面才会触发的事件 17 | * @example 18 | * ```vue 19 | *
20 | * ``` 21 | */ 22 | export default { 23 | bind(el, binding, vnode) { 24 | const id = nodeList.push(el) - 1; 25 | const documentHandler = function(mouseup, mousedown) { 26 | if (!vnode.context || 27 | el.contains(mouseup.target) || 28 | (vnode.context.popperElm && 29 | (vnode.context.popperElm.contains(mouseup.target) || 30 | vnode.context.popperElm.contains(mousedown.target)))) return; 31 | 32 | if (binding.expression && 33 | el[ctx].methodName && 34 | vnode.context[el[ctx].methodName]) { 35 | vnode.context[el[ctx].methodName](); 36 | } else { 37 | el[ctx].bindingFn && el[ctx].bindingFn(); 38 | } 39 | }; 40 | el[ctx] = { 41 | id, 42 | documentHandler, 43 | methodName: binding.expression, 44 | bindingFn: binding.value 45 | }; 46 | }, 47 | 48 | update(el, binding) { 49 | el[ctx].methodName = binding.expression; 50 | el[ctx].bindingFn = binding.value; 51 | }, 52 | 53 | unbind(el) { 54 | let len = nodeList.length; 55 | 56 | for (let i = 0; i < len; i++) { 57 | if (nodeList[i][ctx].id === el[ctx].id) { 58 | nodeList.splice(i, 1); 59 | break; 60 | } 61 | } 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /packages/message/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import { PopupManager } from 'element-ui/src/utils/popup'; 3 | let MessageConstructor = Vue.extend(require('./main.vue')); 4 | 5 | let instance; 6 | let instances = []; 7 | let seed = 1; 8 | 9 | var Message = function(options) { 10 | if (Vue.prototype.$isServer) return; 11 | options = options || {}; 12 | if (typeof options === 'string') { 13 | options = { 14 | message: options 15 | }; 16 | } 17 | let userOnClose = options.onClose; 18 | let id = 'message_' + seed++; 19 | 20 | options.onClose = function() { 21 | Message.close(id, userOnClose); 22 | }; 23 | 24 | instance = new MessageConstructor({ 25 | data: options 26 | }); 27 | instance.id = id; 28 | instance.vm = instance.$mount(); 29 | document.body.appendChild(instance.vm.$el); 30 | instance.vm.visible = true; 31 | instance.dom = instance.vm.$el; 32 | instance.dom.style.zIndex = PopupManager.nextZIndex(); 33 | instances.push(instance); 34 | return instance.vm; 35 | }; 36 | 37 | ['success', 'warning', 'info', 'error'].forEach(type => { 38 | Message[type] = options => { 39 | if (typeof options === 'string') { 40 | options = { 41 | message: options 42 | }; 43 | } 44 | options.type = type; 45 | return Message(options); 46 | }; 47 | }); 48 | 49 | Message.close = function(id, userOnClose) { 50 | for (let i = 0, len = instances.length; i < len; i++) { 51 | if (id === instances[i].id) { 52 | if (typeof userOnClose === 'function') { 53 | userOnClose(instances[i]); 54 | } 55 | instances.splice(i, 1); 56 | break; 57 | } 58 | } 59 | }; 60 | 61 | Message.closeAll = function() { 62 | for (let i = instances.length - 1; i >= 0; i--) { 63 | instances[i].close(); 64 | } 65 | }; 66 | 67 | export default Message; 68 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.zh-CN.md: -------------------------------------------------------------------------------- 1 | # Element UI 贡献指南 2 | 3 | Hi! 首先感谢你使用 Element UI。 4 | 5 | Element UI 是一套为开发者、设计师和产品经理准备的开源组件库,旨在快速搭建页面。它基于 Vue 2.0 开发,并提供了配套的设计资源,充分满足可定制化的需求。 6 | 7 | Element UI 的成长离不开大家的支持,如果你愿意为 Element UI 贡献代码或提供建议,请阅读以下内容。 8 | 9 | ## Issue 规范 10 | - issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。如果你在使用时产生了疑问,请到 Slack 或 [Gitter](https://gitter.im/ElemeFE/element) 里咨询。 11 | 12 | - 在提交 issue 之前,请搜索相关内容是否已被提出。 13 | 14 | - 请说明 Element UI 和 Vue 的版本号,并提供操作系统和浏览器信息。推荐使用 [JSFiddle](https://jsfiddle.net/) 生成在线 demo,这能够更直观地重现问题。 15 | 16 | ## Pull Request 规范 17 | - 请先 fork 一份到自己的项目下,不要直接在仓库下建分支。 18 | 19 | - commit 信息要以`[组件名]: 描述信息` 的形式填写,例如 `Button: fix xxx bug`。 20 | 21 | - **不要提交** `lib` 里面打包的文件。 22 | 23 | - 执行 `npm run dist` 后可以正确打包文件。 24 | 25 | - 为了兼容性以及最终打包的文件体积考虑,我们的 babel 只引入了 `preset-2015`,所以不建议使用 ES2015 的 API,例如 `Array.prototype.find`、`Object.assign`等。如果有需要,请引入第三方的 polyfill。 26 | 27 | - 提交 PR 前请 rebase,确保 commit 记录的整洁。 28 | 29 | - 确保 PR 是提交到 `dev` 分支,而不是 `master` 分支。 30 | 31 | - 如果是修复 bug,请在 PR 中给出描述信息。 32 | 33 | - 合并代码需要两名维护人员参与:一人进行 review 后 approve,另一人再次 review,通过后即可合并。 34 | 35 | ## 开发环境搭建 36 | 首先你需要 Node.js 4+ 和 NPM 3+ 37 | ```shell 38 | git clone git@github.com:ElemeFE/element.git 39 | npm run dev 40 | 41 | # open http://localhost:8085 42 | ``` 43 | 44 | 如果国内用户觉得安装慢可以使用 [yarn](https://github.com/yarnpkg/yarn) 搭配 taobao registry 45 | ```shell 46 | npm i yarn -g 47 | yarn config set registry https://registry.npm.taobao.org 48 | yarn 49 | npm run dev 50 | 51 | # open http://localhost:8085 52 | ``` 53 | 54 | To build: 55 | 56 | ```shell 57 | npm run dist 58 | ``` 59 | 60 | ## 组件开发规范 61 | - 通过 `make new` 创建组件目录结构,包含测试代码、入口文件、cooking 配置、package.json、文档 62 | - 如果包含父子组件,需要更改目录结构,参考 `Button` 63 | - 组件内如果依赖了其他组件,需要在当前组件内引入,参考 `Select` 64 | 65 | ## 代码规范 66 | 遵循饿了么前端的 [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) 即可 67 | -------------------------------------------------------------------------------- /packages/theme-default/src/date-picker/date-picker.css: -------------------------------------------------------------------------------- 1 | @import "../common/var.css"; 2 | @import "./picker-panel.css"; 3 | 4 | @component-namespace el { 5 | @b date-picker { 6 | min-width: 254px; 7 | 8 | &.has-sidebar.has-time { 9 | min-width: 434px; 10 | } 11 | 12 | &.has-sidebar { 13 | min-width: 370px; 14 | } 15 | 16 | &.has-time { 17 | min-width: 324px; 18 | } 19 | 20 | .el-picker-panel__content { 21 | min-width: 224px; 22 | } 23 | 24 | table { 25 | table-layout: fixed; 26 | width: 100%; 27 | } 28 | 29 | @e editor-wrap { 30 | position: relative; 31 | display: table-cell; 32 | padding: 0 5px; 33 | } 34 | 35 | @e time-header { 36 | position: relative; 37 | border-bottom: 1px solid var(--datepicker-inner-border-color); 38 | font-size: 12px; 39 | padding: 8px 5px 5px 5px; 40 | display: table; 41 | width: 100%; 42 | box-sizing: border-box; 43 | } 44 | 45 | @e header { 46 | margin: 12px; 47 | text-align: center; 48 | } 49 | 50 | @e header-label { 51 | font-size: 14px; 52 | padding: 0 5px; 53 | line-height: 22px; 54 | text-align: center; 55 | cursor: pointer; 56 | 57 | &:hover { 58 | color: var(--datepicker-text-hover-color); 59 | } 60 | 61 | &.active { 62 | color: var(--datepicker-active-color); 63 | } 64 | } 65 | 66 | @e prev-btn { 67 | float: left; 68 | } 69 | 70 | @e next-btn { 71 | float: right; 72 | } 73 | 74 | @e time-wrap { 75 | padding: 10px; 76 | text-align: center; 77 | } 78 | 79 | @e time-label { 80 | float: left; 81 | cursor: pointer; 82 | line-height: 30px; 83 | margin-left: 10px; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /packages/theme-default/src/index.css: -------------------------------------------------------------------------------- 1 | @import "./base.css"; 2 | @import "./pagination.css"; 3 | @import "./dialog.css"; 4 | @import "./autocomplete.css"; 5 | @import "./dropdown.css"; 6 | @import "./dropdown-menu.css"; 7 | @import "./dropdown-item.css"; 8 | @import "./menu.css"; 9 | @import "./submenu.css"; 10 | @import "./menu-item.css"; 11 | @import "./menu-item-group.css"; 12 | @import "./input.css"; 13 | @import "./input-number.css"; 14 | @import "./radio.css"; 15 | @import "./radio-group.css"; 16 | @import "./radio-button.css"; 17 | @import "./checkbox.css"; 18 | @import "./checkbox-group.css"; 19 | @import "./switch.css"; 20 | @import "./select.css"; 21 | @import "./button.css"; 22 | @import "./button-group.css"; 23 | @import "./table.css"; 24 | @import "./table-column.css"; 25 | @import "./date-picker.css"; 26 | @import "./time-select.css"; 27 | @import "./time-picker.css"; 28 | @import "./popover.css"; 29 | @import "./tooltip.css"; 30 | @import "./message-box.css"; 31 | @import "./breadcrumb.css"; 32 | @import "./breadcrumb-item.css"; 33 | @import "./form.css"; 34 | @import "./form-item.css"; 35 | @import "./tabs.css"; 36 | @import "./tab-pane.css"; 37 | @import "./tag.css"; 38 | @import "./tree.css"; 39 | @import "./alert.css"; 40 | @import "./notification.css"; 41 | @import "./slider.css"; 42 | @import "./loading.css"; 43 | @import "./row.css"; 44 | @import "./col.css"; 45 | @import "./upload.css"; 46 | @import "./progress.css"; 47 | @import "./spinner.css"; 48 | @import "./message.css"; 49 | @import "./badge.css"; 50 | @import "./card.css"; 51 | @import "./rate.css"; 52 | @import "./steps.css"; 53 | @import "./step.css"; 54 | @import "./carousel.css"; 55 | @import "./scrollbar.css"; 56 | @import "./carousel-item.css"; 57 | @import "./collapse.css"; 58 | @import "./collapse-item.css"; 59 | @import "./cascader.css"; 60 | @import "./color-picker.css"; 61 | -------------------------------------------------------------------------------- /packages/theme-default/src/core/option.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "../common/var.css"; 3 | 4 | @component-namespace element { 5 | 6 | @b option { 7 | box-sizing: border-box; 8 | color: var(--dropdown-color); 9 | cursor: pointer; 10 | display: block; 11 | font-size: var(--dropdown-font-size); 12 | padding: 9px; 13 | 14 | @e remark { 15 | color: var(--dropdown-option-pinyin-color); 16 | float: right; 17 | } 18 | 19 | @m arrow { 20 | 21 | &:not(.is-last)::after { 22 | border-left: 1px solid var(--dropdown-border-color); 23 | border-top: 1px solid var(--dropdown-border-color); 24 | content: " "; 25 | height: 4px; 26 | margin-top: 6px; 27 | position: absolute; 28 | right: 12px; 29 | transform: rotate(135deg); 30 | width: 4px; 31 | } 32 | } 33 | 34 | @when disabled { 35 | background-color: transparent; 36 | color: var(--dropdown-option-color-disabled); 37 | cursor: not-allowed; 38 | } 39 | 40 | &:hover, 41 | &.is-hover { 42 | background-color: var(--dropdown-option-fill-hover); 43 | color: var(--dropdown-option-color-hover); 44 | } 45 | 46 | @when selected { 47 | background-color: var(--dropdown-option-fill-active); 48 | color: var(--dropdown-option-color-active); 49 | } 50 | } 51 | 52 | @b optiongroup { 53 | list-style: none; 54 | padding-left: 0; 55 | 56 | & .element-option { 57 | padding-left: 21px; 58 | } 59 | 60 | @e title { 61 | box-sizing: border-box; 62 | color: var(--dropdown-group-color); 63 | display: inline-block; 64 | font-size: var(--dropdown-font-size); 65 | padding: 8px; 66 | 67 | &:hover { 68 | background-color: inherit; 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/theme-default/src/dropdown.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | @import "./button.css"; 4 | 5 | @component-namespace el { 6 | @b dropdown { 7 | display: inline-block; 8 | position: relative; 9 | color: var(--color-extra-light-black); 10 | font-size: var(--font-size-base); 11 | 12 | .el-button-group { 13 | display: block; 14 | } 15 | 16 | & .el-dropdown__caret-button { 17 | padding: * 5px; 18 | 19 | & .el-dropdown__icon { 20 | padding-left: 0; 21 | } 22 | } 23 | @e icon { 24 | font-size: 12px; 25 | margin: 0 3px; 26 | } 27 | } 28 | @b dropdown-menu { 29 | margin: 5px 0; 30 | background-color: var(--color-white); 31 | border: 1px solid var(--color-base-gray); 32 | box-shadow: var(--dropdown-menu-box-shadow); 33 | padding: 6px 0; 34 | z-index: 10; 35 | position: absolute; 36 | top: 0; 37 | left: 0; 38 | min-width: 100px; 39 | 40 | @e item { 41 | list-style: none; 42 | line-height: 36px; 43 | padding: 0 10px; 44 | margin: 0; 45 | cursor: pointer; 46 | 47 | &:not(.is-disabled):hover { 48 | background-color: var(--dropdown-menuItem-hover-fill); 49 | color: var(--dropdown-menuItem-hover-color); 50 | } 51 | @m divided { 52 | position: relative; 53 | margin-top: 6px; 54 | border-top: 1px solid var(--color-base-gray); 55 | 56 | &:before { 57 | content: ''; 58 | height: 6px; 59 | display: block; 60 | margin: 0 -10px; 61 | background-color: var(--color-white); 62 | } 63 | } 64 | @when disabled { 65 | cursor: default; 66 | color: var(--color-extra-light-silver); 67 | pointer-events: none; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /packages/radio/src/radio-button.vue: -------------------------------------------------------------------------------- 1 | 23 | 68 | -------------------------------------------------------------------------------- /packages/theme-default/src/loading.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | @b loading-mask { 6 | position: absolute; 7 | z-index: 10000; 8 | background-color: rgba(255, 255, 255, .9); 9 | margin: 0; 10 | top: 0; 11 | right: 0; 12 | bottom: 0; 13 | left: 0; 14 | transition: opacity 0.3s; 15 | 16 | @when fullscreen { 17 | position: fixed; 18 | 19 | .el-loading-spinner { 20 | margin-top: calc(- var(--loading-fullscreen-spinner-size) / 2); 21 | 22 | .circular { 23 | size: var(--loading-fullscreen-spinner-size); 24 | } 25 | } 26 | } 27 | } 28 | 29 | @b loading-spinner { 30 | top: 50%; 31 | margin-top: calc(- var(--loading-spinner-size) / 2); 32 | width: 100%; 33 | text-align: center; 34 | position: absolute; 35 | 36 | .el-loading-text { 37 | color: var(--color-primary); 38 | margin: 3px 0; 39 | font-size: 14px; 40 | } 41 | 42 | .circular { 43 | size: var(--loading-spinner-size); 44 | animation: loading-rotate 2s linear infinite; 45 | } 46 | 47 | .path { 48 | animation: loading-dash 1.5s ease-in-out infinite; 49 | stroke-dasharray: 90, 150; 50 | stroke-dashoffset: 0; 51 | stroke-width: 2; 52 | stroke: var(--color-primary); 53 | stroke-linecap: round; 54 | } 55 | } 56 | } 57 | 58 | .el-loading-fade-enter, 59 | .el-loading-fade-leave-active { 60 | opacity: 0; 61 | } 62 | 63 | @keyframes loading-rotate { 64 | 100% { 65 | transform: rotate(360deg); 66 | } 67 | } 68 | 69 | @keyframes loading-dash { 70 | 0% { 71 | stroke-dasharray: 1, 200; 72 | stroke-dashoffset: 0; 73 | } 74 | 50% { 75 | stroke-dasharray: 90, 150; 76 | stroke-dashoffset: -40px; 77 | } 78 | 100% { 79 | stroke-dasharray: 90, 150; 80 | stroke-dashoffset: -120px; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /packages/message/assets/info.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon_info 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/theme-default/src/autocomplete.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./input.css"; 3 | @import "./common/var.css"; 4 | @import "./scrollbar.css"; 5 | 6 | @component-namespace el { 7 | @b autocomplete { 8 | position: relative; 9 | display: inline-block; 10 | } 11 | @b autocomplete-suggestion { 12 | margin: 5px 0; 13 | box-shadow: 0 0 6px 0 rgba(0,0,0,0.04), 0 2px 4px 0 rgba(0,0,0,0.12); 14 | 15 | @e wrap { 16 | max-height: 280px; 17 | overflow: auto; 18 | background-color: var(--color-white); 19 | border: 1px solid var(--color-base-gray); 20 | padding: 6px 0; 21 | border-radius: 2px; 22 | box-sizing: border-box; 23 | } 24 | 25 | @e list { 26 | margin: 0; 27 | padding: 0; 28 | } 29 | 30 | & li { 31 | list-style: none; 32 | line-height: 36px; 33 | padding: 0 10px; 34 | margin: 0; 35 | cursor: pointer; 36 | color: var(--color-extra-light-black); 37 | font-size: 14px; 38 | white-space: nowrap; 39 | overflow: hidden; 40 | text-overflow: ellipsis; 41 | 42 | &:hover { 43 | background-color: var(--select-option-hover-background); 44 | } 45 | &.highlighted { 46 | background-color: var(--color-primary); 47 | color: var(--color-white); 48 | } 49 | &:active { 50 | background-color: darken(var(--color-primary), 0.2); 51 | } 52 | &.divider { 53 | margin-top: 6px; 54 | border-top: 1px solid var(--color-base-gray); 55 | } 56 | &.divider:last-child { 57 | margin-bottom: -6px; 58 | } 59 | } 60 | 61 | @when loading { 62 | li { 63 | text-align: center; 64 | height: 100px; 65 | line-height: 100px; 66 | font-size: 20px; 67 | color: #999; 68 | @utils-vertical-center; 69 | 70 | &:hover { 71 | background-color: var(--color-white); 72 | } 73 | } 74 | 75 | & .el-icon-loading { 76 | vertical-align: middle; 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/docs/zh-CN/icon.md: -------------------------------------------------------------------------------- 1 | 12 | 67 | ## Icon 图标 68 | 69 | 提供了一套常用的图标集合。 70 | 71 | ### 使用方法 72 | 73 | 直接通过设置类名为 `el-icon-iconName` 来使用即可。例如: 74 | 75 | :::demo 76 | ```html 77 | 78 | 79 | 80 | 搜索 81 | 82 | ``` 83 | ::: 84 | 85 | ### 图标集合 86 | 87 |
    88 |
  • 89 | 90 | 91 | {{'el-icon-' + name}} 92 | 93 |
  • 94 |
95 | -------------------------------------------------------------------------------- /packages/loading/README.md: -------------------------------------------------------------------------------- 1 | # element-loading 2 | > A element-loading component for Vue.js. 3 | 4 | ## Demo 5 | http://element-component.github.io/element-loading 6 | 7 | ## Installation 8 | ```shell 9 | npm i element-loading -D 10 | ``` 11 | 12 | ## Usage 13 | ```javascript 14 | import Vue from 'vue' 15 | import ElLoading from 'element-loading' 16 | import 'element-theme-default/dist/loading.css' 17 | 18 | Vue.use(ElLoading) 19 | ``` 20 | 21 | ### 服务 22 | Loading 还可以以服务的方式调用。引入 Loading 服务: 23 | 24 | 在需要调用时: 25 | ```javascript 26 | Loading.service(options); 27 | ``` 28 | 其中 `options` 参数为 Loading 的配置项,具体见下表。`LoadingService` 会返回一个 Loading 实例,可通过调用该实例的 `close` 方法来关闭它: 29 | ```javascript 30 | let loadingInstance = Loading.service(options); 31 | loadingInstance.close(); 32 | ``` 33 | 需要注意的是,以服务的方式调用的全屏 Loading 是单例的:若在前一个全屏 Loading 关闭前再次调用全屏 Loading,并不会创建一个新的 Loading 实例,而是返回现有全屏 Loading 的实例: 34 | ```javascript 35 | let loadingInstance1 = Loading.service({ fullscreen: true }); 36 | let loadingInstance2 = Loading.service({ fullscreen: true }); 37 | console.log(loadingInstance1 === loadingInstance2); // true 38 | ``` 39 | 此时调用它们中任意一个的 `close` 方法都能关闭这个全屏 Loading。 40 | 41 | 如果完整引入了 Element,那么 Vue.prototype 上会有一个全局方法 `$loading`,它的调用方式为:`this.$loading(options)`,同样会返回一个 Loading 实例。 42 | 43 | ### Options 44 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 45 | |---------- |-------------- |---------- |-------------------------------- |-------- | 46 | | target | Loading 需要覆盖的 DOM 节点。可传入一个 DOM 对象或字符串;若传入字符串,则会将其作为参数传入 `document.querySelector`以获取到对应 DOM 节点 | object/string | — | document.body | 47 | | body | 同 `v-loading` 指令中的 `body` 修饰符 | boolean | — | false | 48 | | fullscreen | 同 `v-loading` 指令中的 `fullscreen` 修饰符 | boolean | — | true | 49 | | lock | 同 `v-loading` 指令中的 `lock` 修饰符 | boolean | — | false | 50 | | text | 显示在加载图标下方的加载文案 | string | — | — | 51 | | customClass | Loading 的自定义类名 | string | — | — | 52 | 53 | 54 | ## Development 55 | ```shell 56 | make dev 57 | 58 | ## test 59 | make test 60 | 61 | ## build 62 | make build 63 | ``` 64 | 65 | # License 66 | [MIT](https://opensource.org/licenses/MIT) 67 | -------------------------------------------------------------------------------- /examples/docs/en-US/color-picker.md: -------------------------------------------------------------------------------- 1 | 18 | 19 | ## ColorPicker 20 | 21 | ColorPicker is a color selector supporting multiple color formats. 22 | 23 | ### Basic usage 24 | 25 | :::demo ColorPicker requires a string typed variable to be bound to v-model. 26 | ```html 27 |
28 | With default value 29 | 30 |
31 |
32 | With no default value 33 | 34 |
35 | 36 | 46 | ``` 47 | ::: 48 | 49 | ### Alpha 50 | 51 | :::demo ColorPicker supports alpha channel selecting. To activate alpha selecting, just add the `show-alpha` attribute. 52 | ```html 53 | 54 | 55 | 64 | ``` 65 | ::: 66 | 67 | ### Attributes 68 | | Attribute | Description | Type | Accepted Values | Default | 69 | |---------- |-------- |---------- |------------- |-------- | 70 | | show-alpha | whether to display the alpha slider | boolean | — | false | 71 | | color-format | color format of v-model | string | hsl / hsv / hex / rgb | hex (when show-alpha is false)/ rgb (when show-alpha is true) | 72 | 73 | ### Events 74 | | Event Name | Description | Parameters | 75 | |---------|--------|---------| 76 | | change | triggers when input value changes | color value | -------------------------------------------------------------------------------- /packages/message/assets/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon_warning 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/theme-default/src/message.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | 6 | @b message { 7 | box-shadow: var(--message-shadow); 8 | min-width: var(--message-min-width); 9 | padding: var(--message-padding); 10 | box-sizing: border-box; 11 | border-radius: var(--border-radius-small); 12 | position: fixed; 13 | left: 50%; 14 | top: 20px; 15 | transform: translateX(-50%); 16 | background-color: var(--color-white); 17 | transition: opacity 0.3s, transform .4s; 18 | overflow: hidden; 19 | 20 | @e group { 21 | margin-left: 38px; 22 | position: relative; 23 | height: 20px; 24 | line-height: 20px; 25 | display: flex; 26 | align-items: center; 27 | 28 | @when with-icon { 29 | margin-left: 0; 30 | } 31 | 32 | & p { 33 | font-size: var(--font-size-base); 34 | margin: 0 34px 0 0; 35 | white-space: nowrap; 36 | color: var(--message-content-color); 37 | text-align: justify; 38 | } 39 | } 40 | 41 | @e img { 42 | size: 40px; 43 | position: absolute; 44 | left: 0; 45 | top: 0; 46 | } 47 | 48 | @e icon { 49 | vertical-align: middle; 50 | margin-right: 8px; 51 | } 52 | 53 | @e closeBtn { 54 | position: absolute 3px 0 * *; 55 | cursor: pointer; 56 | color: var(--message-close-color); 57 | font-size: var(--font-size-base); 58 | 59 | &:hover { 60 | color: var(--message-close-hover-color); 61 | } 62 | } 63 | 64 | & .el-icon-circle-check { 65 | color: var(--message-success-color); 66 | } 67 | 68 | & .el-icon-circle-cross { 69 | color: var(--message-danger-color); 70 | } 71 | 72 | & .el-icon-information { 73 | color: var(--message-info-color); 74 | } 75 | 76 | & .el-icon-warning { 77 | color: var(--message-warning-color); 78 | } 79 | } 80 | 81 | .el-message-fade-enter, 82 | .el-message-fade-leave-active { 83 | opacity: 0; 84 | transform: translate(-50%, -100%); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /examples/pages/template/guide.tpl: -------------------------------------------------------------------------------- 1 | 61 | 73 | 92 | -------------------------------------------------------------------------------- /packages/radio/src/radio.vue: -------------------------------------------------------------------------------- 1 | 27 | 86 | -------------------------------------------------------------------------------- /src/locale/lang/zh-CN.js: -------------------------------------------------------------------------------- 1 | export default { 2 | el: { 3 | colorpicker: { 4 | confirm: '确定', 5 | clear: '清空' 6 | }, 7 | datepicker: { 8 | now: '此刻', 9 | today: '今天', 10 | cancel: '取消', 11 | clear: '清空', 12 | confirm: '确定', 13 | selectDate: '选择日期', 14 | selectTime: '选择时间', 15 | startDate: '开始日期', 16 | startTime: '开始时间', 17 | endDate: '结束日期', 18 | endTime: '结束时间', 19 | year: '年', 20 | month1: '1 月', 21 | month2: '2 月', 22 | month3: '3 月', 23 | month4: '4 月', 24 | month5: '5 月', 25 | month6: '6 月', 26 | month7: '7 月', 27 | month8: '8 月', 28 | month9: '9 月', 29 | month10: '10 月', 30 | month11: '11 月', 31 | month12: '12 月', 32 | // week: '周次', 33 | weeks: { 34 | sun: '日', 35 | mon: '一', 36 | tue: '二', 37 | wed: '三', 38 | thu: '四', 39 | fri: '五', 40 | sat: '六' 41 | }, 42 | months: { 43 | jan: '一月', 44 | feb: '二月', 45 | mar: '三月', 46 | apr: '四月', 47 | may: '五月', 48 | jun: '六月', 49 | jul: '七月', 50 | aug: '八月', 51 | sep: '九月', 52 | oct: '十月', 53 | nov: '十一月', 54 | dec: '十二月' 55 | } 56 | }, 57 | select: { 58 | loading: '加载中', 59 | noMatch: '无匹配数据', 60 | noData: '无数据', 61 | placeholder: '请选择' 62 | }, 63 | cascader: { 64 | noMatch: '无匹配数据', 65 | placeholder: '请选择' 66 | }, 67 | pagination: { 68 | goto: '前往', 69 | pagesize: '条/页', 70 | total: '共 {total} 条', 71 | pageClassifier: '页' 72 | }, 73 | messagebox: { 74 | title: '提示', 75 | confirm: '确定', 76 | cancel: '取消', 77 | error: '输入的数据不合法!' 78 | }, 79 | upload: { 80 | delete: '删除', 81 | preview: '查看图片', 82 | continue: '继续上传' 83 | }, 84 | table: { 85 | emptyText: '暂无数据', 86 | confirmFilter: '筛选', 87 | resetFilter: '重置', 88 | clearFilter: '全部' 89 | }, 90 | tree: { 91 | emptyText: '暂无数据' 92 | } 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /src/locale/lang/zh-TW.js: -------------------------------------------------------------------------------- 1 | export default { 2 | el: { 3 | colorpicker: { 4 | confirm: '確認', 5 | clear: '清空' 6 | }, 7 | datepicker: { 8 | now: '現在', 9 | today: '今天', 10 | cancel: '取消', 11 | clear: '清空', 12 | confirm: '確認', 13 | selectDate: '選擇日期', 14 | selectTime: '選擇時間', 15 | startDate: '開始日期', 16 | startTime: '開始時間', 17 | endDate: '結束日期', 18 | endTime: '結束時間', 19 | year: '年', 20 | month1: '1 月', 21 | month2: '2 月', 22 | month3: '3 月', 23 | month4: '4 月', 24 | month5: '5 月', 25 | month6: '6 月', 26 | month7: '7 月', 27 | month8: '8 月', 28 | month9: '9 月', 29 | month10: '10 月', 30 | month11: '11 月', 31 | month12: '12 月', 32 | // week: '周次', 33 | weeks: { 34 | sun: '日', 35 | mon: '一', 36 | tue: '二', 37 | wed: '三', 38 | thu: '四', 39 | fri: '五', 40 | sat: '六' 41 | }, 42 | months: { 43 | jan: '一月', 44 | feb: '二月', 45 | mar: '三月', 46 | apr: '四月', 47 | may: '五月', 48 | jun: '六月', 49 | jul: '七月', 50 | aug: '八月', 51 | sep: '九月', 52 | oct: '十月', 53 | nov: '十一月', 54 | dec: '十二月' 55 | } 56 | }, 57 | select: { 58 | loading: '加載中', 59 | noMatch: '無匹配資料', 60 | noData: '無資料', 61 | placeholder: '請選擇' 62 | }, 63 | cascader: { 64 | noMatch: '無匹配資料', 65 | placeholder: '請選擇' 66 | }, 67 | pagination: { 68 | goto: '前往', 69 | pagesize: '項/頁', 70 | total: '共 {total} 項', 71 | pageClassifier: '頁' 72 | }, 73 | messagebox: { 74 | title: '提示', 75 | confirm: '確定', 76 | cancel: '取消', 77 | error: '輸入的資料不符規定!' 78 | }, 79 | upload: { 80 | delete: '刪除', 81 | preview: '查看圖片', 82 | continue: '繼續上傳' 83 | }, 84 | table: { 85 | emptyText: '暫無資料', 86 | confirmFilter: '篩選', 87 | resetFilter: '重置', 88 | clearFilter: '全部' 89 | }, 90 | tree: { 91 | emptyText: '暫無資料' 92 | } 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /packages/upload/src/ajax.js: -------------------------------------------------------------------------------- 1 | function getError(action, option, xhr) { 2 | let msg; 3 | if (xhr.response) { 4 | msg = `${xhr.status} ${xhr.response.error || xhr.response}`; 5 | } else if (xhr.responseText) { 6 | msg = `${xhr.status} ${xhr.responseText}`; 7 | } else { 8 | msg = `fail to post ${action} ${xhr.status}'`; 9 | } 10 | 11 | const err = new Error(msg); 12 | err.status = xhr.status; 13 | err.method = 'post'; 14 | err.url = action; 15 | return err; 16 | } 17 | 18 | function getBody(xhr) { 19 | const text = xhr.responseText || xhr.response; 20 | if (!text) { 21 | return text; 22 | } 23 | 24 | try { 25 | return JSON.parse(text); 26 | } catch (e) { 27 | return text; 28 | } 29 | } 30 | 31 | export default function upload(option) { 32 | if (typeof XMLHttpRequest === 'undefined') { 33 | return; 34 | } 35 | 36 | const xhr = new XMLHttpRequest(); 37 | const action = option.action; 38 | 39 | if (xhr.upload) { 40 | xhr.upload.onprogress = function progress(e) { 41 | if (e.total > 0) { 42 | e.percent = e.loaded / e.total * 100; 43 | } 44 | option.onProgress(e); 45 | }; 46 | } 47 | 48 | const formData = new FormData(); 49 | 50 | if (option.data) { 51 | Object.keys(option.data).map(key => { 52 | formData.append(key, option.data[key]); 53 | }); 54 | } 55 | 56 | formData.append(option.filename, option.file); 57 | 58 | xhr.onerror = function error(e) { 59 | option.onError(e); 60 | }; 61 | 62 | xhr.onload = function onload() { 63 | if (xhr.status < 200 || xhr.status >= 300) { 64 | return option.onError(getError(action, option, xhr)); 65 | } 66 | 67 | option.onSuccess(getBody(xhr)); 68 | }; 69 | 70 | xhr.open('post', action, true); 71 | 72 | if (option.withCredentials && 'withCredentials' in xhr) { 73 | xhr.withCredentials = true; 74 | } 75 | 76 | const headers = option.headers || {}; 77 | 78 | for (let item in headers) { 79 | if (headers.hasOwnProperty(item) && headers[item] !== null) { 80 | xhr.setRequestHeader(item, headers[item]); 81 | } 82 | } 83 | xhr.send(formData); 84 | return xhr; 85 | } 86 | -------------------------------------------------------------------------------- /packages/message/assets/error.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon_danger 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/locale/lang/ja.js: -------------------------------------------------------------------------------- 1 | export default { 2 | el: { 3 | colorpicker: { 4 | confirm: 'OK', 5 | clear: 'クリア' 6 | }, 7 | datepicker: { 8 | now: '現在', 9 | today: '今日', 10 | cancel: 'キャンセル', 11 | clear: 'クリア', 12 | confirm: 'はい', 13 | selectDate: '日付を選択', 14 | selectTime: '時間を選択', 15 | startDate: '開始日', 16 | startTime: '開始時間', 17 | endDate: '終了日', 18 | endTime: '終了時間', 19 | year: '年', 20 | month1: '1月', 21 | month2: '2月', 22 | month3: '3月', 23 | month4: '4月', 24 | month5: '5月', 25 | month6: '6月', 26 | month7: '7月', 27 | month8: '8月', 28 | month9: '9月', 29 | month10: '10月', 30 | month11: '11月', 31 | month12: '12月', 32 | // week: '週次', 33 | weeks: { 34 | sun: '日', 35 | mon: '月', 36 | tue: '火', 37 | wed: '水', 38 | thu: '木', 39 | fri: '金', 40 | sat: '土' 41 | }, 42 | months: { 43 | jan: '1月', 44 | feb: '2月', 45 | mar: '3月', 46 | apr: '4月', 47 | may: '5月', 48 | jun: '6月', 49 | jul: '7月', 50 | aug: '8月', 51 | sep: '9月', 52 | oct: '10月', 53 | nov: '11月', 54 | dec: '12月' 55 | } 56 | }, 57 | select: { 58 | loading: 'ロード中', 59 | noMatch: 'データなし', 60 | noData: 'データなし', 61 | placeholder: '選択してください' 62 | }, 63 | cascader: { 64 | noMatch: 'データなし', 65 | placeholder: '選択してください' 66 | }, 67 | pagination: { 68 | goto: '', 69 | pagesize: '件/ページ', 70 | total: '総計 {total} 件', 71 | pageClassifier: 'ページ目へ' 72 | }, 73 | messagebox: { 74 | title: 'メッセージ', 75 | confirm: 'はい', 76 | cancel: 'キャンセル', 77 | error: '正しくない入力' 78 | }, 79 | upload: { 80 | delete: '削除する', 81 | preview: 'プレビュー', 82 | continue: '続行する' 83 | }, 84 | table: { 85 | emptyText: 'データなし', 86 | confirmFilter: '確認', 87 | resetFilter: '初期化', 88 | clearFilter: 'すべて' 89 | }, 90 | tree: { 91 | emptyText: 'データなし' 92 | } 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /src/locale/lang/ko.js: -------------------------------------------------------------------------------- 1 | export default { 2 | el: { 3 | colorpicker: { 4 | confirm: '확인', 5 | clear: '초기화' 6 | }, 7 | datepicker: { 8 | now: '지금', 9 | today: '오늘', 10 | cancel: '취소', 11 | clear: '초기화', 12 | confirm: '확인', 13 | selectDate: '날짜 선택', 14 | selectTime: '시간 선택', 15 | startDate: '시작 날짜', 16 | startTime: '시작 시간', 17 | endDate: '종료 날짜', 18 | endTime: '종료 시간', 19 | year: '년', 20 | month1: '1월', 21 | month2: '2월', 22 | month3: '3월', 23 | month4: '4월', 24 | month5: '5월', 25 | month6: '6월', 26 | month7: '7월', 27 | month8: '8월', 28 | month9: '9월', 29 | month10: '10월', 30 | month11: '11월', 31 | month12: '12월', 32 | // week: 'week', 33 | weeks: { 34 | sun: '일', 35 | mon: '월', 36 | tue: '화', 37 | wed: '수', 38 | thu: '목', 39 | fri: '금', 40 | sat: '토' 41 | }, 42 | months: { 43 | jan: '1월', 44 | feb: '2월', 45 | mar: '3월', 46 | apr: '4월', 47 | may: '5월', 48 | jun: '6월', 49 | jul: '7월', 50 | aug: '8월', 51 | sep: '9월', 52 | oct: '10월', 53 | nov: '11월', 54 | dec: '12월' 55 | } 56 | }, 57 | select: { 58 | loading: '불러오는 중', 59 | noMatch: '맞는 데이터가 없습니다', 60 | noData: '데이터 없음', 61 | placeholder: '선택' 62 | }, 63 | cascader: { 64 | noMatch: '맞는 데이터가 없습니다', 65 | placeholder: '선택' 66 | }, 67 | pagination: { 68 | goto: '이동', 69 | pagesize: '/page', 70 | total: '총 {total}', 71 | pageClassifier: '' 72 | }, 73 | messagebox: { 74 | title: '메시지', 75 | confirm: '확인', 76 | cancel: '취소', 77 | error: '올바르지 않은 입력' 78 | }, 79 | upload: { 80 | delete: '삭제', 81 | preview: '미리보기', 82 | continue: '계속하기' 83 | }, 84 | table: { 85 | emptyText: '데이터 없음', 86 | confirmFilter: '확인', 87 | resetFilter: '초기화', 88 | clearFilter: '전체' 89 | }, 90 | tree: { 91 | emptyText: '데이터 없음' 92 | } 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /packages/theme-default/src/date-picker/time-picker.css: -------------------------------------------------------------------------------- 1 | @import "../common/var.css"; 2 | 3 | @component-namespace el { 4 | @b time-panel { 5 | margin: 5px 0; 6 | border: solid 1px var(--datepicker-border-color); 7 | background-color: var(--color-white); 8 | box-shadow: var(--box-shadow-base); 9 | border-radius: 2px; 10 | position: absolute; 11 | width: 180px; 12 | left: 0; 13 | z-index: var(--index-top); 14 | user-select: none; 15 | 16 | @e content { 17 | font-size: 0; 18 | position: relative; 19 | overflow: hidden; 20 | 21 | &::after, &::before { 22 | content: ":"; 23 | top: 50%; 24 | color: var(--color-white); 25 | position: absolute; 26 | font-size: 14px; 27 | margin-top: -15px; 28 | line-height: 16px; 29 | background-color: var(--datepicker-active-color); 30 | height: 32px; 31 | z-index: -1; 32 | left: 0; 33 | right: 0; 34 | box-sizing: border-box; 35 | padding-top: 6px; 36 | text-align: left; 37 | } 38 | 39 | &::after { 40 | left: 50%; 41 | margin-left: -2px; 42 | } 43 | 44 | &::before { 45 | padding-left: 50%; 46 | margin-right: -2px; 47 | } 48 | 49 | &.has-seconds { 50 | &::after { 51 | left: calc(100% / 3 * 2); 52 | } 53 | 54 | &::before { 55 | padding-left: calc(100% / 3); 56 | } 57 | } 58 | } 59 | 60 | @e footer { 61 | border-top: 1px solid var(--datepicker-inner-border-color); 62 | padding: 4px; 63 | height: 36px; 64 | line-height: 25px; 65 | text-align: right; 66 | box-sizing: border-box; 67 | } 68 | 69 | @e btn { 70 | border: none; 71 | line-height: 28px; 72 | padding: 0 5px; 73 | margin: 0 5px; 74 | cursor: pointer; 75 | background-color: transparent; 76 | outline: none; 77 | font-size: 12px; 78 | color: var(--color-base-silver); 79 | 80 | &.confirm { 81 | font-weight: 800; 82 | color: var(--datepicker-active-color); 83 | } 84 | } 85 | 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /packages/theme-default/src/date-picker/date-table.css: -------------------------------------------------------------------------------- 1 | @import "../common/var.css"; 2 | 3 | @component-namespace el { 4 | @b date-table { 5 | font-size: 12px; 6 | min-width: 224px; 7 | user-select: none; 8 | 9 | @when week-mode { 10 | .el-date-table__row { 11 | &:hover { 12 | background-color: var(--datepicker-cell-hover-color); 13 | } 14 | 15 | &.current { 16 | background-color: var(--datepicker-inrange-color); 17 | } 18 | } 19 | } 20 | 21 | td { 22 | width: 32px; 23 | height: 32px; 24 | box-sizing: border-box; 25 | text-align: center; 26 | cursor: pointer; 27 | 28 | &.next-month, 29 | &.prev-month { 30 | color: var(--datepicker-off-color); 31 | } 32 | 33 | &.today { 34 | color: var(--datepicker-text-hover-color); 35 | position: relative; 36 | &:before { 37 | content: " "; 38 | position: absolute; 39 | top: 0px; 40 | right: 0px; 41 | width: 0; 42 | height: 0; 43 | border-top: 0.5em solid var(--datepicker-active-color); 44 | border-left: .5em solid transparent; 45 | } 46 | } 47 | 48 | &.available:hover { 49 | background-color: var(--datepicker-cell-hover-color); 50 | } 51 | 52 | &.in-range { 53 | background-color: var(--datepicker-inrange-color); 54 | &:hover { 55 | background-color: var(--datepicker-inrange-hover-color); 56 | } 57 | } 58 | 59 | &.current:not(.disabled), 60 | &.start-date, 61 | &.end-date { 62 | background-color: var(--datepicker-active-color) !important; 63 | color: var(--color-white); 64 | } 65 | 66 | &.disabled { 67 | background-color: #f4f4f4; 68 | opacity: 1; 69 | cursor: not-allowed; 70 | color: #ccc; 71 | } 72 | 73 | &.week { 74 | font-size: 80%; 75 | color: var(--datepicker-header-color); 76 | } 77 | } 78 | 79 | th { 80 | padding: 5px; 81 | color: var(--datepicker-header-color); 82 | font-weight: 400; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /packages/theme-default/src/alert.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | 6 | @b alert { 7 | width: 100%; 8 | padding: var(--alert-padding); 9 | margin: 0; 10 | box-sizing: border-box; 11 | border-radius: var(--alert-border-radius); 12 | position: relative; 13 | background-color: var(--color-white); 14 | overflow: hidden; 15 | color: var(--color-white); 16 | opacity: 1; 17 | display: table; 18 | transition: opacity .2s; 19 | 20 | @modifier success { 21 | background-color: var(--alert-success-color); 22 | } 23 | 24 | @modifier info { 25 | background-color: var(--alert-info-color); 26 | } 27 | 28 | @modifier warning { 29 | background-color: var(--alert-warning-color); 30 | } 31 | 32 | @modifier error { 33 | background-color: var(--alert-danger-color); 34 | } 35 | 36 | @e content { 37 | display: table-cell; 38 | padding: 0 8px; 39 | } 40 | 41 | @e icon { 42 | font-size: var(--alert-icon-size); 43 | width: var(--alert-icon-size); 44 | display: table-cell; 45 | color: var(--color-white); 46 | vertical-align: middle; 47 | @when big { 48 | font-size: var(--alert-icon-large-size); 49 | width: var(--alert-icon-large-size); 50 | } 51 | } 52 | 53 | @e title { 54 | font-size: var(--alert-title-font-size); 55 | line-height: 18px; 56 | @when bold { 57 | font-weight: bold; 58 | } 59 | } 60 | 61 | & .el-alert__description { 62 | color: var(--color-white); 63 | font-size: var(--alert-description-font-size); 64 | margin: 5px 0 0 0; 65 | } 66 | 67 | @e closebtn { 68 | font-size: var(--alert-close-font-size); 69 | color: var(--color-white); 70 | opacity: 1; 71 | position: absolute 12px 15px * *; 72 | cursor: pointer; 73 | 74 | @when customed { 75 | font-style: normal; 76 | font-size: var(--alert-close-customed-font-size); 77 | top: 9px; 78 | } 79 | } 80 | } 81 | 82 | .el-alert-fade-enter, 83 | .el-alert-fade-leave-active { 84 | opacity: 0; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /packages/theme-default/src/notification.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./common/var.css"; 3 | 4 | @component-namespace el { 5 | 6 | @b notification { 7 | width: var(--notification-width); 8 | padding: var(--notification-padding); 9 | box-sizing: border-box; 10 | border-radius: var(--border-radius-small); 11 | position: fixed; 12 | right: 16px; 13 | background-color: var(--color-white); 14 | box-shadow: var(--notification-shadow); 15 | transition: opacity 0.3s, transform .3s, right .3s, top 0.4s; 16 | overflow: hidden; 17 | 18 | @e group { 19 | margin-left: 0; 20 | @when with-icon { 21 | margin-left: 55px; 22 | } 23 | } 24 | 25 | @e title { 26 | font-weight: normal; 27 | font-size: var(--notification-title-font-size); 28 | color: var(--notification-title-color); 29 | margin: 0; 30 | } 31 | 32 | @e content { 33 | font-size: var(--notification-font-size); 34 | line-height: 21px; 35 | margin: 10px 0 0 0; 36 | color: var(--notification-color); 37 | text-align: justify; 38 | } 39 | 40 | @e icon { 41 | size: var(--notification-icon-size); 42 | font-size: var(--notification-icon-size); 43 | float: left; 44 | position: relative; 45 | top: 3px; 46 | } 47 | 48 | @e closeBtn { 49 | position: absolute 20px 20px * *; 50 | cursor: pointer; 51 | color: var(--notification-close-color); 52 | font-size: var(--notification-font-size); 53 | 54 | &:hover { 55 | color: var(--notification-close-hover-color); 56 | } 57 | } 58 | 59 | & .el-icon-circle-check { 60 | color: var(--notification-success-color); 61 | } 62 | 63 | & .el-icon-circle-cross { 64 | color: var(--notification-danger-color); 65 | } 66 | 67 | & .el-icon-information { 68 | color: var(--notification-info-color); 69 | } 70 | 71 | & .el-icon-warning { 72 | color: var(--notification-warning-color); 73 | } 74 | } 75 | 76 | .el-notification-fade-enter { 77 | transform: translateX(100%); 78 | right: 0; 79 | } 80 | 81 | .el-notification-fade-leave-active { 82 | opacity: 0; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /packages/theme-default/src/table-column.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import "./checkbox.css"; 3 | @import "./tag.css"; 4 | @import "./common/var.css"; 5 | 6 | @component-namespace el { 7 | @b table-column { 8 | @m selection .cell { 9 | padding-left: 14px; 10 | padding-right: 14px; 11 | } 12 | } 13 | 14 | @b table-filter { 15 | border: solid 1px var(--color-base-gray); 16 | border-radius: 2px; 17 | background-color: var(--color-white); 18 | box-shadow: var(--dropdown-menu-box-shadow); 19 | box-sizing: border-box; 20 | margin: 2px 0; 21 | 22 | /** used for dropdown mode */ 23 | @e list { 24 | padding: 5px 0; 25 | margin: 0; 26 | list-style: none; 27 | min-width: 100px; 28 | } 29 | 30 | @e list-item { 31 | line-height: 36px; 32 | padding: 0 10px; 33 | cursor: pointer; 34 | font-size: var(--font-size-base); 35 | 36 | &:hover { 37 | background-color: var(--dropdown-menuItem-hover-fill); 38 | color: var(--dropdown-menuItem-hover-color); 39 | } 40 | 41 | @when active { 42 | background-color: var(--color-primary); 43 | color: var(--color-white); 44 | } 45 | } 46 | 47 | @e content { 48 | min-width: 100px; 49 | } 50 | 51 | @e bottom { 52 | border-top: 1px solid var(--color-base-gray); 53 | padding: 8px; 54 | 55 | button { 56 | background: transparent; 57 | border: none; 58 | color: var(--color-base-silver); 59 | cursor: pointer; 60 | font-size: var(--font-size-base); 61 | padding: 0 3px; 62 | 63 | &:hover { 64 | color: var(--color-primary); 65 | } 66 | 67 | &:focus { 68 | outline: none; 69 | } 70 | 71 | &.is-disabled { 72 | color: var(--color-extra-light-silver); 73 | cursor: not-allowed; 74 | } 75 | } 76 | } 77 | 78 | @e checkbox-group { 79 | padding: 10px; 80 | 81 | .el-checkbox { 82 | display: block; 83 | margin-bottom: 8px; 84 | margin-left: 5px; 85 | } 86 | 87 | .el-checkbox:last-child { 88 | margin-bottom: 0; 89 | } 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /src/locale/lang/sv-SE.js: -------------------------------------------------------------------------------- 1 | export default { 2 | el: { 3 | colorpicker: { 4 | confirm: 'OK', 5 | clear: 'Töm' 6 | }, 7 | datepicker: { 8 | now: 'Nu', 9 | today: 'Idag', 10 | cancel: 'Avbryt', 11 | clear: 'Töm', 12 | confirm: 'OK', 13 | selectDate: 'Välj datum', 14 | selectTime: 'Välj tid', 15 | startDate: 'Startdatum', 16 | startTime: 'Starttid', 17 | endDate: 'Slutdatum', 18 | endTime: 'Sluttid', 19 | year: 'År', 20 | month1: 'Januari', 21 | month2: 'Februari', 22 | month3: 'Mars', 23 | month4: 'April', 24 | month5: 'Maj', 25 | month6: 'Juni', 26 | month7: 'Juli', 27 | month8: 'Augusti', 28 | month9: 'September', 29 | month10: 'Oktober', 30 | month11: 'November', 31 | month12: 'December', 32 | // week: 'week', 33 | weeks: { 34 | sun: 'Sön', 35 | mon: 'Mån', 36 | tue: 'Tis', 37 | wed: 'Ons', 38 | thu: 'Tor', 39 | fri: 'Fre', 40 | sat: 'Lör' 41 | }, 42 | months: { 43 | jan: 'Jan', 44 | feb: 'Feb', 45 | mar: 'Mar', 46 | apr: 'Apr', 47 | may: 'Maj', 48 | jun: 'Jun', 49 | jul: 'Jul', 50 | aug: 'Aug', 51 | sep: 'Sep', 52 | oct: 'Okt', 53 | nov: 'Nov', 54 | dec: 'Dec' 55 | } 56 | }, 57 | select: { 58 | loading: 'Laddar', 59 | noMatch: 'Hittade inget', 60 | noData: 'Ingen data', 61 | placeholder: 'Välj' 62 | }, 63 | pagination: { 64 | goto: 'Gå till', 65 | pagesize: '/sida', 66 | total: 'Total {total}', 67 | pageClassifier: '' 68 | }, 69 | messagebox: { 70 | title: 'Meddelande', 71 | confirm: 'OK', 72 | cancel: 'Avbryt', 73 | error: 'Felaktig inmatning' 74 | }, 75 | upload: { 76 | delete: 'Radera', 77 | preview: 'Förhandsvisa', 78 | continue: 'Fortsätt' 79 | }, 80 | table: { 81 | emptyText: 'Inga Data', 82 | confirmFilter: 'Bekräfta', 83 | resetFilter: 'Återställ', 84 | clearFilter: 'Alla' 85 | }, 86 | tree: { 87 | emptyText: 'Inga Data' 88 | } 89 | } 90 | }; 91 | -------------------------------------------------------------------------------- /packages/date-picker/README.md: -------------------------------------------------------------------------------- 1 | # element-datepicker 2 | 3 | 4 | ## Installation 5 | ```shell 6 | npm i element-datepicker -S 7 | ``` 8 | 9 | ## Usage 10 | 11 | A: 12 | ```javascript 13 | import Vue from 'vue' 14 | import ElDatePicker from 'element-datepicker' 15 | 16 | Vue.use(ElDatePicker) 17 | ``` 18 | 19 | B: 20 | ```javascript 21 | import Vue from 'vue' 22 | import { DatePicker, TimePicker, TimeSelect } from 'element-datepicker' 23 | 24 | Vue.component(DatePicker.name, DatePicker); 25 | Vue.component(TimePicker.name, TimePicker); 26 | Vue.component(TimeSelect.name, TimeSelect); 27 | ``` 28 | 29 | C: 30 | ```html 31 | 32 | 33 | 36 | ``` 37 | 38 | ### Attributes 39 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 40 | |---------- |-------------- |---------- |-------------------------------- |-------- | 41 | | readonly | 完全只读 | boolean | — | false | 42 | | disabled | 禁用 | boolean | - | false | 43 | | editable | 文本框可输入 | boolean | - | true | 44 | | size | 输入框尺寸 | string | large, small, mini | — | 45 | | placeholder | 占位内容 | string | — | — | 46 | | type | 显示类型 | string | year/month/date/week/ datetime/datetimerange/daterange | date | 47 | | format | 时间日期格式化 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | yyyy-MM-dd | 48 | | align | 对齐方式 | string | left, center, right | left | 49 | |picker-options | 当前时间日期选择器特有的选项参考下表 | object | — | {} | 50 | 51 | ### Picker Options 52 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 53 | |---------- |-------------- |---------- |-------------------------------- |-------- | 54 | | shortcuts | 设置快捷选项,需要传入 { text, onClick } 对象用法参考 demo 或下表 | Object[] | - | - | 55 | | disabledDate | 设置禁用状态,参数为当前日期,要求返回 Boolean | Function | - | - | 56 | 57 | ### Shortcuts 58 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 59 | |---------- |-------------- |---------- |-------------------------------- |-------- | 60 | | text | 标题文本 | string | — | — | 61 | | onClick | 选中后的回调函数,参数是 vm,可通过触发 'pick' 事件设置选择器的值。例如 vm.$emit('pick', new Date()) | function | — | — | 62 | 63 | ## License 64 | MIT 65 | --------------------------------------------------------------------------------